有效计算theano中层的雅可比行列式

时间:2017-06-02 07:35:20

标签: python theano backpropagation

我想仔细研究完全连接的神经网络中每层的雅可比行列式,即∂y/∂x,其中x是层的输入向量(激活前一层),y是输出向量(激活该层的这一层。

在线学习计划中,可以通过以下方式轻松完成:

import theano
import theano.tensor as T
import numpy as np

x = T.vector('x')
w = theano.shared(np.random.randn(10, 5))
y = T.tanh(T.dot(w, x))

# computation of Jacobian
j = T.jacobian(y, x)

在批量学习时,您需要额外扫描才能获得每个样本的雅可比行列式

x = T.matrix('x')
...

# computation of Jacobian
j = theano.scan(lambda i, a, b : jacobian(b[i], a)[:,i], 
    sequences = T.arange(y.shape[0]), non_sequences = [x, y]
)

这对于玩具示例非常有效,但是当学习具有1000个隐藏单元和数千个样本的多个层的网络时,这种方法会导致计算的大幅减速。 (索引Jacobian结果的想法可以在this question

中找到

当我们已经在计算损失的导数时,我认为不需要这种显式的雅可比计算。毕竟,关于例如损失的梯度。网络的输入,可以分解为
∂L(y,yL)/∂x=∂L(y,yL)/∂yL∂yL/∂y(L-1)∂y(L-1)/∂y(L-2)...∂ y2 /∂y1∂y1/∂x
即损失的梯度w.r.t. x是每层衍生物的乘积(L将是这里的层数)。

我的问题是,是否(以及如何)可以避免额外的计算并使用上面讨论的分解。我认为它应该是可能的,因为自动区分实际上是链规则的应用(据我所知)。但是,我似乎没有找到任何可以支持这个想法的东西。有任何建议,提示或指示吗?

1 个答案:

答案 0 :(得分:0)

T.jacobian效率非常低,因为它在内部使用扫描。如果您计划将雅可比矩阵与某些东西相乘,则应分别使用T.LopT.Rop进行左/右乘法。目前,“智能”jacobian在渐变模块中不存在theano。如果你想要优化的雅可比,你必须手工制作它们。

请尽可能使用T.scan等批量操作,而不是使用T.batched_dotT.scan将始终导致CPU循环。