长短期记忆人工神经网络是一种时间递归神经网络,是为了解决长期以来问题而专门设计出来的,所有的RNN都具有一种重复神经网络模块的链式形式。在标准RNN中,这个重复的结构模块只有一个非常简单的结构,例如一个tanh层。
简介长短期记忆人工神经网络(Long-Short Term Memory,LSTM)论文首次发表于1997年。由于独特的设计结构,LSTM适合于处理和预测时间序列中间隔和延迟非常长的重要事件。
LSTM的表现通常比时间递归神经网络及隐马尔科夫模型(HMM)更好,比如用在不分段连续手写识别上。2009年,用LSTM构建的人工神经网络模型赢得过ICDAR手写识别比赛冠军。LSTM还普遍用于自主语音识别,2013年运用TIMIT自然演讲数据库达成17.7%错误率的纪录。作为非线性模型,LSTM可作为复杂的非线性单元用于构造更大型深度神经网络。1
结构LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为它可以记忆不定时间长度的数值,区块中有一个gate能够决定input是否重要到能被记住及能不能被输出output。
右图底下是四个S函数单元,最左边函数依情况可能成为区块的input,右边三个会经过gate决定input是否能传入区块,左边第二个为input gate,如果这里产出近似于零,将把这里的值挡住,不会进到下一层。左边第三个是forget gate,当这产生值近似于零,将把区块里记住的值忘掉。第四个也就是最右边的input为output gate,他可以决定在区块记忆中的input是否能输出 。
LSTM有很多个版本,其中一个重要的版本是GRU(Gated Recurrent Unit),根据谷歌的测试表明,LSTM中最重要的是Forget gate,其次是Input gate,最次是Output gate。2
训练方法为了最小化训练误差,梯度下降法(Gradient descent)如:应用时序性倒传递算法,可用来依据错误修改每次的权重。梯度下降法在递回神经网络(RNN)中主要的问题初次在1991年发现,就是误差梯度随着事件间的时间长度成指数般的消失。当设置了LSTM 区块时,误差也随着倒回计算,从output影响回input阶段的每一个gate,直到这个数值被过滤掉。因此正常的倒传递类神经是一个有效训练LSTM区块记住长时间数值的方法。
搭建实例以下代码展示了在tensorflow中实现使用LSTM结构的循环神经网络的前向传播过程。
# 定义一个LSTM结构,LSTM中使用的变量也会在该函数中自动被声明lstm=rnn_cell.BasicLSTMCell(lstm_hidden_size) # 将LSTM中的状态初始化为全0数组,BasicLSTMCell提供了zero_state函数来生成全零的初始状态state=lstm.zero_state(batch_size,tf.float32) # 定义损失函数loss=0.0# 理论上循环神经网络可以处理任意长度的序列,但是在训练时为了避免梯度消散的问题,会规定一个最大的序列长度# 下面代码使用参数num_steps来表示这个长度for i in range(num_steps): # 在第一个时刻声明LSTM结构中使用的变量,在之后的时刻都需要复用之前定义好的变量 if i>0: tf.get_variable_scope().reuse_variables() # 每一步处理时间序列中的一个时刻。将当前输入(current_input)和前一时刻状态(state)传入定义的LSTM结构可以得到 # 当前LSTM结构的输出lstm_output和更新后的状态state lstm_output,state=lstm(current_input,state) # 将当前时刻LSTM结构的输出传入一个全连接层得到最后的输出 final_output=fully_connected(lstm_output) # 计算当前时刻输出的损失 loss+=calc_loss(final_output,expected_output)LSTM网络的变体:双向循环神经网络和深层循环神经网络
双向循环神经网络的主体结构是由两个单向循环神经网络组成的。在每一个时刻t,输入会同时提供给这两个方向相反的循环神经网络,而输出则是由这两个单向循环神经网络共同决定。其结构如下图一所示:
六个权值分别对应:输入到向前和向后隐含层(w1, w3),隐含层到隐含层自己(w2, w5),向前和向后隐含层到输出层(w4, w6)。值得注意的是:向前和向后隐含层之间没有信息流,这保证了展开图是非循环的。
深层循环神经网络:为了增强模型的表达能力,该网络在每一个时刻上将循环体结构复制多次,每一层的循环体中参数是一致的,而不同层中的参数可以不同。其结构如下图二所示:
tensorflow中提供了MultiRNNCell类来实现深层循环神经网络的前向传播过程。代码如下:
# 定义一个基本的LSTM结构作为循环体的基础结构。深层循环神经网络也支持使用其他的循环体结构lstm=rnn_cell.BasicLSTMCell(lstm_size) # 通过MultiRNNCell类实现深层循环神经网络中每一个时刻的前向传播过程。其中number_of_layers表示有多少层。stacked_lstm=rnn_cell.MultiRNNCell([lstm]*number_of_layers) # 通过zero_state函数来获取初始状态state=stacked_lstm.zero_state(batch_size,tf.float32) # 定义损失函数loss=0.0for i in range(num_steps): if i>0: tf.get_variable_scope().reuse_variables() stacked_lstm_output,state=stacked_lstm(current_input,state) # 将当前时刻LSTM结构的输出传入一个全连接层得到最后的输出 final_output=fully_connected(stacked_lstm_output) # 计算当前时刻输出的损失 loss+=calc_loss(final_output,expected_output)本词条内容贡献者为:
王沛 - 副教授、副研究员 - 中国科学院工程热物理研究所