本文为Lancelod_Liu编译, 转载请保留此行.
This Article is translated and edited by Lancelod_Liu, keep this line if you share it.
原文:戳.
初步 - 基本运算
两个标量相加
下面的语句展示了如何使用Theano进行计算2个数的和.
>>> import theano.tensor as T
>>> from theano import function
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
>>> z = x + y
>>> f = function([x, y], z)
我们可以使用上面创建的函数进行计算任意的两个数(就和C语言的函数一样)
>>> f(2, 3)
array(5.0)
>>> f(16.3, 12.1)
array(28.4)
一步一步地拆分这堆代码吧. 第一步是定义2个符号(变量), 它们代表了你想要相加的值. 注意从现在开始, 我们会使用"变量"来指代"符号"(x,y,z都是变量对象). 函数f的输出是一个numpy.ndarray, 只不过是0维的(标量).
当你键入这两行代码的时候你会发现执行function指令会有一些延迟. 在底层, f被编译成C代码.
Step 1
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
在Theano中, 所有的符号都必须被显示声明. 比如, T.dscalar 是我们赋予的0维(scalar)浮点(d)数组. 它是一个 TheanoType.
dscalar 并非一个类. 因此, x和y实际上都不是dscalar的实例. 它们都是TensorVariable的实例. x和y实际上仅仅是在它们的type域中赋了dscalar的值. 如下:
>>> type(x)
<class 'theano.tensor.basic.TensorVariable'>
>>> x.type
TensorType(float64, scalar)
>>> T.dscalar
TensorType(float64, scalar)
>>> x.type is T.dscalar
True
通过带字符串参数调用T.dscalar, 你就创建了一个代表浮点标量的变量, 其名为字符串参数. 如果你没有给出字符串参数, 那么这个符号变量就没有名字. 名字并非必须, 但有助于调试. 讲到Theano的结构时我们会讲解更多. 你也可以在这里学习更多:Graph Structures.
Step 2
第二步是把x 和 y 相加得到和 z:
>>> z = x + y
z 是另一个变量, 代表着x和y的和.你可以使用pp函数来"优雅"地打印出与z相关的运算.
>>> from theano import pp
>>> print pp(z)
(x + y)
Step 3
最后一步是把 x 和 y 作为输入, 把z作为输出:
>>> f = function([x, y], z)
function 的第一个参数是一个变量列表, 它们是函数的输入. 第二个参数可以是变量或变量列表. 两种情况下, 第二个参数都是我们使用函数时希望看到的输出. f 此时就可以作为一个普通Python函数来使用了.
注意
你可以跳过第三步来快速使用这个特性. 只要使用一个变量的eval() 方法.eval() 方法并不如function() 灵活 但它几乎可以解决任何我们在这个教程中遇到的问题. 它使得你不需要import function(), 下面是eval()的用法:
>>> import theano.tensor as T
>>> x = T.dscalar('x')
>>> y = T.dscalar('y')
>>> z = x + y
>>> z.eval({x : 16.3, y : 12.1})
array(28.4)
我们给 eval() 传递了一个字典, 映射了符号变量<->值, 它返回了计算表达式的结果.
eval() 首次调用时会比较慢, 它需要调用function() 来编译表达式. 之后使用同样的变量调用eval()将会很快, 因为变量缓存了编译好的函数.
Adding two Matrices
你可能已经会了. 实际上, 唯一的改变就是你需要使用矩阵类型初始化x和y:
>>> x = T.dmatrix('x')
>>> y = T.dmatrix('y')
>>> z = x + y
>>> f = function([x, y], z)
dmatrix 是浮点型矩阵. 我们可以对2D arrays使用新的函数 :
>>> f([[1, 2], [3, 4]], [[10, 20], [30, 40]])
array([[ 11., 22.],
[ 33., 44.]])
变量是一个 NumPy 数组(array). 我们也可以使用NumPy数组(array)直接做输入:
>>> import numpy
>>> f(numpy.array([[1, 2], [3, 4]]), numpy.array([[10, 20], [30, 40]]))
array([[ 11., 22.],
[ 33., 44.]])
矩阵和标量/标量, 向量和标量的相加都是可以的. 具体的变化参考 broadcasting.
共有下面的变量类型:
- byte: bscalar,bvector, bmatrix, brow, bcol, btensor3, btensor4
- 16-bit integers: wscalar,wvector, wmatrix, wrow, wcol, wtensor3, wtensor4
- 32-bit integers: iscalar,ivector, imatrix, irow, icol, itensor3, itensor4
- 64-bit integers: lscalar,lvector, lmatrix, lrow, lcol, ltensor3, ltensor4
- float: fscalar,fvector, fmatrix, frow, fcol, ftensor3, ftensor4
- double: dscalar,dvector, dmatrix, drow, dcol, dtensor3, dtensor4
- complex: cscalar,cvector, cmatrix, crow, ccol, ctensor3, ctensor4
所有的变量类型参考: tensor creation.
注意
使用者--而不是系统架构者--必须选择你使用32还是64位的整数(i或l前缀)和浮点(f和d前缀).
Exercise
import theano
a = theano.tensor.vector() # declare variable
out = a + a ** 10 # build symbolic expression
f = theano.function([a], out) # compile function
print f([0, 1, 2]) # prints `array([0, 2, 1026])`
Modify and execute this code to compute this expression: a ** 2 + b ** 2 + 2 * a * b.