提示:本文是在keras架构上使用LSTM层训练IMDB数据集,并展示对应的代码和结果
前言
经过上一节用keras中的SimpleRNN层实现了IMDB电影评论分类问题,这一节在上节的基础上,学习更为复杂点的LSTM和GRU层。
上一节博客的链接为:用keras的SimpleRNN实现IMDB电影评论分类问题
simpleRNN并不是Keras中唯一可用的循环层,还有另外两个:LSTM和GRU。由于simpleRNN太过于简化,没有实用价值。simpleRNN最大的问题是:在时刻t,理论上他应该能够记住许多时间步之前见过的信息,但实际上它是不可能学到这种长期依赖的。原因在于梯度消失问题,这一效应类似于在层数较多的非循环网络中观察道德效应:随着层数的增加,网络最终变得无法训练。
而LSTM和GRU都是解决这个问题而设计的。
LSTM介绍
先来看LSTM层。背后的长短期记忆(LSTM,long short-term memory)算法是由Hochreiter 和 Schmidhuber在1977年开发是二人研究梯度消失问题的重要成果。
LSTM是SimpleRNN层的一种变体,增加了一种携带信息跨越多个时间步的方法。原理可以简化为:序列中的信息可以在任意位置上跳上传送带然后被传送到更远的时间步,并在需要时原封不动地跳回来。
根据下图可以看到:信息对每个单元产生了以下的影响:它将与输入连接和循环连接进行运算,从而影响传递到下一个时间步的状态。从概念上看,携带数据流是一种调节下一个输出和下一个状态的方法。
LSTM架构伪代码
output_t = activation(dot(state_t, Uo) + dot(input_t, Wo) + dot(C_t, Vo) + bo)
i_t = activation(dot(state_t, Ui) + dot(input_t, Wi) + bi)
f_t = activation(dot(state_t, Uf) + dot(input_t, Wf) + bf)
k_t = activation(dot(state_t, Uk) + dot(input_t, Wk) + bk)
Keras中的一个LSTM例子
现在我们使用LSTM层来创建一个模型,然后在IMDB数据集上训练模型。
Keras具有很好的默认性,无需手动调参,模型就可以正常运行。
from keras.layers import LSTM
model = Sequential()
model.add(Embedding(max_features, 32))
model.add(LSTM(32))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(input_train, y_train,
epochs=10,
batch_size=128,
validation_split=0.2)
显示结果如下:
为什么此处的LSTM 不能表现得更好?
一个原因是你没有再度调节超参数,比如嵌入维度或 LSTM 输出维度。另一个原因可能是缺少正则化。
但主要原因在于,适用于评论分析全局的长期性结构(这正是 LSTM 所擅长的),对情感分析问题帮助不大。对于这样的基本问题,观察每条评论中出现了哪些词及其出现频率就可以很好地解决。这也正是第一个全连接方法的做法。但还有更加困难的自然语言处理问题,特别是问答和机器翻译,这时 LSTM 的优势就明显了。
参考:deep learning with python