本文从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