0


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')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深度学习实战——使用循环神经网络构建情感分析模型

标签: 深度学习 keras lstm

本文转载自: https://blog.csdn.net/LOVEmy134611/article/details/126702803
版权归原作者 盼小辉丶 所有, 如有侵权,请联系我们删除。

“Keras深度学习实战——使用长短时记忆网络构建情感分析模型”的评论:

还没有评论