天天看點

tensorflow-LSTM講解blog

http://colah.github.io/posts/2015-08-Understanding-LSTMs/​

一些參數:

max_grad_norm = 5       # 用于控制梯度膨脹,如果梯度向量的L2模超過max_grad_norm,則等比例縮小
num_layers = 2          # lstm層數
num_steps = 20          # 單個資料中,序列的長度。
# 對于RNNCell,還有兩個類屬性比較重要:
    state_size # 隐層的大小
    output_size # 輸出的大小
input_size # 表示輸入資料單個序列單個時間次元上固有的長度      

比如我們通常是将一個batch送入模型計算,設輸入資料的形狀為(batch_size, input_size),那麼計算時得到的隐層狀态就是(batch_size, state_size),輸出就是(batch_size, output_size)。

從源碼中可以看到,在LSTM單元中,有2個狀态值,分别是c和h。其中h在作為目前時間段的輸出的同時,也是下一時間段的輸入的一部分。

當state_is_tuple=True的時候,state是元組形式,state=(c,h)。如果是False,那麼state是一個由c和h拼接起來的張量,state=tf.concat(1,[c,h])。

在rnn中使用dropout的方法和cnn不同。在rnn中進行dropout時,對于rnn的部分不進行dropout,也就是說從t-1時候的狀态傳遞到t時刻進行計算時,這個中間不進行memory的dropout;僅在同一個t時刻中,多層cell之間傳遞資訊的時候進行dropout。在使用tf.nn.rnn_cell.DropoutWrapper時,同樣有一些參數,例如input_keep_prob,output_keep_prob等,分别控制輸入和輸出的dropout機率。(同層cell不進行dropout)

lstm上一時間段的狀态會自動參與到目前時間段的輸出和狀态的計算當中。

TensorFlow提供了一個tf.nn.dynamic_rnn函數,使用該函數就相當于調用了n次call函數。

# inputs: shape = (batch_size, time_steps, input_size)

# cell: RNNCell

# initial_state: shape = (batch_size, cell.state_size)。初始狀态。一般可以取零矩陣

outputs, state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state)
'''
此時,得到的outputs就是time_steps步裡所有的輸出。
它的形狀為(batch_size, time_steps, cell.output_size)。
state是最後一步的隐狀态,它的形狀為(batch_size, cell.state_size)。
'''      
# 源碼中BasicRNNCell的call函數實作:

    def call(self, inputs, state):
       """Most basic RNN: output = new_state = act(W * input + U * state + B)."""
       output = self._activation(_linear([inputs, state], self._num_units, True))
       return      
self._forget_bias) + sigmoid(i) * self._activation(j))

new_h = self._activation(new_c) * sigmoid(o)


if self._state_is_tuple:
 new_state = LSTMStateTuple(new_c, new_h)

else:
 new_state = array_ops.concat([new_c, new_h], 1)

return      

繼續閱讀