Keras深度学习实战——使用长短时记忆网络构建情感分析模型
0. 前言
我们已经学习了如何使用循环神经网络 (Recurrent neural networks, RNN) 构建情感分析模型,为了将循环神经网络与长短时记忆网络 (
Long Short Term Memory
,
LSTM
) 的性能进行对比,同时也为了加深对
LSTM
的了解,在节中,我们将使用
LSTM
来完成同样的情感分类任务。
1. 构建 LSTM 模型进行情感分类
1.1 数据集分析
接下来,我们将实现
LSTM
构建情感分析模型,所用的数据集与在《从零开始构建单词向量》一节中使用的数据集相同,即航空公司
Twitter
数据集,模型的目标是预测用户对于航空公司的评价属于正面、负面或者中立。
1.2 模型构建
(1) 据加载与预处理。本节所用数据加载与预处理过程与使用 RNN 进行情感分类任务中使用的方法完全相同:
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.models import Sequential
from keras.layers.embeddings import Embedding
from sklearn.model_selection import train_test_split
import numpy as np
import nltk
from nltk.corpus import stopwords
import re
import pandas as pd
data=pd.read_csv('archive/Tweets.csv')print(data.head())
stop = nltk.corpus.stopwords.words('english')defpreprocess(text):
text=text.lower()
text=re.sub('[^0-9a-zA-Z]+',' ',text)
words = text.split()
words2=[w for w in words if(w notin stop)]#words3=[ps.stem(w) for w in words]
words4=' '.join(words2)return(words4)
data['text']= data['text'].apply(preprocess)from collections import Counter
counts = Counter()for i,review inenumerate(data['text']):
counts.update(review.split())
words =sorted(counts, key=counts.get, reverse=True)
nb_chars =len(words)print(nb_chars)
word_to_int ={word: i for i, word inenumerate(words,1)}
int_to_word ={i: word for i, word inenumerate(words,1)}
mapped_reviews =[]for review in data['text']:
mapped_reviews.append([word_to_int[word]for word in review.split()])print('Original text:',data.loc[0]['text'])print('Mapped text:',mapped_reviews[0])
length_sent =[]for i inrange(len(mapped_reviews)):
length_sent.append(len(mapped_reviews[i]))
sequence_length =max(length_sent)from keras.preprocessing.sequence import pad_sequences
x = pad_sequences(maxlen=sequence_length, sequences=mapped_reviews, padding="post", value=0)
y = data['airline_sentiment'].values
y = np.array(pd.get_dummies(y))
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
(2) 定义模型。嵌入层的输入是数据集中不同单词的总数,使用
output_dim
参数指定每个单词需要转换的预期维度,此外,我们还需要指定输入句子的长度
input_length
:
embedding_vecor_length=32
max_review_length=26
model = Sequential()
model.add(Embedding(input_dim=nb_chars+1, output_dim=32, input_length =26))
model.add(LSTM(40, return_sequences=False))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])print(model.summary())
该模型的简要结构信息如下:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param # =================================================================
embedding (Embedding)(None, 26, 32)477920
_________________________________________________________________
lstm (LSTM)(None, 40)11680
_________________________________________________________________
dense (Dense)(None, 3)123=================================================================
Total params: 489,723
Trainable params: 489,723
Non-trainable params: 0
_________________________________________________________________
可以看到嵌入层和最后一层中的参数与使用 RNN 进行情感分类所用的模型参数相同,仅
LSTM
层具有不同数量的参数。
(3) 获取
LSTM
层中的
11680
个参数:
W = model.layers[1].get_weights()[0]
U = model.layers[1].get_weights()[1]
b = model.layers[1].get_weights()[2]print(W.shape,U.shape,b.shape)
输出的参数形状如下所示:
(32, 160)(40, 160)(160,)
因此,
LSTM
权重的总数为
(
32
∗
160
)
+
(
40
∗
160
)
+
160
=
11680
(32 * 160)+(40 * 160)+ 160 = 11680
(32∗160)+(40∗160)+160=11680。
W
表示将输入连接到四个
LSTM
单元
(i, f, c, o)
的权重,
U
表示网络中间状态间的连接,
b
表示每个单元中的偏置。
(4) 输入、遗忘门、输入门和输出门的权重可以按以下方式获得:
units =40
W_i = W[:,:units]
W_f = W[:, units: units *2]
W_c = W[:, units *2: units *3]
W_o = W[:, units *3:]
U_i = U[:,:units]
U_f = U[:, units: units *2]
U_c = U[:, units *2: units *3]
U_o = U[:, units *3:]
b_i = b[:units]
b_f = b[units: units *2]
b_c = b[units *2: units *3]
b_o = b[units *3:]
(5) 拟合模型编译后的
LSTM
模型:
history = model.fit(x_train, y_train,
validation_data=(x_test, y_test),
epochs=20,
batch_size=64)
模型在训练和测试数据集中随着训练时间的增加,损失值和准确率的变化如下:
使用
LSTM
层时的预测准确率约为
80%
,比使用
simpleRNN
层时的预测精度更好一些。接下来,我们可以通过使用堆叠多个
LSTM
层来尝试进一步改善分类结果。
2. 构建多层 LSTM 进行情感分类
在上一节中,我们利用
Keras
中构建了
LSTM
模型实现了情感分类。在本节中,我们将堆叠多个
LSTM
层实现同样的情感分类任务。堆叠多个
LSTM
可能会捕获数据中的更多变化,从而有可能获得更高的准确性。
(1) 堆叠多层
LSTM
的实现如下,代码中需要将第
1
个
LSTM
层中的
return_sequences
参数值更改为
true
,这样可以确保第一个
LSTM
返回一个输出序列,然后将其传递给另一个
LSTM
层作为输入:
embedding_vecor_length=32
max_review_length=26
model = Sequential()
model.add(Embedding(input_dim=nb_chars+1, output_dim=32, input_length =26))
model.add(LSTM(40, return_sequences=True))
model.add(LSTM(40, return_sequences=False))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])print(model.summary())
模型架构的简要信息输入如下:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param # =================================================================
embedding (Embedding)(None, 26, 32)477920
_________________________________________________________________
lstm (LSTM)(None, 26, 40)11680
_________________________________________________________________
lstm_1 (LSTM)(None, 40)12960
_________________________________________________________________
dense (Dense)(None, 3)123=================================================================
Total params: 502,683
Trainable params: 502,683
Non-trainable params: 0
_________________________________________________________________
在此体系结构中,使用了
2
个叠加的
LSTM
层,第一个
LSTM
每个时间戳输出
40
个值,因此输出形状为
(None, 26, 40)
,其中
None
表示
batch_size
,
26
表示时间戳数,
40
表示
LSTM
中神经元数,也就是每个时间戳输出值的维度。第二个
LSTM
中的参数数量如下所示:
W = model.layers[2].get_weights()[0]
U = model.layers[2].get_weights()[1]
b = model.layers[2].get_weights()[2]print(W.shape,U.shape,b.shape)
得到的参数形状输出如下,从输出中可以看到,共有
12960
个参数:
(40, 160)(40, 160)(160,)
(2) 训练模型,如下所示:
history = model.fit(x_train, y_train,
validation_data=(x_test, y_test),
epochs=20,
batch_size=64)
随着训练时间的增加,在训练和测试数据集,损失值和准确率的变化如下:
如上图所示,训练后的多层
LSTM
模型的测试准确率约为
78%
。但是,可以看到模型出现了严重的过拟合,在使用更多的数据后,多层
LSTM
比单层
LSTM
能够捕获更多信息。
相关链接
Keras深度学习实战(1)——神经网络基础与模型训练过程详解
Keras深度学习实战(2)——使用Keras构建神经网络
Keras深度学习实战(7)——卷积神经网络详解与实现
Keras深度学习实战(24)——从零开始构建单词向量
Keras深度学习实战(25)——使用skip-gram和CBOW模型构建单词向量
Keras深度学习实战(26)——文档向量详解
Keras深度学习实战(27)——循环神经详解与实现
Keras深度学习实战(28)——利用单词向量构建情感分析模型
Keras深度学习实战(29)——长短时记忆网络详解与实现
Keras深度学习实战——使用循环神经网络构建情感分析模型
版权归原作者 盼小辉丶 所有, 如有侵权,请联系我们删除。