您的位置:首页 > 其它

Theano Tutorial文档翻译(五) - 衍生工具

2016-08-16 00:27 274 查看

Theno Tutorial文档翻译(五) - Theano的衍生工具

很多一知半解的,直接翻译过去了,就当个笔记看看吧。

原文地址:http://deeplearning.net/software/theano/tutorial/gradients.html

Computing Gradients 计算梯度

让我们用Theano来完成一个更复杂的任务:新建一个计算梯度的函数。为了完成这个任务我们要用到
T.grad
。例如,我们可以计算
x**2
x
的导数。即
d(x**2)/dx=2*x


import numpy
import theano
import theano.tensor as T
from theano import pp
x = T.dscalar('x')
y = x ** 2
gy = T.grad(y, x)
pp(gy)

# '((fill((x ** TensorConstant{2}), TensorConstant{1.0}) * TensorConstant{2}) * (x ** (TensorConstant{2} - TensorConstant{1})))'

f = theano.function([x], gy)
f(4)
# 8.0
numpy.allclose(f(94.2), 188.4)


在这个例子中,我们可以从
pp(gy)
中看到我们计算了正确的符号梯度。
fill((x ** 2), 1.0)
意味着我们生成一个和
x**2
一样大小的矩阵并且赋值1.0。

注意:优化器简化了符号梯度的表达式。你可以通过进一步挖掘他的内部性质的编译函数来看到它。pp(f.maker.fgraph.outputs[0]) #(2.0 * x)


我们可以计算一些复杂函数的梯度,例如之前的逻辑斯特函数。它的导数是
ds(x)/dx = s(x)*(1-s(x))




一个逻辑斯特导数的分布图,横坐标是x,纵坐标是ds(x)/dx

x = T.dmatrix('x')
s = T.sum(1 / (1 + T.exp(-x)))
gs = T.grad(s, x)
dlogistic = theano.function([x], gs)
dlogistic([[0,1], [-1,-2]])


通常地对于任意scalar表达式,
T.grad(s,w)
为theano提供了计算
ds/dw
。这样Theano可以被用作高效的符号微分。(
T.grad
表达式的返回在编译会被优化),即使是多输入函数。(automatic differentiation,一个符号微分的描述)

注意:T.grad的第二个参数可以是一个列表,那么输出也是一个列表。两个列表的顺序是很重要的:输入和输出一一对应


Computing the Jacobian 计算雅可比

在Theano,Jacobian指明了张量的输出对输入的偏导数。(这在数学中也叫雅可比矩阵)。如果需要计算雅可比,Theano提供了
theano.gradient.jacobian()


为了计算函数y对x的导数,我们需要使用到
scan
。这个函数就是循环遍历y并且计算y[i]对x的梯度。

注意:scan在Theano是一个通用的允许在所有符号方程进行的重复操作。


import theano
import theano.tensor as T
x = T.dvector('x')
y = x ** 2
J, updates = theano.scan(lambda i,y,x: T.grad(y[i], x), sequences=T.arange(y.shape[0]), non_sequences=[y,x])
f = theano.function([x], J, updates=updates)
f([4,4])


我们在这段代码里,
T.arange
生成一个0到
y.shape[0]
的整数序列。然后我们通过这个序列来循环,在每一步中,我们计算y[i]对x的导数。
scan
自动地链接所有列,生成一个雅可比矩阵。

注意:这里有一些关于T.grad的陷阱。一个是你不可以以 theano.scan(lambda y_i,x : T.grad(y_i,x), sequences=y, non_sequences=x) 重写上面雅可比的表达式。即使这看起来是可行的,但是因为y_i不是x的函数,y[i]才是。


Computing the Hessian 计算海森

在Theano,Hessian有数学解释:是矩阵的二阶导数。Theano提供了
theano.gradient.hessian()
函数来实现。

你可以先计算雅可比那样计算Hessian。唯一不同的就是,我们计算
T.grad(cost,x)
的雅可比而不是计算y的雅可比,cost是一些标量。

x = T.dvector('x')
y = x ** 2
cost = y.sum()
gy = T.grad(cost, x)
H, updates = theano.scan(lambda i,gy,x: T.grad(gy[i],x), sequences=T.arange(gy.shape[0]), non_sequences=[gy,x])
f = theano.function([x], H, updates=updates)
f([4,4])


Jacobian times a Vector 雅可比的一个向量

有时候我们可以用Jacobians times vectors 或者 vectors times Jacobians的术语来表达一个算法。这种方法可以计算得到我们想要的结果Jacobian的求值。具体参考:

Barak A. Pearlmutter, “Fast Exact Multiplication by the Hessian”, Neural Computation, 1994

我们想要Theano自动为我们实现这个功能。

R-operator R操作

R操作是为了评估一个雅可比和一个向量的
df(x)/dx
v。这个公司可以被扩展即使x是一个矩阵或者张量,例如雅可比是一个张量或者是一个张量的生成。因为通常我们一计算这样一个权值矩阵为结束,Theano提供这样一个一般性的操作。为了评估R操纵的表达式y,以x为参数,你要做类似的事就是用一个雅可比乘v:

W = T.dmatrix('W')
V = T.dmatrix('V')
x = T.dmatrix('x')
y = T.dot(x, W)
JV = T.Rop(y, W, V)
f = theano.function([W, V, x], JV)
f([[1,1],[1,1]],[[2,2],[2,2]], [0,1])


L-operator L操作

类似地,L操作会计算没一行的雅可比,数学表达式:v
df(x)/dx


W = T.dmatrix('W')
v = T.dmatrix('v')
x = T.dvector('x')
y = T.dot(x, W)
VJ = T.Lop(y, W, v)
f = theano.function([v, x], VJ)
f([2,2], [0,1])


注意:两个操作的v是不同含义的。在L操作中,v必须和输出有相同的形状,在R操作需要和输入有相同的形状。还有,两个结构的输出也不一样。L操作的结果和输入有相同形状,R操作和输出有相同形状。


Hessian times a Vector 海森的向量

L操作

x = T.dvector('x')
v = T.dvector('v')
y = T.sum(x**2)
gy = T.grad(y, x)
vH = T.grad(T.sum(gy*v), x)
f = theano.function([x,y], vH)
f([4,4], [2,2])


R操作

x = T.dvector('x')
v = T.dvector('v')
y = T.sum(x ** 2)
gy = T.grad(y, x)
Hv = T.Rop(gy, x, v)
f = theano.function([x, v], Hv)
f([4,4], [2,2])


总结

grad
函数符号化:它接受和返回Theano的变量

grad
和宏相比可以重复应用

标量成本只可以被
grad
直接处理。数组被重复应用处理。

Built-in函数计算雅可比向量或海森向量会有效点。

在优化器过程中的工作需要有效计算全雅可比和海森,或雅可比向量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  theano