T.grad(cost, wrt),一般接收两个参数,第一个参数表示需要求导的函数,放在深度学习的背景下就是代价函数,wrt(with respect to)表示代价函数所关于的参数(通俗地讲,就叫自变量,
f(x)
表示关于
x
的函数
T.grad的第一个参数必须是标量。
>>> import thenao
>>> import theano.tensor as T
>>> x = T.dmatrix('x')
>>> y = x**2+x
>>> gy = T.grad(y, x)
TypeError: cost must be a scalar.
>>> x = T.dmatrix('x')
>>> y = T.sum(x**2+x)
# 这里的T.sum似乎并没有做加和的动作
>>> gy = T.grad(y, x)
>>> f = theano.function([x], gy)
>>> f([[0, 1], [2, 3]])
array([[ 1., 3.],
[ 5., 7.]])
同理,对sigmoid型函数
求导,
>>> 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]])
array([[ 0.25 , 0.19661193],
[ 0.19661193, 0.10499359]])
1. Jacobian 矩阵
在向量分析中,雅克比矩阵是一阶偏导数以一定方式排列成的矩阵,其行列式称为雅克比行列式。
假设
F:Rn→Rm
是一个从欧氏
n
维空间转换到
此矩阵表示为: JF(x1,…,xn) ,或者 ∂(y1,…,ym)∂(x1,…,xn)
>>> 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([3, 4])
array([[ 6., 0.],
[ 0., 8.]])
再考虑这样一个向量, f(x)=[3x21+x2ln(x1)sin(x2)]T ,则 Jacobian 为:
2. Hessian矩阵
Hessian matrix是一个自变量为向量的实值函数的二阶偏导数组成的方块矩阵,此函数如下:
如果 f 的所有二阶导数都存在,那么
其中 x=(x1,x2,…,xn) ,即 H(f) 为:
>>> x = T.dvector('x')
>>> y = x**2
>>> cost = T.sum(y)
>>> 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([3, 4])
array([[ 2., 0.],
[ 0., 2.]])