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

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


很多一知半解的,直接翻译过去了,就当个笔记看看吧。
原文地址:http://deeplearning.net/software/theano/tutorial/gradients.html


Computing Gradients 计算梯度

让我们用Theano来完成一个更复杂的任务:新建一个计算梯度的函数。为了完成这个任务我们要用到T.grad。例如,我们可以计算x**2x的导数。即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)/dxv。这个公司可以被扩展即使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操作会计算没一行的雅可比,数学表达式:vdf(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函数计算雅可比向量或海森向量会有效点。
  • 在优化器过程中的工作需要有效计算全雅可比和海森,或雅可比向量。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值