来自:http://deeplearning.net/software/theano/tutorial/loop.html

loop

一、Scan

  • 一个递归的通常的形式,可以用来作为循环语句。
  • 约间和映射(在第一个(leading,个人翻译成第一个)维度上进行循环)是scan的特殊情况
  • 沿着一些输入序列scan一个函数,然后在每个时间步上生成一个输出。
  • 该函数可以查看函数的前K个时间步的结果。
  • sum() 可以通过在一个列表上使用 z + x(i) 函数(初始化为Z=0)来得到结果。
  • 通常来说,一个for循环可以表示成一个scan()操作,而且scan是与theano的循环联系最紧密的。
  • 使用scan而不是for循环的优势:
    • 迭代的次数是符号graph的一部分。
    • 最小化GPU的迁移(如果用到GPU的话)。
    • 通过连续的步骤计算梯度。
    • 比python中使用theano编译后的for循环稍微快一点。
    • 通过检测实际用到的内存的数量,来降低总的内存使用情况。

所有的文档可以查看库对应的: Scan.

1.1 Scan 例子: 逐元素计算 tanh(x(t).dot(W) + b)

import theano
import theano.tensor as T
import numpy as np# defining the tensor variables
X = T.matrix("X")
W = T.matrix("W")
b_sym = T.vector("b_sym")results, updates = theano.scan(lambda v: T.tanh(T.dot(v, W) + b_sym), sequences=X)
compute_elementwise = theano.function(inputs=[X, W, b_sym], outputs=[results])# test values
x = np.eye(2, dtype=theano.config.floatX)
w = np.ones((2, 2), dtype=theano.config.floatX)
b = np.ones((2), dtype=theano.config.floatX)
b[1] = 2print compute_elementwise(x, w, b)[0]# comparison with numpy
print np.tanh(x.dot(w) + b)

1.2 Scan 例子:计算序列 x(t) = tanh(x(t - 1).dot(W) + y(t).dot(U) + p(T - t).dot(V))

import theano
import theano.tensor as T
import numpy as np# define tensor variables
X = T.vector("X")
W = T.matrix("W")
b_sym = T.vector("b_sym")
U = T.matrix("U")
Y = T.matrix("Y")
V = T.matrix("V")
P = T.matrix("P")results, updates = theano.scan(lambda y, p, x_tm1: T.tanh(T.dot(x_tm1, W) + T.dot(y, U) + T.dot(p, V)),sequences=[Y, P[::-1]], outputs_info=[X])
compute_seq = theano.function(inputs=[X, W, Y, U, P, V], outputs=[results])# test values
x = np.zeros((2), dtype=theano.config.floatX)
x[1] = 1
w = np.ones((2, 2), dtype=theano.config.floatX)
y = np.ones((5, 2), dtype=theano.config.floatX)
y[0, :] = -3
u = np.ones((2, 2), dtype=theano.config.floatX)
p = np.ones((5, 2), dtype=theano.config.floatX)
p[0, :] = 3
v = np.ones((2, 2), dtype=theano.config.floatX)print compute_seq(x, w, y, u, p, v)[0]# comparison with numpy
x_res = np.zeros((5, 2), dtype=theano.config.floatX)
x_res[0] = np.tanh(x.dot(w) + y[0].dot(u) + p[4].dot(v))
for i in range(1, 5):x_res[i] = np.tanh(x_res[i - 1].dot(w) + y[i].dot(u) + p[4-i].dot(v))
print x_res

1.3 Scan 例子: 计算 X的线(指的是按照某一维度方向) 范数

import theano
import theano.tensor as T
import numpy as np# define tensor variable
X = T.matrix("X")
results, updates = theano.scan(lambda x_i: T.sqrt((x_i ** 2).sum()), sequences=[X])
compute_norm_lines = theano.function(inputs=[X], outputs=[results])# test value
x = np.diag(np.arange(1, 6, dtype=theano.config.floatX), 1)
print compute_norm_lines(x)[0]# comparison with numpy
print np.sqrt((x ** 2).sum(1))

1.4 Scan 例子:计算x的列的范数 

import theano
import theano.tensor as T
import numpy as np# define tensor variable
X = T.matrix("X")
results, updates = theano.scan(lambda x_i: T.sqrt((x_i ** 2).sum()), sequences=[X.T])
compute_norm_cols = theano.function(inputs=[X], outputs=[results])# test value
x = np.diag(np.arange(1, 6, dtype=theano.config.floatX), 1)
print compute_norm_cols(x)[0]# comparison with numpy
print np.sqrt((x ** 2).sum(0))

1.5 Scan 例子: 计算x的迹

