正如问题所示,我想计算相对于矩阵行的梯度。在代码中:
import numpy.random as rng
import theano.tensor as T
from theano import function
t_x = T.matrix('X')
t_w = T.matrix('W')
t_y = T.dot(t_x, t_w.T)
t_g = T.grad(t_y[0,0], t_x[0]) # my wish, but DisconnectedInputError
t_g = T.grad(t_y[0,0], t_x) # no problems, but a lot of unnecessary zeros
f = function([t_x, t_w], [t_y, t_g])
y,g = f(rng.randn(2,5), rng.randn(7,5))
正如评论所示,当我计算相对于整个矩阵的梯度时,代码没有任何问题。在这种情况下,正确计算了梯度,但问题是结果在第0行中只有非零条目(因为x的其他行显然没有出现在y的第一行的等式中)。
我找到this question,建议将矩阵的所有行存储在单独的变量中,并根据这些变量构建图形。但在我的设置中,我不知道X
中可能有多少行。
是否有人知道如何获得相对于矩阵的单行的渐变或如何省略输出中的额外零?如果有人会建议如何堆叠任意数量的矢量,那我也应该这样做。
答案 0 :(得分:0)
我意识到在计算行i
中的条目的衍生物时可以删除零:
t_g = T.grad(t_y[i,0], t_x)[i]
为了计算雅可比,我发现了
t_g = T.jacobian(t_y[i], t_x)[:,i]
诀窍。然而,它似乎对计算速度有相当大的影响。
也可以用数学方法解决这个问题。矩阵乘法的雅可比行列式t_y
w.r.t. t_x
只是t_w.T
的转置,在这种情况下为t_w
(转置的转置是原始矩阵)。因此,计算就像
t_g = t_w