2015-12-26 2 views
0

Я играю с ванильным Rnn's, тренируюсь с градиентным спусками (без пакетной версии), и у меня возникает проблема с вычислением градиента для (скалярной) стоимости; вот соответствующая часть моего кода:Проблема с вычислительным градиентом для Rnn в 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) 

По некоторым причинам я не хочу, чтобы передать полные данные (подготовка) к train_model (..), вместо этого я хочу передать отдельные примеры в то время. Теперь проблема в том, что каждый вызов train_model (..) возвращает мне стоимость (отрицательный лог-правдоподобие) этого конкретного примера, а затем я должен суммировать всю стоимость (полного набора данных обучения), а затем принять производным и выполнить соответствующее обновление весовых параметров в sgd_step (..), и по очевидным причинам с моей текущей реализацией я получаю эту ошибку: theano.gradient.DisconnectedInputError: grad method было предложено вычислить градиент по отношению к переменная, которая не является частью вычислительного графика стоимости или используется только недифференцируемым оператором: W_xh. Теперь я не понимаю, как сделать «« »частью вычислительного графика (как в моем случае, когда мне нужно дождаться его агрегирования), или есть лучший/элегантный способ добиться того же самого?

Спасибо.

ответ

0

Получается, что символьная переменная не может быть переведена на диаграмму Аяно, если они не являются частью вычислительного графа. Поэтому мне нужно изменить способ передачи данных в train_model (..); передача данных обучения, а не отдельных примеров, устраняет проблему.