import theano
import theano.tensor as T
import numpy as np
floatX = "float32"# define tensor variable
X = T.matrix("X")
results, updates = theano.scan(lambda i, j, t_f: T.cast(X[i, j] + t_f, floatX),sequences=[T.arange(X.shape[0]), T.arange(X.shape[1])],outputs_info=np.asarray(0., dtype=floatX))
result = results[-1]
compute_trace = theano.function(inputs=[X], outputs=[result])# test value
x = np.eye(5, dtype=theano.config.floatX)
x[0] = np.arange(5, dtype=theano.config.floatX)
print compute_trace(x)[0]# comparison with numpy
print np.diagonal(x).sum()

1.6 Scan 例子:计算序列 x(t) = x(t - 2).dot(U) + x(t - 1).dot(V) + tanh(x(t - 1).dot(W) + b)

import theano
import theano.tensor as T
import numpy as np# define tensor variables
X = T.matrix("X")
W = T.matrix("W")
b_sym = T.vector("b_sym")
U = T.matrix("U")
V = T.matrix("V")
n_sym = T.iscalar("n_sym")results, updates = theano.scan(lambda x_tm2, x_tm1: T.dot(x_tm2, U) + T.dot(x_tm1, V) + T.tanh(T.dot(x_tm1, W) + b_sym),n_steps=n_sym, outputs_info=[dict(initial=X, taps=[-2, -1])])
compute_seq2 = theano.function(inputs=[X, U, V, W, b_sym, n_sym], outputs=[results])# test values
x = np.zeros((2, 2), dtype=theano.config.floatX) # the initial value must be able to return x[-2]
x[1, 1] = 1
w = 0.5 * np.ones((2, 2), dtype=theano.config.floatX)
u = 0.5 * (np.ones((2, 2), dtype=theano.config.floatX) - np.eye(2, dtype=theano.config.floatX))
v = 0.5 * np.ones((2, 2), dtype=theano.config.floatX)
n = 10
b = np.ones((2), dtype=theano.config.floatX)print compute_seq2(x, u, v, w, b, n)# comparison with numpy
x_res = np.zeros((10, 2))
x_res[0] = x[0].dot(u) + x[1].dot(v) + np.tanh(x[1].dot(w) + b)
x_res[1] = x[1].dot(u) + x_res[0].dot(v) + np.tanh(x_res[0].dot(w) + b)
x_res[2] = x_res[0].dot(u) + x_res[1].dot(v) + np.tanh(x_res[1].dot(w) + b)
for i in range(2, 10):x_res[i] = (x_res[i - 2].dot(u) + x_res[i - 1].dot(v) +np.tanh(x_res[i - 1].dot(w) + b))
print x_res

1.7 Scan 例子:计算 y = tanh(v.dot(A))  关于 x 的jacobian

import theano
import theano.tensor as T
import numpy as np# define tensor variables
v = T.vector()
A = T.matrix()
y = T.tanh(T.dot(v, A))
results, updates = theano.scan(lambda i: T.grad(y[i], v), sequences=[T.arange(y.shape[0])])
compute_jac_t = theano.function([A, v], [results], allow_input_downcast=True) # shape (d_out, d_in)# test values
x = np.eye(5, dtype=theano.config.floatX)[0]
w = np.eye(5, 3, dtype=theano.config.floatX)
w[2] = np.ones((3), dtype=theano.config.floatX)
print compute_jac_t(w, x)[0]# compare with numpy
print ((1 - np.tanh(x.dot(w)) ** 2) * w).T

注意到我们需要对y的索引值而不是y的元素进行迭代。原因在于scan会对它的内部函数创建一个占位符变量,该占位符变量没有和需要替换的那个变量同样的依赖条件。

1.8 Scan 例子: 在scan中累计循环次数

import theano
import theano.tensor as T
import numpy as np# define shared variables
k = theano.shared(0)
n_sym = T.iscalar("n_sym")results, updates = theano.scan(lambda:{k:(k + 1)}, n_steps=n_sym)
accumulator = theano.function([n_sym], [], updates=updates, allow_input_downcast=True)k.get_value()
accumulator(5)
k.get_value()

 1.9 Scan 例子:计算 tanh(v.dot(W) + b) * d ,这里d 是 二项式

import theano
import theano.tensor as T
import numpy as np# define tensor variables
X = T.matrix("X")
W = T.matrix("W")
b_sym = T.vector("b_sym")# define shared random stream
trng = T.shared_randomstreams.RandomStreams(1234)
d=trng.binomial(size=W[1].shape)results, updates = theano.scan(lambda v: T.tanh(T.dot(v, W) + b_sym) * d, sequences=X)
compute_with_bnoise = theano.function(inputs=[X, W, b_sym], outputs=[results],updates=updates, allow_input_downcast=True)
x = np.eye(10, 2, dtype=theano.config.floatX)
w = np.ones((2, 2), dtype=theano.config.floatX)
b = np.ones((2), dtype=theano.config.floatX)print compute_with_bnoise(x, w, b)

