本文從tensorflow的代碼層面理解LSTM。
看本文之前,需要先看我的這兩篇博客
https://www.cnblogs.com/yanshw/p/10495745.html 談到網絡結構
https://www.cnblogs.com/yanshw/p/10515436.html 談到多隱層神經網絡
回憶一下LSTM網絡
輸出
tensorflow 用 tf.nn.dynamic_rnn構建LSTM的輸出
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_number,forget_bias = 1.0) # 初始化s init_state = lstm_cell.zero_state(batch_size,dtype=tf.float32) outputs,states = tf.nn.dynamic_rnn(lstm_cell,X_in,initial_state=init_state,time_major=False)
output,states 都是隱層的輸出,注意只是隱層h,還沒到o,o=vh+c(c是bias,不同於states的c,這是記憶單元)
output 是以三維矩陣形式記錄了 所有樣本所有時刻所有隱層的輸出,shape 為 [batch_size, timestep_size, hidden_size]
states 是所有樣本最后時刻所有隱層的 c 和 h,c 是記憶單元, states的shape 為 [2, batch_size, hidden_size] ,2表示 c 和 h
故 states[1] == outputs[:,-1,:] == h
圖形表示如下
多隱層
1. MultiRNNCell 構建多隱層LSTM,輸出同 tf.nn,dynamic_rnn
2. 多隱層 h0 的shape
3. 多隱層 的輸出
# encoding:utf-8 __author__ = 'HP' import tensorflow as tf # 時序為1 batch_size=10 depth=128 # 特征數 inputs=tf.Variable(tf.random_normal([batch_size,depth])) # # 多隱層的h0 previous_state0=(tf.random_normal([batch_size,100]),tf.random_normal([batch_size,100])) previous_state1=(tf.random_normal([batch_size,200]),tf.random_normal([batch_size,200])) previous_state2=(tf.random_normal([batch_size,300]),tf.random_normal([batch_size,300])) num_units=[100,200,300] # 隱層神經元個數 print(inputs) cells=[tf.nn.rnn_cell.BasicLSTMCell(num_unit) for num_unit in num_units] mul_cells=tf.nn.rnn_cell.MultiRNNCell(cells) # MultiRNNCell 直接輸出 outputs,states=mul_cells(inputs,(previous_state0,previous_state1,previous_state2)) print(outputs.shape) #(10, 300) print(states[0]) #第一層LSTM print(states[1]) #第二層LSTM print(states[2]) ##第三層LSTM print(states[0].h.shape) #第一層LSTM的h狀態,(10, 100) print(states[0].c.shape) #第一層LSTM的c狀態,(10, 100) print(states[1].h.shape) #第二層LSTM的h狀態,(10, 200)
網絡構建
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=hidden_size, forget_bias=1.0, state_is_tuple=True) mlstm_cell = rnn.MultiRNNCell([clstm() for i in range(layer_num)], state_is_tuple=True) outputs, state = tf.nn.dynamic_rnn(mlstm_cell, inputs=X, initial_state=init_state, time_major=False) vs mul_cells=tf.nn.rnn_cell.MultiRNNCell(cells) outputs,states=mul_cells(inputs,(previous_state0,previous_state1,previous_state2))
h0 shape
之前講到h0的shape是 [batch_size, hidden_size],只是針對單隱層的
多隱層應該是 [batch_size, hidden1_size] + [batch_size, hidden2_size] + [batch_size, hidden3_size] + ...
上例中用 MultiRNNCell 構建LSTM, 需要同時定義 c0 和 h0,且二者shape相同,故
previous_state0=(tf.random_normal([batch_size,100]),tf.random_normal([batch_size,100])) previous_state1=(tf.random_normal([batch_size,200]),tf.random_normal([batch_size,200])) previous_state2=(tf.random_normal([batch_size,300]),tf.random_normal([batch_size,300]))
圖形表示
多隱層輸出
單隱層輸出本文最開頭已經講了,多隱層會稍有不同
output 仍然是 [batch_size, timestep_size, hidden_size]
而 states 是 [n_layer, 2, batch_size, hidden_size]
print(outputs.shape) #(10, 300) print(states[0]) #第一層LSTM print(states[1]) #第二層LSTM print(states[2]) ##第三層LSTM print(states[0].h.shape) #第一層LSTM的h狀態,(10, 100) print(states[0].c.shape) #第一層LSTM的c狀態,(10, 100) print(states[1].h.shape) #第二層LSTM的h狀態,(10, 200)
圖形表示
故 state[-1][1] == outputs[:, -1, :] == h