来自: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] = 2 print 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 = False k = 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 = False coefficients = 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 numpy import theano
import theano.tensor as tt # 1. First example theano.config.warn.subtensor_merge_bug = False k = 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 example coefficients = 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 scan theano.config.warn.subtensor_merge_bug = False coefficients = 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. 数据结构和算法(Golang实现)(10)基础知识-算法复杂度主方法

    算法复杂度主方法 有时候,我们要评估一个算法的复杂度,但是算法被分散为几个递归的子问题,这样评估起来很难,有一个数学公式可以很快地评估出来. 一.复杂度主方法 主方法,也可以叫主定理.对于那些用分治法 ...

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

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

  3. 1.6 Python基础知识 - for循环

    在循环语句中,除了while循环外,还有一种循环叫for循环的循环语句,for循环语句用于遍历可迭代(什么是迭代?以及迭代的相关知识,我们到后面再进行阐述,这里只要记住就可以了.)对象集合中的元素,并 ...

  4. 1.10 基础知识——GP3.1 制度化 & GP3.2 收集改进信息

    摘要: GP3.1是要求建立组织级的关于该过程的制度.标准.模版等全套体系,要求覆盖该PA所有的SP和GP.GP3.2 体现的是持续改进,每个过程都应该收集相应的改进信息. 正文: GP3.1 Est ...

  5. C语言基础知识【循环】

    C 循环1.有的时候,我们可能需要多次执行同一块代码.一般情况下,语句是按顺序执行的:函数中的第一个语句先执行,接着是第二个语句,依此类推.编程语言提供了更为复杂执行路径的多种控制结构.循环语句允许我 ...

  6. python基础知识(循环语句)

    for循环.while循环.循环嵌套 for 迭代变量 In 对象: 循环体 range(start,end,step) 第一个和第三个可以省略生成一系列的连续整数 start 包括起始值 end  ...

  7. 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号

    算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...

  8. 数据结构和算法(Golang实现)(8.1)基础知识-前言

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

  9. 数据结构和算法(Golang实现)(8.2)基础知识-分治法和递归

    分治法和递归 在计算机科学中,分治法是一种很重要的算法. 字面上的解释是分而治之,就是把一个复杂的问题分成两个或更多的相同或相似的子问题. 直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合 ...

随机推荐

  1. 从Prototype学习JavaScript面向对象编程

    概述 JavaScript是一种基于对象的编程语言.它是灵活的,既有面向过程(也就是面向函数)的编程,也有面向对象的编程.因此我称它是基于对象的编程语言. 对于JavaScript的面向过程的编程特性 ...

  2. 小议如何使用APPLY

    简介 如果你打算为在结果集中的每条记录写一个调用表值函数或者表值表达式的select语句,那么你就能用到APPLY 操作符来实现.一般又两种形式写法: 第一种格式就是CROSS APPLY.这种格式可 ...

  3. WIN7管理工具配置ODBC数据源-系统DSN中无Oracle,Sybase驱动的解决方法

    在C:\Windows\SysWOW64下找到: odbcad32.exe 这个文件,双击打开. 点击添加按钮,选择 对应的 驱动,然后就可用添加连接Oracle/Sybase的ODBC的数据源了.

  4. 猜拳游戏GuessGame源码

    该游戏是一款比较不错的猜拳游戏GuessGame源码案例,GuessGame——猜拳游戏,这也是我自己的第一款休闲类的游戏案例,游戏实现也比较简单的,希望这个能够帮大家的学习和使用,更多安卓源码尽在源 ...

  5. To create my first app in iOS with Xcode(在Xcode创建我的第一个iOS app )

    To create my first app in iOS create the project. In the welcome window, click “Create a new Xcode p ...

  6. Linux screen 命令

    简单的来说 在screen里面敲的命令都是在后台的,所以不需要想bg那样,ctrl+z在bg把后台服务运行起来.而且下次可以直接进去screen作业的后台界面,可以看到我们过去敲的命令记录,即使你的C ...

  7. Terminal中输入命令直接打开QtCreator,以及创建其桌面快捷方式

    工业项目设计学习第一步,熟悉开发工具 Qt学习论坛,东西多,但也杂 emouse的博客,以前学习STM32开发环境搭建时也是参考这位博主的 更多详细的步骤在上面都能找到,今天先不写,等明天把硬件设备全 ...

  8. POJ3255Roadblocks[次短路]

    Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12697   Accepted: 4491 Descr ...

  9. arr的高级用法

    arr的高级用法 reduce 方法(升序) 语法: array1.reduce(callbackfn[, initialValue]) 参数 定义 array1 必需.一个数组对象. callbac ...

  10. idea常用快捷键

    十大Intellij IDEA快捷键 2015-01-16 21:31 122307人阅读 评论(38) 收藏 举报 本文章已收录于: .embody { padding: 10px 10px 10p ...