注意到如果你想使用一个不会通过scan循环更新的随机变量 d ,你就应该将这个变量作为参数传递给non_sequences 。

1.10 Scan 例子: 计算 pow(A, k)

import theano
import theano.tensor as T
theano.config.warn.subtensor_merge_bug = Falsek = T.iscalar("k")
A = T.vector("A")def inner_fct(prior_result, B):return prior_result * B# Symbolic description of the result
result, updates = theano.scan(fn=inner_fct,outputs_info=T.ones_like(A),non_sequences=A, n_steps=k)# Scan has provided us with A ** 1 through A ** k.  Keep only the last
# value. Scan notices this and does not waste memory saving them.
final_result = result[-1]power = theano.function(inputs=[A, k], outputs=final_result,updates=updates)print power(range(10), 2)
#[  0.   1.   4.   9.  16.  25.  36.  49.  64.  81.]

1.11 Scan 例子: 计算一个多项式

import numpy
import theano
import theano.tensor as T
theano.config.warn.subtensor_merge_bug = Falsecoefficients = theano.tensor.vector("coefficients")
x = T.scalar("x")
max_coefficients_supported = 10000# Generate the components of the polynomial
full_range=theano.tensor.arange(max_coefficients_supported)
components, updates = theano.scan(fn=lambda coeff, power, free_var:coeff * (free_var ** power),outputs_info=None,sequences=[coefficients, full_range],non_sequences=x)polynomial = components.sum()
calculate_polynomial = theano.function(inputs=[coefficients, x],outputs=polynomial)test_coeff = numpy.asarray([1, 0, 2], dtype=numpy.float32)
print calculate_polynomial(test_coeff, 3)
# 19.0

二、Exercise

运行两个例子。

修改并执行多项式的例子,通过scan来进行约间。

