Градиент Theano с функцией на тензорах

У меня есть функция, которая вычисляет значение скалярного поля в трехмерном пространстве, поэтому я передаю ей трехмерные тензоры для координат x, y и z (полученные numpy.meshgrid) и везде использую поэлементные операции. Это работает, как и ожидалось.

Теперь мне нужно вычислить градиент скалярного поля. Я играл с theano.tensor.grad и theano.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]]}))

который возвращает

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

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

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

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

(ненулевые элементы вместе дадут мне ожидаемую матрицу из предыдущего примера)

Есть ли способ получить нужные мне градиенты elmentwise?

Могу ли я, например, как-то определить функцию как скалярную (три скаляра в скалярную) применить ее поэлементно над тензорами координат? Таким образом, производная также будет простым скаляром, и все будет работать гладко.


person cube    schedule 28.05.2016    source источник


Ответы (1)


Первый элемент expr[0,0] как стоимость по отношению к x относится только к первому элементу 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.]]
person Makis Tsantekidis    schedule 28.05.2016
comment
Спасибо, это именно то, что мне было нужно. - person cube; 29.05.2016