keras深度学习实战——使用长短时记忆网络构建情感分析模型(代码片段)

盼小辉丶 盼小辉丶     2022-10-23     450

关键词:

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 (32160)+(40160)+160=11680W 表示将输入连接到四个 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 的实现如下,代码中需要将第 1LSTM 层中的 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_size26 表示时间戳数,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深度学习实战(29)——长短时记忆网络详解与实现(代码片段)

Keras深度学习实战(29)——长短时记忆网络详解与实现0.前言1.RNN的局限性2.LSTM模型架构详解2.1LSTM架构2.2LSTM各组成部分与计算流程3.从零开始实现LSTM3.1LSTM模型实现3.2验证输出小结系列链接0.前言长短时记忆网络(LongShortTer... 查看详情

keras深度学习实战(33)——基于lstm的序列预测模型(代码片段)

Keras深度学习实战(33)——基于LSTM的序列预测模型0.前言1.序列学习任务1.1命名实体提取1.2文本摘要1.3机器翻译2.从输出网络返回输出序列2.1传统模型体系结构2.2返回每个时间戳的网络中间状态序列2.3使用双向LSTM网络小... 查看详情

keras深度学习实战——使用循环神经网络构建情感分析模型(代码片段)

Keras深度学习实战——使用循环神经网络构建情感分析模型0.前言1.使用循环神经网络构建情感分析模型1.1数据集分析1.2构建RNN模型进行情感分析相关链接0.前言在《循环神经详解与实现》一节中,我们已经了解循环神经网络(Recurr... 查看详情

keras深度学习实战(40)——音频生成(代码片段)

Keras深度学习实战(40)——音频生成0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.音频生成模型2.1数据集加载与预处理2.2模型构建与训练小结系列链接0.前言我们已经在《文本生成模型》一节中学习了如何利用深... 查看详情

keras深度学习实战——使用循环神经网络构建情感分析模型(代码片段)

Keras深度学习实战——使用循环神经网络构建情感分析模型0.前言1.使用循环神经网络构建情感分析模型1.1数据集分析1.2构建RNN模型进行情感分析相关链接0.前言在《循环神经详解与实现》一节中,我们已经了解循环神经网络(R... 查看详情

keras深度学习实战——使用keras构建神经网络(代码片段)

Keras深度学习实战(2)——使用Keras构建神经网络0前言1.Keras简介与安装2.Keras构建神经网络初体验3.训练香草神经网络3.1香草神经网络与MNIST数据集介绍3.2训练神经网络步骤回顾3.3使用Keras构建神经网络模型3.4关键步骤总结... 查看详情

keras深度学习实战(32)——基于lstm预测股价(代码片段)

Keras深度学习实战(32)——基于LSTM预测股价0.前言1.模型与数据集分析1.1数据集分析1.2模型分析2.基于长短时记忆网络LSTM预测股价2.1根据最近五天的股价预测股价2.2考虑最近五天的股价和新闻数据小结系列链接0.前言股价... 查看详情

keras深度学习实战——卷积神经网络详解与实现(代码片段)

Keras深度学习实战(7)——卷积神经网络详解与实现0.前言1.传统神经网络的缺陷1.1构建传统神经网络1.2传统神经网络的缺陷2.使用Python从零开始构建CNN2.1卷积神经网络的基本概念2.2卷积和池化相比全连接网络的优势3.使用... 查看详情

(转)零基础入门深度学习-长短时记忆网络(lstm)

...理大数据的时代,作为一个有理想有追求的程序员,不懂深度学习(DeepLearning)这个超热的技术,会不会感觉马上就out了?现在救命稻草来了,《零基础入门深度学习》系列文章旨在讲帮助爱编程的你从零基础达到入门级水平。... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型,其... 查看详情

keras深度学习实战(24)——从零开始构建单词向量(代码片段)

Keras深度学习实战(24)——从零开始构建单词向量0.前言1.单词向量1.1Word2Vec原理1.2构建单词向量1.3神经网络架构2.使用Keras从零开始构建单词向量3.测量单词向量之间的相似度小结系列链接0.前言在解决文本相关问题时,传统方法... 查看详情

keras深度学习实战——使用fasttext模型构建单词向量(代码片段)

Keras深度学习实战——使用fastText模型构建单词向量0.前言1.fastText算法模型2.模型与数据集分析2.1fastText模型分析2.2数据集分析3.使用Keras实现fastText生成单词向量相关链接0.前言fastText是另一种用于生成单词向量的神经网络模型࿰... 查看详情

keras深度学习实战(24)——从零开始构建单词向量(代码片段)

Keras深度学习实战(24)——从零开始构建单词向量0.前言1.单词向量1.1Word2Vec原理1.2构建单词向量1.3神经网络架构2.使用Keras从零开始构建单词向量3.测量单词向量之间的相似度小结系列链接0.前言在解决文本相关问题时ÿ... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如何构... 查看详情

keras深度学习实战(26)——文档向量详解(代码片段)

Keras深度学习实战(26)——文档向量详解0.前言1.文档向量基本概念2.神经网络模型与数据集分析2.1模型分析2.2数据集介绍3.利用Keras构建神经网络模型生成文档向量小结系列链接0.前言在《从零开始构建单词向量》一节中,我们... 查看详情

keras深度学习实战——使用glove模型构建单词向量(代码片段)

Keras深度学习实战——使用GloVe模型构建单词向量0.前言1.GloVe算法模型1.1模型目标1.2GloVe算法计算细节3.实现GloVe模型构建单词向量3.1数据集3.2模型实现相关链接0.前言在《使用fastText模型构建单词向量》一节中,我们学习了如... 查看详情

keras深度学习实战(28)——利用单词向量构建情感分析模型(代码片段)

Keras深度学习实战(28)——利用单词向量构建情感分析模型0.前言1.模型与数据集分析1.1模型分析1.2数据集分析2.情感分析模型2.1使用CBOW模型获取单词向量2.2构建并训练情感分析模型小结系列链接0.前言在获取单词向量的相关博... 查看详情

深度学习实战keras构建cnn神经网络完成cifar100类别分类(代码片段)

Keras构建CNN神经网络完成CIFAR100类别分类1.CIFAR100数据集介绍2.API使用3.步骤分析以及代码实现(缩减版LeNet5)4.完整代码1.CIFAR100数据集介绍这个数据集就像CIFAR-10,除了它有100个类,每个类包含600个图像。,每类各有500个... 查看详情