具有张量函数的 Theano 梯度

Theano gradient with function on tensors

我有一个计算 3D 标量场值的函数 space,所以我为它提供 x、y 和 z 坐标的 3D 张量(由 numpy.meshgrid 获得)并使用无处不在的元素操作。这按预期工作。

现在我需要计算标量场的梯度。我一直在玩 theano.tensor.gradtheano.tensor.jacobian,但我不明白元素运算的导数应该如何工作。

这是一个我不明白的MWE:

import theano.tensor as T 

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.grad(expr[0, 0], x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

它打印

[[ 2.  0.]
 [ 0.  0.]]

虽然我希望

[[ 2.  4.]
 [ 2.  4.]]

我也试过 jacobian:

import theano.tensor as T

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.jacobian(expr.flatten(), x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

哪个returns

[[[ 2.  0.]
  [ 0.  0.]]

 [[ 0.  4.]
  [ 0.  0.]]

 [[ 0.  0.]
  [ 2.  0.]]

 [[ 0.  0.]
  [ 0.  4.]]]

(非零元素加在一起会给出上一个示例中的预期矩阵)

有什么方法可以得到我需要的 elmentwise 梯度吗?

例如,我能否以某种方式将函数定义为标量(将三个标量转换为一个标量)将其逐元素应用于坐标张量?这样,导数也将只是一个简单的标量,一切都会顺利进行。

作为相对于 x 的成本的第一个元素 expr[0,0] 仅与 x 的第一个元素相关,因此您收到的结果是正确的。

如果对整个 expr 数组求和,就会产生您期望的结果。 Theano 将负责通过 sum

向后传播梯度
import theano.tensor as T 

x, y = T.matrices("xy")

expr = x**2 + y
grad = T.grad(expr.sum(), x)
print(grad.eval({x: [[1, 2], [1, 2]], y: [[1, 1], [2, 2]]}))

打印

[[ 2.  4.]
 [ 2.  4.]]