RNN-LSTM
- 1.RNN
- 2.LSTM
- 3. tensorflow 中的RNN-LSTM
- 3.1 tf.nn.rnn_cell.BasicRNNCell()
- 3.2 tf.nn.rnn_cell.BasicLSTMCell()
- 3.3 tf.nn.dynamic_rnn()--多步執行循環神經網絡
1.RNN
RNN-Recurrent Neural Network-循環神經網絡
RNN用來處理序列數據。多層感知機MLP層間節點全聯接,層內節點并無鏈接。 RNN層內節點的之間存在連接關系,用來反映上一層隱層狀態作為下一層的輸入,將直接輸給中間隱藏層。
RNN網絡模塊圖如下所示:
其中: xtx_txt? 網絡t時刻輸入, hth_tht? 網絡t時刻的輸出。 如果將RNN按時間序列展開,可以得到以下鏈式結構:
用簡單的權重矩陣建模rnn, 輸入-狀態-輸出之間存在以下的關系:[oto_tot?即上文的hth_tht?]
st=f(U?xt+W?st?1)s_{t} = f(U\cdot x_t + W\cdot s_{t-1})st?=f(U?xt?+W?st?1?)
ot=g(V?st)o_t = g(V\cdot s_t)ot?=g(V?st?)
st?1s_{t-1}st?1?能夠建模歷史信息對當前輸出的影響。原始RNN隨著時間的推移,歷史狀態對當前輸出的影響減弱。但是很多任務需要長時依賴關系。LSTM營運而生。
2.LSTM
LSTM-Long Short-Term Memory 可以學習長時依賴信息,LSTM網絡模塊圖如下所示:
狀態傳遞機制決定了上一時刻狀態信息的保留量,以及新輸入信息的增量。LSTM包含三個關鍵的門用于實現這一傳遞機制。
**遺忘門:**上一時刻輸出和這一個時刻輸入決定上一時刻的狀態保留百分比ftf_tft?。【sigmoid輸出0-1 之間的一個數】
輸入門:C~t\tilde{C}_tC~t?為新信息候選向量, iti_tit? 決定了多少新信息候選向量能夠通過。隨后更新狀態信息:
輸出門: 當前狀態CtC_tCt? 和 ht?1h_{t-1}ht?1? 以及xtx_txt? 共同決定當前時刻輸出信息hth_tht?
參考資料:https://colah.github.io/posts/2015-08-Understanding-LSTMs/
3. tensorflow 中的RNN-LSTM
RNNCell是TensorFlow中實現RNN的基本單元,每個RNNCell都有一個call方法,使用方式是:(output, next_state) = call(input, state)。RNNCell是一個抽象類,實際使用時候,用它的兩個子類BasicRNNCell [RNN的基礎類] 和BasicLSTMCell [LSTM的基礎類]。
3.1 tf.nn.rnn_cell.BasicRNNCell()
RNNCell,具有兩個比較重要類屬性:state_size–決定隱層的大小,output_size決定輸出大小
例如將(batch_size, input_size)數據輸入RNN,得到的隱層狀態就是(batch_size, state_size),輸出是(batch_size, output_size)。
import tensorflow as tf
import numpy as np
cell = tf.nn.rnn_cell.BasicRNNCell(num_units=128) # state_size = 128
print(cell.state_size) # 128inputs = tf.placeholder(np.float32, shape=(32, 100)) # batch_size=32
h0 = cell.zero_state(32, np.float32) # 全零狀態(batch_size, state_size)
output, h1 = cell.call(inputs, h0)
print(h1.shape) # (32, 128)
、
3.2 tf.nn.rnn_cell.BasicLSTMCell()
tf.nn.rnn_cell.BasicLSTMCell(num_units, # int類型,隱層輸出大小forget_bias=1.0, # float類型, 遺忘門偏置state_is_tuple=True, # 回的狀態是h_t和c_t的2元tuple LSTM可以看做有兩個隱狀態h和cactivation=None, # 內部狀態的激活函數。默認為tanhreuse=None,name=None,dtype=None)
3.3 tf.nn.dynamic_rnn()–多步執行循環神經網絡
基礎的RNNCell使用它的call函數進行運算時,只是在序列時間上前進了一步。例如使用(x1,h0)得到h1,(x2, h1)得到h2等。如果序列長度為10,需調用10次call函數,比較麻煩。
TensorFlow提供了一個tf.nn.dynamic_rnn函數,該函數可實現n次調用call函數。即通過{h0,x1, x2, …., xn}得{h1,h2…,hn}。
輸入數據格式為(batch_size, time_steps, input_size),其中time_steps表示序列長度,input_size表示單個序列元素的特征長度。
tf.nn.dynamic_rnn(cell, inputs, sequence_length=None, initial_state=None, dtype=None,parallel_iterations=None, swap_memory=False, time_major=False, scope=None
)
對于一個定義的的cell ,多次執行該cell 的demo 為:
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)。
動態調整sequence_length tf.nn.dynamic_rnn 詳解
參考資料:
tensorflow學習之BasicLSTMCell詳解
TensorFlow中RNN實現的正確打開方式