2017-05-18 1 views
0

Comme la question le suggère, je voudrais calculer le gradient par rapport à une rangée de matrice. Dans le code:gradient de theano par rapport à la ligne de matrice

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)) 

Comme les commentaires l'indiquent, le code fonctionne sans problème lorsque je calcule le gradient par rapport à la matrice entière. Dans ce cas, le gradient est correctement calculé, mais le problème est que le résultat n'a que des entrées non nulles dans la ligne 0 (car les autres lignes de x n'apparaissent évidemment pas dans les équations de la première ligne de y).

J'ai trouvé this question, suggérant de stocker toutes les lignes de la matrice dans des variables séparées et de construire des graphiques à partir de ces variables. Dans mon cadre cependant, je n'ai aucune idée de combien de lignes pourraient être dans X.

Est-ce que quelqu'un aurait une idée de comment obtenir le gradient par rapport à une seule rangée d'une matrice ou comment je pourrais omettre les zéros supplémentaires dans la sortie? Si quelqu'un avait des suggestions sur la façon d'empiler un nombre arbitraire de vecteurs, cela devrait fonctionner aussi, je suppose.

Répondre

0

je réalise qu'il est possible de se débarrasser des zéros lors du calcul des dérivés par rapport aux entrées dans la ligne i:

t_g = T.grad(t_y[i,0], t_x)[i] 

et pour calculer le jacobien, j'ai découvert que

t_g = T.jacobian(t_y[i], t_x)[:,i] 

fait l'affaire. Cependant, il semble avoir un impact plutôt lourd sur la vitesse de calcul.


Il serait également possible d'aborder ce problème mathématiquement. Le Jacobien de la multiplication matricielle t_y w.r.t. t_x est simplement la transposition de t_w.T, qui est t_w dans ce cas (la transposition de la transposition est la matrice originale). Ainsi, le calcul serait aussi simple que

t_g = t_w