日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新)


IMDB影评的情感分析任务

学习目标

  • 了解影评情感分析任务和IMDB数据集。
  • 掌握使用RNN模型完成IMDB影评情感分析任务的实现流程。
  • 掌握对比不同隐层的RNN模型对情感分析任务的影响。

任务说明

  • 对IMDB影评语料进行情感分析,是NLP中典型的应用案例,它的输入是一段文本,输出该段文本为“积极”或“消极”的态度,这是典型的二分类任务。与此同时,我还将在此任务基础上对所使用的RNN模型进行改进,增加更多的隐层来比较最终的效果!

数据集说明

  • 数据集名称: IMDB数据集
  • 数据集大小: 84M
  • 数据下载地址: http://ai.stanford.edu/~amaas/data/sentiment/
  • 训练样本数: 25000
  • 验证样本数: 25000
  • 数据集预览:
review  label
"Once again Mr. Costner has dragged out a movie for far longer than necessary. Aside from the terrific sea rescue sequences, of which there are very few I just did not care about any of the characters"       neg
"This is an example of why the majority of action films are the same. Generic and boring, there's really nothing worth watching here. A complete waste of the then barely-tapped talents of Ice-T and Ice"      neg
"Finally, the golf scenes are well photographed. Although the course used in the movie was not the actual site of the historical tournament, the little liberties taken by Disney do not detract from the beauty of the film."      pos
...
  • 内容说明:

    • review代表用户影评文本,label代表评论的情感极性,有pos和neg两种,分别代表积极和消极.
    • 直接下载的数据是经过处理的tfrecord二进制文件(压缩文件),以上预览是通过还原的文本内容.

使用GRU模型实现文本生成任务的步骤

  • 第一步:使用TFDS下载IMDB数据集,并划分训练集和测试集
  • 第二步:按batch划分数据并训练单层biLSTM模型
  • 第三步:训练双层bi-LSTM模型,对比效果

第一步: 使用TFDS下载IMDB数据集,并划分训练集和测试集

  • 下载IMDB数据:
from __future__ import absolute_import, division, print_function, unicode_literals# TFDS介绍: tensorflow datasets的缩写,由tensorflow官方提供的标准数据集工具,
# 截止到2020年2月,共包含可使用的不同数据集数量155个,同时提供在加载过程中,
# 对数据集的多种操作,满足后续对dataset的使用.
# tfds安装: pip install tensorflow_datasets==2.0.0
import tensorflow_datasets as tfds
import tensorflow as tf
# 打印tensorflow版本
print("Tensorflow Version:", tf.__version__)# 使用tfds加载数据集,其中参数with_info=True代表返回数据相关信息,包括数据进行数值映射的方式等。
# 参数as_supervised=True, 代表返回的数据为监督数据即需要将data和对应的label以一个元组的方式(data, label)返回。
dataset, info = tfds.load('imdb_reviews/subwords8k', with_info=True,as_supervised=True)# 返回的dataset对象是一个字典形式,直接取train和test作为训练集和验证集
train_dataset, test_dataset = dataset['train'], dataset['test']# 从dataset的info对象中可以获得子词数值映射器或称为子词数值编码器(encoder)
# 关于子词数值映射的概念下方有详细说明
encoder = info.features['text'].encoder# 从子词数值映射器中取出它映射过的非重复子词数量
print('Vocabulary size: {}'.format(encoder.vocab_size))
  • 输出效果
Tensorflow Version: 2.1.0-rc2
Vocabulary size: 8185
  • 子词数值映射(也称子词编码器):

    • 文本的子词数值映射是文本数值映射的拓展,基本的文本数值映射是将每个英文单词映射成一个词汇,如hello映射成数值1,而文本子词映射可能将hello拆分成子词如:hell和o,分别映射成对应的数值34和6,这样相当于将hello映射成34和6。文本子词数值映射在英文文本生成任务中使用频繁,因为子词的多样组合使得模型对不同的文本输入更加友好,不再局限于训练语料大小。在TFDS中,对该文本语料都使用了该技巧。
  • 用一个样例演示子词数值映射的方式:
# 样例字符串hello tensorflow
sample_string = 'Hello TensorFlow.'# 使用encoder进行映射(编码)并查看结果
encoded_string = encoder.encode(sample_string)
print('Encoded string is {}'.format(encoded_string))# 之后使用对应的方法decode进行解码并查看结果
original_string = encoder.decode(encoded_string)
print('The original string: "{}"'.format(original_string))
  • 输出效果
