Theano2.1.2-基础知识之第一步:代数

时间:2023-03-08 17:00:39

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

Baby Steps - Algebra

一、两个标量相加

在学习theano的开始,首先来感受下它是如何工作的,让我们先来定义一个简单的相加函数:

>>> 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)

现在,我们可以使用之前创建好的函数,然后使用了:

>>> f(2, 3)
array(5.0)
>>> f(16.3, 12.1)
array(28.4)

这里是将上面部分进行分步介绍。首先定义两个符号 (变量)来表示你想要相加的数。注意到从现在开始,我们将会使用变量(Variable)来表示“符号”(换句话说,也就是 xyz 都是变量对象)。函数 f 的输出就是一个有着0维的 numpy.ndarray 。

如果你想要输入一个整数,你可能会发现在执行function的时候有轻微的延时。这是因为需要将函数 f 编译成c 代码。

第一步

>>> x = T.dscalar('x')
>>> y = T.dscalar('y')

在theano中,所有的符号都必须手动输入。具体来说,T.dscalar 就是我们分配给“doubles类型(d)的0维数组(scalar)”类型。这是一个theano类型 Type.

  dscalar 不是一个类,所以 x 和 y 都不是 dscalar的实例。他们是 TensorVariable的实例 。正如下面看到的:

>>> 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 ,可以创建一个变量来表示一个给定名字下的一个浮点标量。如果你不提供参数,该符号将会是未命名的(unnamed)。虽然名字是不是必须的,可是却有助于调试。

更多的可以看看theano的内部结构。同样可以看看 Graph Structures.

第二步

第二步就是结合 x 与y 到它们的和z中

>>> z = x + y

z 是另一个变量用来表示 x 与 y的和.
你可以使用 pp 函数来友好的打印出与z
关联的计算结果。

>>> from theano import pp
>>> print pp(z)
(x + y)

第三步

最后一步就是创建一个函数,将x 与 y  作为输入,然后通过z  作为输出:

>>> f = function([x, y], z)

function 的第一个参数是变量的列表,用来作为输入提供给函数。第二个参数是一个单一的变量或者一个变量列表。在其他情况下,第二个变参数就是我们想要的输出。然后f
就可以被和普通的python函数一样使用了。
note:作为一个快捷方式,你可以跳过第三步,值使用一个变量的eval() 方法。 eval() 方法没有 function() 这么灵活,不过却能做教程中的任何事情。这是你不需要inport 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()传递一个词典,将符号theano变量映射成值从而来取代它们,然后对表达式返回数值。

eval() 在第一次调用的时候可能会比较慢,因为它需要调用 function() 来计算场景后面的表达式。之后对 eval() 以同样的变量上的调用将会很快,因为变量已经将编译后的函数进行缓存了。

二、两个矩阵相加

你可能已经猜到如何来做了确实,这里与之前唯一的区别在于你需要实例化x 与y ,然后使用矩阵类型:

>>> x = T.dmatrix('x')
>>> y = T.dmatrix('y')
>>> z = x + y
>>> f = function([x, y], z)

  dmatrix 是doubles类型的矩阵,然后我们就能在2D数组上使用新的函数了:

>>> f([[1, 2], [3, 4]], [[10, 20], [30, 40]])
array([[ 11., 22.],
[ 33., 44.]])

该变量是一个 NumPy 数组。我们同样可以直接使用NumPy 数组作为输入:

>>> import numpy
>>> f(numpy.array([[1, 2], [3, 4]]), numpy.array([[10, 20], [30, 40]]))
array([[ 11., 22.],
[ 33., 44.]])

计算矩阵加标量、矩阵加向量、向量加标量都是可以的。这些能够得以实现得归功于broadcasting.

下面的类型都是可用的:

  • bytebscalar, bvector, bmatrix, brow, bcol, btensor3, btensor4
  • 16-bit integerswscalar, wvector, wmatrix, wrow, wcol, wtensor3, wtensor4
  • 32-bit integersiscalar, ivector, imatrix, irow, icol, itensor3, itensor4
  • 64-bit integerslscalar, lvector, lmatrix, lrow, lcol, ltensor3, ltensor4
  • floatfscalar, fvector, fmatrix, frow, fcol, ftensor3, ftensor4
  • doubledscalar, dvector, dmatrix, drow, dcol, dtensor3, dtensor4
  • complexcscalar, cvector, cmatrix, crow, ccol, ctensor3, ctensor4

上面的列表不够详尽,针对使用Numpy数组来兼容所有类型的更详细文档可以看: tensor creation.

note:你,用户(不是系统架构者)不得不选择你的程序为32- 或者 64-bit 的整数 (i 前缀 vs. l 前缀) 和浮点数 (f 前缀 vs. d 前缀).

三、练习

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])`

修改并计算这个表达式的结果: a ** 2 + b ** 2 + 2 * a * b.

下面就是答案:

#!/usr/bin/env python
# Theano tutorial
# Solution to Exercise in section 'Baby Steps - Algebra' from __future__ import print_function
import theano
a = theano.tensor.vector() # declare variable
b = theano.tensor.vector() # declare variable
out = a ** 2 + b ** 2 + 2 * a * b # build symbolic expression
f = theano.function([a, b], out) # compile function
print(f([1, 2], [4, 5])) # prints [ 25. 49.]

参考资料:

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