2015-12-26 4 views
0

Je joue avec les Rnn de vanille, s'entraînant avec la descente de gradient (version non-batch), et j'ai un problème avec le calcul de gradient pour le coût (scalaire); voici la partie pertinente de mon code:Problème avec le gradient de calcul pour Rnn dans Theano

class Rnn(object): 
# ............ [skipping the trivial initialization] 
    def recurrence(x_t, h_tm_prev): 
     h_t = T.tanh(T.dot(x_t, self.W_xh) + 
        T.dot(h_tm_prev, self.W_hh) + self.b_h) 
     return h_t 

    h, _ = theano.scan(
     recurrence, 
     sequences=self.input, 
     outputs_info=self.h0 
    ) 

    y_t = T.dot(h[-1], self.W_hy) + self.b_y 
    self.p_y_given_x = T.nnet.softmax(y_t) 

    self.y_pred = T.argmax(self.p_y_given_x, axis=1) 


def negative_log_likelihood(self, y): 
    return -T.mean(T.log(self.p_y_given_x)[:, y]) 


def testRnn(dataset, vocabulary, learning_rate=0.01, n_epochs=50): 
    # ............ [skipping the trivial initialization] 
    index = T.lscalar('index') 
    x = T.fmatrix('x') 
    y = T.iscalar('y') 
    rnn = Rnn(x, n_x=27, n_h=12, n_y=27) 
    nll = rnn.negative_log_likelihood(y) 
    cost = T.lscalar('cost') 
    gparams = [T.grad(cost, param) for param in rnn.params] 
    updates = [(param, param - learning_rate * gparam) 
       for param, gparam in zip(rnn.params, gparams) 
       ] 
    train_model = theano.function(
     inputs=[index], 
     outputs=nll, 
     givens={ 
      x: train_set_x[index], 
      y: train_set_y[index] 
     }, 
    ) 
    sgd_step = theano.function(
     inputs=[cost], 
     outputs=[], 
     updates=updates 
    ) 
    done_looping = False 
    while(epoch < n_epochs) and (not done_looping): 
     epoch += 1 
     tr_cost = 0. 
     for idx in xrange(n_train_examples): 
      tr_cost += train_model(idx) 
     # perform sgd step after going through the complete training set 
     sgd_step(tr_cost) 

Pour certaines raisons, je ne veux pas transmettre des données complètes (formation) au train_model (..), au lieu que je veux transmettre des exemples individuels à la fois. Maintenant, le problème est que chaque appel à train_model (..) me renvoie le coût (log-vraisemblance négative) de cet exemple particulier et ensuite je dois agréger tous les coûts (de l'ensemble de données (de formation)) et ensuite prendre dérivé et effectuer la mise à jour pertinente aux paramètres de poids dans le sgd_step (..), et pour des raisons évidentes avec ma mise en œuvre actuelle, je reçois cette erreur: theano.gradient.DisconnectedInputError: méthode de grad a été demandé de calculer le gradient par rapport à une variable qui ne fait pas partie du graphe de calcul du coût, ou est utilisée uniquement par un opérateur non dérivable: W_xh. Maintenant, je ne comprends pas comment faire 'coût' une partie du graphique de calcul (comme dans mon cas quand je dois attendre qu'il soit agrégé) ou y at-il une meilleure/élégante façon d'atteindre la même chose?

Merci.

Répondre

0

Il s'avère que l'on ne peut pas amener la variable symbolique dans le graphique Theano s'ils ne font pas partie du graphe de calcul. Par conséquent, je dois changer la manière de passer des données au train_model (..); en passant les données d'entraînement complètes au lieu d'un exemple individuel, résolvez le problème.