Keras深度学习实战——使用长短时记忆网络构建情感分析模型
Posted 盼小辉丶
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Keras深度学习实战——使用长短时记忆网络构建情感分析模型相关的知识,希望对你有一定的参考价值。
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')
def preprocess(text):
text=text.lower()
text=re.sub('[^0-9a-zA-Z]+',' ',text)
words = text.split()
words2=[w for w in words if (w not in 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 in enumerate(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 in enumerate(words, 1)
int_to_word = i: word for i, word in enumerate(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 in range(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深度学习实战——使用循环神经网络构建情感分析模型
以上是关于Keras深度学习实战——使用长短时记忆网络构建情感分析模型的主要内容,如果未能解决你的问题,请参考以下文章
Keras深度学习实战(33)——基于LSTM的序列预测模型