Encoded string is [4025, 222, 6307, 2327, 4043, 2120, 7975]
The original string: "Hello TensorFlow."
# 断定解码字符串与原样例字符串相同
assert original_string == sample_string# 为什么原来两个单词会映射成5个数值呢?
# 我们将每个数值进行解码查看,发现它们都是原单词的子词(原单词的一部分)
for index in encoded_string:print('{} ----> {}'.format(index, encoder.decode([index])))
  • 输出效果
4025 ----> Hell
222 ----> o
6307 ----> Ten
2327 ----> sor
4043 ----> Fl
2120 ----> ow
7975 ----> .

第二步:按batch划分数据并训练单层biLSTM模型

  • 批次化数据
# 定义shuffle时的缓存大小
BUFFER_SIZE = 10000
# 定义训练批次大小
BATCH_SIZE = 64# 打乱训练数据
train_dataset = train_dataset.shuffle(BUFFER_SIZE)
# 划分批次,并做批次内最大长度补齐,使每个批次输入都是一个矩阵# 训练集划分
train_dataset = train_dataset.padded_batch(BATCH_SIZE, train_dataset.output_shapes)# 验证集划分
test_dataset = test_dataset.padded_batch(BATCH_SIZE, test_dataset.output_shapes)
  • 构建模型:
# 模型结构
# 首层为embedding层
# 之后双向LSTM层
# 全连接层
# 输出层(全连接层)
model = tf.keras.Sequential([tf.keras.layers.Embedding(encoder.vocab_size, 64),tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),tf.keras.layers.Dense(64, activation='relu'),tf.keras.layers.Dense(1, activation='sigmiod')
])
  • 定义损失函数和优化方法
# 使用二分类交叉熵损失,并且from_logits设置为True,即保留y_pred的真实值,不进行强制为0或1
# 优化器是Adam
# 评估指标为准确率
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),optimizer=tf.keras.optimizers.Adam(1e-4),metrics=['accuracy'])
  • 训练模型并打印日志
# 指定训练集和验证集和轮数进行训练
# 这里指定验证过程的总步数为30以防止验证时间过久
history = model.fit(train_dataset, epochs=10,validation_data=test_dataset, validation_steps=30)
  • 输出效果
Train for 391 steps, validate for 30 steps
Epoch 1/10
391/391 [==============================] - 48s 123ms/step - loss: 0.6656 - accuracy: 0.5314 - val_loss: 0.5635 - val_accuracy: 0.6922
Epoch 2/10
391/391 [==============================] - 44s 112ms/step - loss: 0.3783 - accuracy: 0.8263 - val_loss: 0.3738 - val_accuracy: 0.8510
Epoch 3/10
391/391 [==============================] - 44s 111ms/step - loss: 0.2747 - accuracy: 0.8876 - val_loss: 0.3534 - val_accuracy: 0.8448
Epoch 4/10
391/391 [==============================] - 44s 113ms/step - loss: 0.2247 - accuracy: 0.9128 - val_loss: 0.3405 - val_accuracy: 0.8656
Epoch 5/10
391/391 [==============================] - 43s 111ms/step - loss: 0.1862 - accuracy: 0.9324 - val_loss: 0.3479 - val_accuracy: 0.8542
Epoch 6/10
391/391 [==============================] - 44s 113ms/step - loss: 0.1640 - accuracy: 0.9436 - val_loss: 0.3703 - val_accuracy: 0.8625
Epoch 7/10
391/391 [==============================] - 44s 113ms/step - loss: 0.1562 - accuracy: 0.9459 - val_loss: 0.4085 - val_accuracy: 0.8651
Epoch 8/10
391/391 [==============================] - 44s 113ms/step - loss: 0.1381 - accuracy: 0.9530 - val_loss: 0.4257 - val_accuracy: 0.8656
Epoch 9/10
391/391 [==============================] - 44s 112ms/step - loss: 0.1226 - accuracy: 0.9589 - val_loss: 0.4311 - val_accuracy: 0.8646
Epoch 10/10
391/391 [==============================] - 44s 113ms/step - loss: 0.1087 - accuracy: 0.9658 - val_loss: 0.4558 - val_accuracy: 0.8599
  • 绘制损失和准确率对照曲线:
import matplotlib.pyplot as plt# 根据训练历史日志和对应的评估指标绘制曲线
def plot_graphs(history, metric):# 绘制训练曲线plt.plot(history.history[metric])# 绘制验证曲线plt.plot(history.history['val_'+metric], '')# 横坐标为epochsplt.xlabel("Epochs")# 纵坐标为对应指标plt.ylabel(metric)# 图中曲线说明框plt.legend([metric, 'val_'+metric])plt.show()# 进行准确率和损失的绘制
plot_graphs(history, 'accuracy')
plot_graphs(history, 'loss')

  • 在验证集上计算评估损失和准确率:
test_loss, test_acc = model.evaluate(test_dataset)print('Test Loss: {}'.format(test_loss))
print('Test Accuracy: {}'.format(test_acc))
  • 输出效果
391/391 [==============================] - 33s 84ms/step - loss: 0.5256 - accuracy: 0.8432
Test Loss: 0.5255793487400655
Test Accuracy: 0.8431599736213684

第三步:训练双层bi-LSTM模型,对比效果

  • 构建模型
# 结构与上面的模型类似,只不过多加了一层双向LSTM
# return_sequences=True表示将返回每一个时间步的综合结果(结果张量进行拼接)。
# 为了防止过拟合,还加入了dropout层
model = tf.keras.Sequential([tf.keras.layers.Embedding(encoder.vocab_size, 64),tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64,  return_sequences=True)),tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),tf.keras.layers.Dense(64, activation='relu'),tf.keras.layers.Dropout(0.5),tf.keras.layers.Dense(1)
])
  • 选择损失函数和优化方法
# 与第一个模型相同
# 二分类交叉熵损失
# Adam优化器
# 准确率为评估指标
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),optimizer=tf.keras.optimizers.Adam(1e-4),metrics=['accuracy'])
  • 模型训练并打印日志
# 模型训练拟合
history = model.fit(train_dataset, epochs=10,validation_data=test_dataset,validation_steps=30)
  • 输出效果
Train for 391 steps, validate for 30 steps
Epoch 1/10
391/391 [==============================] - 82s 209ms/step - loss: 0.6905 - accuracy: 0.5090 - val_loss: 0.6268 - val_accuracy: 0.6500
Epoch 2/10
391/391 [==============================] - 77s 198ms/step - loss: 0.4483 - accuracy: 0.8062 - val_loss: 0.3569 - val_accuracy: 0.8562
Epoch 3/10
391/391 [==============================] - 78s 198ms/step - loss: 0.2891 - accuracy: 0.8906 - val_loss: 0.3535 - val_accuracy: 0.8609
Epoch 4/10
391/391 [==============================] - 78s 198ms/step - loss: 0.2364 - accuracy: 0.9166 - val_loss: 0.3601 - val_accuracy: 0.8667
Epoch 5/10
391/391 [==============================] - 78s 198ms/step - loss: 0.1974 - accuracy: 0.9359 - val_loss: 0.3640 - val_accuracy: 0.8708
Epoch 6/10
391/391 [==============================] - 78s 200ms/step - loss: 0.1629 - accuracy: 0.9502 - val_loss: 0.3921 - val_accuracy: 0.8552
Epoch 7/10
391/391 [==============================] - 77s 197ms/step - loss: 0.1454 - accuracy: 0.9580 - val_loss: 0.4394 - val_accuracy: 0.8646
Epoch 8/10
391/391 [==============================] - 78s 200ms/step - loss: 0.1244 - accuracy: 0.9656 - val_loss: 0.4521 - val_accuracy: 0.8641
Epoch 9/10
391/391 [==============================] - 78s 198ms/step - loss: 0.1108 - accuracy: 0.9721 - val_loss: 0.4762 - val_accuracy: 0.8458
Epoch 10/10
391/391 [==============================] - 77s 198ms/step - loss: 0.0906 - accuracy: 0.9791 - val_loss: 0.5085 - val_accuracy: 0.8484
  • 绘制损失和准确率对照曲线:
# 绘制损失和准确率对照曲线
plot_graphs(history, 'accuracy')
plot_graphs(history, 'loss')

  • 在验证集上计算评估损失和准确率:
test_loss, test_acc = model.evaluate(test_dataset)print('Test Loss: {}'.format(test_loss))
print('Test Accuracy: {}'.format(test_acc))
  • 输出效果
391/391 [==============================] - 33s 84ms/step - loss: 0.5256 - accuracy: 0.8432
Test Loss: 0.5255793487400655
Test Accuracy: 0.8431599736213684

对比分析:

  • 在IMDB数据集的25000条训练数据下,单层biLSTM的验证准确率为: 0.8578, 双层biLSTM的验证准确率为: 0.8432, 相比之下,模型准确率没有因为层数的增加而提升,反倒略微下降。说明在该大小的文本数据量级上,使用层数更多的LSTM并不能提升模型准确率,模型优化可以从其他超参数或工程技巧入手。