答案(Solution

#!/usr/bin/env python
# Theano tutorial
# Solution to Exercise in section 'Loop'
from __future__ import print_function
import numpyimport theano
import theano.tensor as tt# 1. First exampletheano.config.warn.subtensor_merge_bug = Falsek = tt.iscalar("k")
A = tt.vector("A")def inner_fct(prior_result, A):return prior_result * A# Symbolic description of the result
result, updates = theano.scan(fn=inner_fct,outputs_info=tt.ones_like(A),non_sequences=A, n_steps=k)# Scan has provided us with A ** 1 through A ** k.  Keep only the last
# value. Scan notices this and does not waste memory saving them.
final_result = result[-1]power = theano.function(inputs=[A, k], outputs=final_result,updates=updates)print(power(range(10), 2))
# [  0.   1.   4.   9.  16.  25.  36.  49.  64.  81.]# 2. Second examplecoefficients = tt.vector("coefficients")
x = tt.scalar("x")
max_coefficients_supported = 10000# Generate the components of the polynomial
full_range = tt.arange(max_coefficients_supported)
components, updates = theano.scan(fn=lambda coeff, power, free_var:coeff * (free_var ** power),sequences=[coefficients, full_range],outputs_info=None,non_sequences=x)
polynomial = components.sum()
calculate_polynomial1 = theano.function(inputs=[coefficients, x],outputs=polynomial)test_coeff = numpy.asarray([1, 0, 2], dtype=numpy.float32)
print(calculate_polynomial1(test_coeff, 3))
# 19.0# 3. Reduction performed inside scantheano.config.warn.subtensor_merge_bug = Falsecoefficients = tt.vector("coefficients")
x = tt.scalar("x")
max_coefficients_supported = 10000# Generate the components of the polynomial
full_range = tt.arange(max_coefficients_supported)outputs_info = tt.as_tensor_variable(numpy.asarray(0, 'float64'))components, updates = theano.scan(fn=lambda coeff, power, prior_value, free_var:prior_value + (coeff * (free_var ** power)),sequences=[coefficients, full_range],outputs_info=outputs_info,non_sequences=x)polynomial = components[-1]
calculate_polynomial = theano.function(inputs=[coefficients, x],outputs=polynomial, updates=updates)test_coeff = numpy.asarray([1, 0, 2], dtype=numpy.float32)
print(calculate_polynomial(test_coeff, 3))
# 19.0

参考资料:

[1]官网:http://deeplearning.net/software/theano/tutorial/loop.html

Theano2.1.10-基础知识之循环相关推荐

  1. 1.5 Python基础知识 - while循环

    在我们生活中有很多反复要做的事情,或者动作,我们称之为循环.在开发程序中也会有循环的事情要去做,就是需要反复的去执行某个代码,或者反复进行某种演算,直到达到某种条件的时候才会停止.在Python中我们 ...

  2. java基础知识之循环结构与数组

    1.for循环:for(循环变量的初始化1:循环的条件2:循环变量的变化3){ 循环体4: } 执行顺序为:1,2,4,3,2,4,3,2,4,3,2,4,3.....当2为false时结束循环 2. ...

  3. Java基础知识之循环语句(for循环、while循环)

    文章目录 一.for循环 二.while循环 三.各种循环的区别 四.循环注意事项 一.for循环 1.简答说明 for(初始化语句; 条件判断语句; 条件控制语句){循环体语句: } (1)执行初始 ...

  4. C语言基础知识入门【2022】

    一.C语言基础知识入门前言 C语言一经出现就以其特点迅速在全世界普及和推广.C语言不但执行效率高而且可移植性好,可以用来开发应用软件.驱动.操作系统等,也是其它众多高级编程语言的鼻祖语言,所以说学习C ...

  5. vrp 节约算法 c++_数据结构和算法(Golang实现)(8.1)基础知识-前言

    基础知识 学习数据结构和算法.我们要知道一些基础的知识. 一.什么是算法 算法(英文algorithm)这个词在中文里面博大精深,表示算账的方法,也可以表示运筹帷幄的计谋等.在计算机科技里,它表示什么 ...

  6. c 结构体在声明时赋值_Java基础知识 初识Java 循环结构进阶 数组 数据类型 各种运算符...

    今天给大家带来的是初级Java基础部分的知识:包括初始Java.变量.常量.数据类型.运算符.各种选择结构.循环结构.数组等Java的基础语法部分!最后还有****循环结构的进阶****,步骤超详细, ...

  7. [Python学习] 专题二.条件语句和循环语句的基础知识

            前面讲述了"专题一.函数的基础知识",而这篇文章讲述的Python的条件语句和循环语句的基础知识.主要内容包括:         1.条件语句:包括单分支.双分支和 ...

  8. 计算机二级循环储存,【日常干货】计算机二级基础知识(第三期)

    原标题:[日常干货]计算机二级基础知识(第三期) 即便是周末 也不要忘了学习哦 1.下列结构中属于线性结构链式存储的是 A)双向链表 B)循环队列 C)二叉链表 D)二维数组 ▼ A[解析]双向链表也 ...

  9. C/C++基础知识10道题,你都会吗?

    题目1:指针基础知识 题述:描述指针数组和数组指针(指向数组的指针)的区别并举例 考察点:C指针的基础知识 答案:考虑如下 char *q[] = {"xxx", "xx ...

最新文章

  1. CSS教程:div垂直居中的N种方法以及多行文本垂直居中的方法
  2. 在C盘和D盘执行php 结果不同,window_双系统电脑给C盘扩容后导致D盘Win10引导项丢失该怎么办?,为了写个经验,特意把C盘用无 - phpStudy...
  3. android Eclipse导入com.android.internal.R和layoutlib.jar报错解决方案
  4. linux下面升级 Python版本并修改yum属性信息
  5. python实现qq登录界面_使用Python编写一个QQ办公版的图形登录界面!
  6. 计算机小知识分享,分享几小个计算机操作技巧
  7. 机器学习顶刊文献_“大数据+机器学习”在光催化制氢中的研究范式
  8. 【BLE蓝牙学习开发笔记】安利一款简单好用且高性价比的BLE蓝牙抓包器
  9. WareZ入门指南--TLF元老thunderlight
  10. 华为防火墙USG6000V三种管理方法
  11. js实现轮播图背景色随之渐变的效果(小程序版)
  12. 保护模式下的80386及其编程01:数据类型
  13. 三角函数π/2转化_数学集训营 | NO.16 任意角的三角函数之必考点
  14. Invalid bound statement (not found): org.seckill.dao.Suc
  15. HTTP传输大文件的方法
  16. 主分区与逻辑分区的区别
  17. C++ 智能指针(二) std::unique_ptr
  18. 【ThreadPoolTaskExecutor】 SpringBoot 的线程池的使用
  19. Chrome浏览器ERR_INVALID_SIGNED_EXCHANGE解决方案
  20. C#使用随机数模拟器来模拟世界杯排名(一)

热门文章

  1. 鸟叫就能黑掉AI系统,而且你根本察觉不到
  2. 过年回家送什么?这10个教小朋友编程玩具最有科技感
  3. 【洛谷】NOIP2018原创模拟赛DAY1解题报告
  4. 宣城市加快运用大数据推动全域旅游发展
  5. 我要学ASP.NET MVC 3.0(十三): MVC 3.0 防止跨站点请求伪造 (CSRF) 攻击
  6. 创意对抗网络(CANs)你知多少?
  7. BCG菜单button的简单使用
  8. MySQL性能优化-根据执行计划进行性能优化
  9. linux笔记:linux帮助命令,man,help,whatis,apropos
  10. Spring ScheduledTimerTask 定时任务执行