Объединение скаляров и векторов в Theano для вычисления гессиана
Я пытаюсь использовать Theano для вычисления гессиана функции по отношению к вектору, а также к паре скаляров (редактировать: я хочу, чтобы скаляры добавлялись к вектору, для которого я вычисляю гессиан относительно), Вот минимальный пример:
import theano
import theano.tensor as T
A = T.vector('A')
b,c = T.scalars('b','c')
y = T.sum(A)*b*c
Моя первая попытка была:
hy = T.hessian(y,[A,b,c])
Который не с AssertionError: tensor.hessian expects a (list of) 1 dimensional variable as 'wrt'
Моя вторая попытка состояла в том, чтобы объединить A, b и c с:
wrt = T.concatenate([A,T.stack(b,c)])
hy = T.hessian(y,[wrt])
Который не с DisconnectedInputError: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: Join.0
Как правильно вычислить гессиан в этом случае?
Обновление: чтобы уточнить, что я ищу, предположим, что A - это вектор из 2 элементов. Тогда гессиан будет:
[[d2y/d2A1, d2y/dA1dA2, d2y/dA1dB, d2y/dA1dC],
[d2y/dA2dA1, d2y/d2A2, d2y/dA2dB, d2y/dA2dC],
[d2y/dBdA1, d2y/dBdA2, d2y/d2B, d2y/dABdC],
[d2y/dCdA1, d2y/dCdA2, d2y/dCdB, d2y/d2C]]
который для примера функции y
должно быть:
[[0, 0, C, B],
[0, 0, C, B],
[C, C, 0, A1+A2],
[B, B, A1+A2, 0]]
Так что, если мы должны были определить функцию:
f = theano.function([A,b,c], hy)
затем, предполагая, что мы могли бы вычислить hy
успешно, мы ожидаем, что результат:
f([1,1], 4, 5) =
[[0, 0, 5, 4],
[0, 0, 5, 4],
[5, 5, 0, 2],
[4, 4, 2, 0]]
В моем реальном приложении А имеет 25 элементов и y
сложнее, но идея та же.
2 ответа
Если вы пройдете b,c
как векторы, это должно работать. Гессианский оператор ожидает одномерные массивы. Хотя скаляры тоже должны работать, вероятно, проще всего просто указать тип ввода, который ему нравится.
Причиной неудачи в укладке является то, что stack
Операция выдает новую переменную, не являющуюся конечным узлом в другой ветви графа, относительно которой вы не можете явно брать производные явно. Так что Теано просто не позволяет этого.
Это работает для меня:
import theano.tensor as T
A = T.vector('A')
b,c = T.vectors('b','c')
y = T.sum(A)*b[0]*c[0]
hy = T.hessian(y,[A,b,c])
Основываясь на предложении @eickenberg объединить входные данные на уровне numpy, я использовал следующий обходной путь:
import theano
import theano.tensor as T
A,temp = T.vectors('A','T')
b,c = T.scalars('b','c')
y = T.sum(A)*b*c
y2 = theano.clone(y,{A:temp[:-2],b:temp[-2],c:temp[-1]})
hy = T.hessian(y2,[temp])
f = theano.function([temp], hy)
f([1,1,4,5])
дает ожидаемый результат:
> [array([[ 0., 0., 5., 4.],
> [ 0., 0., 5., 4.],
> [ 5., 5., 0., 2.],
> [ 4., 4., 2., 0.]])]
Это работает, но чувствует себя довольно неловко, если кто-нибудь знает лучшее (более общее) решение, пожалуйста, дайте мне знать.