IMDB影评的情感分析任务:双层bi-LSTM模型(双向LSTM)相关推荐

  1. Tensorflow2.0学习(五) — Keras基础应用(IMDb电影集情感分析)

    今天这一节内容是关于Keras应用分析的最后一节,在熟悉了Keras的基础知识之后,下面几节我们就可以正式接触Tensorflow2.0.根据博主多处查阅,最终还是发现Tensorflow的官方教程好 ...

  2. 使用SnowNLP对影评进行情感分析

    1.准备数据集 2.准备相关包 from snownlp import SnowNLP import codecs import os import matplotlib.pyplot as plt ...

  3. PaddlePaddle︱开发文档中学习情感分类(CNN、LSTM、双向LSTM)、语义角色标注

    PaddlePaddle出教程啦,教程一部分写的很详细,值得学习. 一期涉及新手入门.识别数字.图像分类.词向量.情感分析.语义角色标注.机器翻译.个性化推荐. 二期会有更多的图像内容. 随便,帮国产 ...

  4. 实战六十四:基于机器学习朴素贝叶斯的豆瓣Top250影评的情感分析与预测 附完整源码和数据

    首先需要豆瓣Top250影评的语料,我用Scrapy抓取了5w份语料,用于训练与验证. 豆瓣影评爬虫 github.com/3inchtime/d- 有了语料之后我们就可以开始实际开发了. 这里建议使 ...

  5. [深度学习-实战]LSTM Attention训练IMDB文本的情感分析

    Train.npz, test.npz 以及embedding_matrix.npy的产生请看这本博客 完整代码如下 import os import numpy as np import tenso ...

  6. 朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测。​

    前言 本文使用朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测. 最近在学习自然语言正负面情感的处理问题,但是绝大部分能搜索到的实践都是Kggle上IMDB影评的情感分析. 所以在这里我就 ...

  7. 自然语言11_情感分析

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.htm?courseId=1005269003&am ...

  8. python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码

    一.项目介绍 python商品评论数据采集与分析可视化系统 Flask框架.MySQL数据库. requests爬虫.可抓取指定商品评论.Echarts可视化.评论多维度分析.NLP情感分析.LDA主 ...

  9. 深度学习笔记——情感分析

    很早之前就想写一篇关于用深度学习做情感分析的文章,一直拖到现在,拖延症啊.... 什么是情感分析? 情感分析(Sentiment analysis)是自然语言处理(NLP)领域的一个任务,又称倾向性分 ...

最新文章

  1. 传智168期JavaEE struts2杜宏 day 29~day31笔记(2017年2月4日23:14:00)
  2. SCP传输文件和断点续传
  3. SAP UI5 extension component loads standard component
  4. 面经——嵌入式软件工程师ARM体系与架构相关
  5. ES6~ES12——Array Includes、Object values、Object entries、Object fromEntries、flat、flatMap、空值合并运算符、可选链等
  6. 保护系统 用数据库加密实现数据安全
  7. 荣耀9X将搭载麒麟810处理器:全球四大7nm芯片之一无法低调
  8. mysql的int最大值_MySQL中int最大值深入讲解
  9. 这个世界上不存在什么弯道超车,只存在正道超车
  10. 微软新版 Edge 浏览器叫板 Chrome!
  11. 牛客网暑期ACM多校训练营(第五场): F. take(期望+线段树)
  12. mysql怎么让自增id不连续_MySQL中自增主键不连续之解决方案。(20131109)
  13. 怎样取消IBM笔记本电脑的桌面扩展功能?
  14. 2022年工业互联网厂商全景地图
  15. fgo梅林服务器维护,FGO针对开挂用户处理公告 封禁账号并回复异常数据
  16. 项目集锦 | 易基因近期m6A甲基化(MeRIP-seq)研究成果
  17. 关于调制解调器、路由器、交换机
  18. 工信部宣布新规,微信支付存在漏洞必须整改,网友:马化腾会赔偿损失吗?
  19. 计算机yiji教案,剑桥一级下册详细教案
  20. Linux下的共享内存 ---创建共享内存

热门文章

  1. C#——signalr实现简单的网页实时聊天
  2. 1M带宽能做些什么?
  3. C++报错信息:LNK2001:无法解析的外部符号 原因分析及解决方法
  4. GotW#63 狂乱的代码
  5. python opencv resize函数_OpenCV尺寸调整函数resize
  6. matlab画图颜色属性
  7. 解决报错:did not contain a valid NDK and couldn‘t be used
  8. pwn题堆利用的一些姿势 -- IO_FILE
  9. SIM卡的操作系统cos
  10. ping 超时原因总结