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