2016-03-29 2 views
0
class RNNSLU(object): 
''' elman neural net model ''' 
def __init__(self, nh, nc, ne, de, cs): 
    ''' 
    nh :: dimension of the hidden layer 
    nc :: number of classes 
    ne :: number of word embeddings in the vocabulary 
    de :: dimension of the word embeddings 
    cs :: word window context size 
    ''' 
    # parameters of the model 
    self.emb = theano.shared(name='embeddings', 
          value=0.2 * numpy.random.uniform(-1.0, 1.0, 
          (ne+1, de)) 
          # add one for padding at the end 
          .astype(theano.config.floatX)) 
    self.wx = theano.shared(name='wx', 
          value=0.2 * numpy.random.uniform(-1.0, 1.0, 
          (de * cs, nh)) 
          .astype(theano.config.floatX)) 
    self.wh = theano.shared(name='wh', 
          value=0.2 * numpy.random.uniform(-1.0, 1.0, 
          (nh, nh)) 
          .astype(theano.config.floatX)) 
    self.w = theano.shared(name='w', 
          value=0.2 * numpy.random.uniform(-1.0, 1.0, 
          (nh, nc)) 
          .astype(theano.config.floatX)) 
    self.bh = theano.shared(name='bh', 
          value=numpy.zeros(nh, 
          dtype=theano.config.floatX)) 
    self.b = theano.shared(name='b', 
          value=numpy.zeros(nc, 
          dtype=theano.config.floatX)) 
    self.h0 = theano.shared(name='h0', 
          value=numpy.zeros(nh, 
          dtype=theano.config.floatX)) 

    # bundle 
    self.params = [self.emb, self.wx, self.wh, self.w, self.bh, self.b, self.h0] 



def recurrence(x_t, h_tm1): 
     h_t = T.nnet.sigmoid(T.dot(x_t, self.wx) 
          + T.dot(h_tm1, self.wh) + self.bh) 
     s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b) 
     return [h_t, s_t] 

[h, s], = theano.scan(fn=recurrence, 
          sequences=x, 
          outputs_info=[self.h0, None], 
          n_steps=x.shape[0]) 

Я выполняю это Theano учебник о RNN. (http://deeplearning.net/tutorial/rnnslu.html) Но у меня есть два вопроса по этому поводу. Первый. В этом учебнике, рекуррентной функции, как это:параметр RNN в Theano учебнике

def recurrence(x_t, h_tm1): h_t = T.nnet.sigmoid(T.dot(x_t, self.wx) + T.dot(h_tm1, self.wh) + self.bh) s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b) return [h_t, s_t]

Я wounder почему не плюс h0 в h_t? (т. е. h_t = T.nnet.sigmoid(T.dot(x_t, self.wx) + T.dot(h_tm1, self.wh) + self.bh + self.h0))

Во-вторых, почему outputs_info=[self.h0, None]? Я знаю, что output_info - это результат инициализации. Так что я думаю, что outputs_info=[self.bh+self.h0, T.nnet.softmax(T.dot(self.bh+self.h0, self.w_h2y) + self.b_h2y)]

ответ

1
def recurrence(x_t, h_tm1): 
     h_t = T.nnet.sigmoid(T.dot(x_t, self.wx) 
          + T.dot(h_tm1, self.wh) + self.bh) 
     s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b) 
     return [h_t, s_t] 

Итак, сначала вы спросите, почему мы не используем h0 в функции повторения. Проведем разбивку по этой части,

h_t = T.nnet.sigmoid(T.dot(x_t, self.wx)+ T.dot(h_tm1, self.wh) + self.bh) 

Что мы ожидаем, это три условия.

  1. Первый член входной слой умножается на весовой матрицы T.dot(x_t, self.wx).

  2. Второй термин - это скрытый слой, смешанный с другой взвешивающей матрицей (это то, что делает ее повторяющейся) T.dot(h_tm1, self.wh). Обратите внимание, что у вас должна быть взвешивающая матрица, вы предложили добавить self.h0 в качестве предубеждения в основном.

  3. Третий термин - это смещение скрытого слоя, self.bh.

Теперь, после каждой итерации мы хотим, чтобы следить за активации скрытого слоя, содержащихся в self.h0. Однако self.h0 предназначен для активации активации CURRENT, и нам нужны предыдущие активации.

[h, s], _ = theano.scan(fn=recurrence, 
          sequences=x, 
          outputs_info=[self.h0, None], 
          n_steps=x.shape[0]) 

Итак, снова просмотрите функцию сканирования. Вы правы, что outputs_info=[self.h0, None] инициализирует значения, но значения также связаны с выходами. Есть два выхода от recurrence(), а именно [h_t, s_t].

Итак, что делает output_info, так это то, что после каждой итерации значение self.h0 перезаписывается значением h_t (первое возвращаемое значение). Второй элемент outputs_info является None, потому что мы не экономим или инициализировать значение s_t в любом месте (второй аргумент outputs_info связан с возвращенными значениями функции повторения таким образом.)

В следующей итерации первый аргумент outputs_info используется снова как вход, так что h_tm1 - это то же значение, что и self.h0. Но, поскольку мы должны иметь аргумент для h_tm, мы должны инициализировать это значение. Поскольку нам не нужно инициализировать второй аргумент в outputs_info, мы оставляем второй член как None.

Предоставлено, функция theano.scan() очень запутанная время от времени, и я тоже новичок в ней. Но это то, что я понял из этого же учебника.

+0

Благодарим вас за ответ.Это так полезно, я думаю, что понимаю, что вы имеете в виду, большое вам спасибо –

Смежные вопросы