这是一个使用深度学习处理文本序列的示例。
我们已经尝试使用密集连接层处理过IMDB数据集,回顾请参考Imdb影评分类。
本文使用循环神经网络来处理文本序列。
文本可以理解为单词序列或字符序列。
现在已经广泛使用的自然语言理解、文档分类、自动问答等都可以看作是深度学习在文本识别领域的应用。
本文介绍的深度学习模型并没有像人类一样真正地理解了文本,而只是映射出书面语言的统计结构,但这也足以解决许多简单的文本处理任务。
深度学习用于自然语言处理是将模式识别应用于单词、句子和段落,这与计算机视觉是将模式识别应用于像素大致相同。
识别文本的关键一步是文本向量化,有两种方法可以实现,一种是one-hot编码,另一种是使用密集的词向量(词嵌入)。
one-hot编码得到的向量是二进制、稀疏的、维度很高(维度等于单词个数)。而词嵌入是从数据中学习得到的,它是低维的浮点数向量。
在keras中可以使用Embedding层学习词嵌入。
循环神经网络与之前使用的密集连接网络和卷积神经网络不同:
如下图所示,展示了RNN的一种形式:
keras内置了循环层,如SimpleRNN,它接收形状为(batch_size, timesteps, input_features)的输入可以在两种模式下运行:
直接上代码:
# -*- coding: utf-8 -*-
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
from keras.datasets import imdb
from keras.preprocessing import sequence
max_features = 10000
maxlen = 500
batch_size = 32
print('load data...')
path = r'E:\practice\tf2\imdb\imdb.npz'
(input_train, y_train), (input_test, y_test) = imdb.load_data(path, num_words = max_features)
print('pad sequences (smaples x time)')
input_train = sequence.pad_sequences(input_train, maxlen = maxlen)
input_test = sequence.pad_sequences(input_test, maxlen = maxlen)
print('input_train shape: ', input_train.shape)
print('input_test shape: ', input_test.shape)
# 训练网络
from keras import models
from keras import layers
from keras.layers import Dense
from keras.layers import Embedding
from keras.layers import SimpleRNN
# 使用一个Embedding层和一个SimpleRNN层
model = models.Sequential()
model.add(Embedding(max_features, 32))
model.add(SimpleRNN(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)
# 绘图
import matplotlib.pyplot as plt
acc = history.history['acc']
val_acc = history.history['val_acc']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
plt.plot(epochs, acc, 'bo', label = 'Training acc')
plt.plot(epochs, val_acc, 'b', label = 'Balidation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()
plt.plot(epochs, loss, 'bo', label = 'Training loss')
plt.plot(epochs, val_loss, 'b', label = 'Validation loss')
plt.title("Training and validation loss")
plt.legend()
plt.show()
结果如下图:
SimpleRNN并非keras中唯一可用的循环层,还有LSTM和GRU。
SimpleRNN的问题在于它并不能记住许多时间步之前的信息,这是由于梯度消失问题引起的。
LSTM(long short-term memory)长短期记忆是SimpleRNN的一种变体,它增加了一种携带信息跨越多个时间步的方法。
它能够保存信息以便以后使用,从而防止较早期的信号在处理过程中逐渐消失。
使用LSTM训练IMDB数据的方法与使用SimpleRNN类似,只需要在训练时修改使用SimpleRNN的地方如下:
from keras.layers import LSTM
# 只需要指定LSTM层的输出维度,其他所有参数都使用Keras的默认值
model.add(LSTM(32))
训练结果绘图如下所示:
总体而言,使用RNN训练的处理IMDB影评分类的神经网络,在最终精确度上并不比密集连接层高多少,可能的原因如下:
《Python深度学习》