Tensorflow2.1实现文本中情感分类实现解析
作者:我是王大你是谁 发布时间:2022-12-22 17:49:51
前言
本文主要是用 cpu 版本的 tensorflow 2.1 搭建深度学习模型,完成对电影评论的情感分类任务。 本次实践的数据来源于IMDB 数据集,里面的包含的是电影的影评,每条影评评论文本分为积极类型或消极类型。数据集总共包含 50000 条影评文本,取该数据集的 25000 条影评数据作为训练集,另外 25000 条作为测试集,训练集与测试集中包含相等数量的积极和消极影评,保证数据质量的平衡。
实现过程和思路解析
下载影评数据并进行 padding 处理
(1)这里主要是通过 tf 内置的接口从网络上下载 imdb 数据,该数据是已经经过处理的,每一条评论中的每个单词都是用对应的整数表示的,所以每一条评论都是一个整数列表。而对应的每条影评的标签是一个 0 或 1 的整数, 0 代表的是消极评论,1 代表的是积极评论。
(2)这里的 num_words=6000 表示我们只需要保留了训练数据中出现频率最高的 6000 个常用单词,低频词会被全部弃用,因为一方面这些低频词可能是些符号或者停用词,对影评情感分类没有意义,另一方面如果低频词太多,需要构造的词典太过庞大,严重影响计算效率,且消耗大量内存。
import tensorflow as tf
from tensorflow import keras
imdb = keras.datasets.imdb
num_words = 6000
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=num_words)
(3)这里主要是建立整数与单词之间的映射关系,并建立了一个函数 decode_review 可以将影评数据从数字序列转换回单词序列。
word_index = imdb.get_word_index()
word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
index_word = dict([(value, key) for (key, value) in word_index.items()])
def decode_review(text):
return ' '.join([index_word.get(i, '?') for i in text])
(4)这里主要是对影评数据进行填充,因为每条数据的长度(数字序列的长度)是不一致的,而要进行深度学习模型的输入必须要保证每条影评数据的长度相等,所以我们要进行填充操作,指定了最大的影评长度 maxlen 为 256 ,如果超过 256 则进行截断,如果不足 256 则用 0 (也就是<PAD>对应的整数)在末尾进行填充。这里的 maxlen 可以随意指定,但是其长度会影响模型的效果,需要在实践中不断调整折中。
train_data = keras.preprocessing.sequence.pad_sequences(train_data, value=word_index["<PAD>"], padding='post', maxlen=256)
val_data = keras.preprocessing.sequence.pad_sequences(val_data, value=word_index["<PAD>"], padding='post', maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data, value=word_index["<PAD>"], padding='post', maxlen=256)
创建验证集数据
这里主要是创建验证集,那么有了训练集为什么要创建验证集呢?首先我们要知道训练集数据是用来开发和调整模型的,而检查模型的准确率指标只能是用未见过的数据进行评测,所以我们从原始的训练数据中抽取出 10000 个样本来创建验证集,此时训练样本只有 15000 个,我们结合使用训练集和验证集共同调整和开发模型,当模型定型之后,最后需要使用一次测试集评估模型的实际使用效果即可。
val_data = train_data[:10000]
val_labels = train_labels[:10000]
train_data = train_data[10000:]
train_labels = train_labels[10000:]
搭建简单的深度学习模型
(1)第一层是 Embedding 层,它将输入的每一个单词转换为一个 32 维的向量,所以每一个样本输入就从一维的 (sequence) 变成了二维的 (sequence, 32)
(2)第二层主要是使用了平均池化操作 GlobalAveragePooling1D , 此操作可以将每个样本的二维维度向量 (sequence, 32) 又压缩成一维向量 (32) ,上一步中的 32 维向量表示的是每个单词向量,但是这里的 32 维向量表示的是一个影评样本向量。
(3)第三层是一个通过 relu 激活函数将输入转换成输出为 16 维度向量的全连接层操作
(4)第四层是一个通过 sigmoid 激活函数将输入转换成输出为 1 维度向量的全连接层操作,也就是最后输出一个介于 0 与 1 之间的浮点数,它表示了概率,常规情况下如果概率大于等于 0.5 则说明该样本预测类别为 1 ,否则说明该样本预测类别为 0
model = keras.Sequential()
model.add(keras.layers.Embedding(num_words, 32))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16 , activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
配置并编译模型
(1)我们选择了常用的 Adam 优化器,你也可以自行选择其他优化器。
(2)因为这是一个二分类问题且模型会输出一个概率值,我们选择了常见的 binary_crossentropy 损失函数。
(3)评估指标我们选择了最容易理解的准确率 accuracy 。
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
训练模型
这里主要是使用训练数据进行模型的训练,使用训练集反复进行 40 次模型训练,并且在训练过程中,使用验证集的 10000 个样本来评估模型上的损失值(loss)和准确率(accuracy)。
model.fit(train_data, train_labels, epochs=40, batch_size=512, validation_data=(val_data, val_labels), verbose=1)
输出如下所示:
Train on 15000 samples, validate on 10000 samples
Epoch 1/40
15000/15000 [==============================] - 3s 169us/sample - loss: 0.6913 - accuracy: 0.5465 - val_loss: 0.6881 - val_accuracy: 0.6872
Epoch 2/40
15000/15000 [==============================] - 1s 88us/sample - loss: 0.6815 - accuracy: 0.7043 - val_loss: 0.6732 - val_accuracy: 0.7427
Epoch 3/40
...
Epoch 38/40
15000/15000 [==============================] - 1s 79us/sample - loss: 0.1045 - accuracy: 0.9707 - val_loss: 0.3431 - val_accuracy: 0.8738
Epoch 39/40
15000/15000 [==============================] - 1s 76us/sample - loss: 0.1022 - accuracy: 0.9712 - val_loss: 0.3470 - val_accuracy: 0.8737
Epoch 40/40
15000/15000 [==============================] - 1s 77us/sample - loss: 0.0985 - accuracy: 0.9735 - val_loss: 0.3526 - val_accuracy: 0.8725
评估模型
这里主要是使用测试数据对模型进行评估,由于当前模型较为简单,如果使用复杂的模型和更好的训练方法,准确率应该能达到 98% 以上.
model.evaluate(test_data, test_labels, verbose=2)
结果输出为,损失为 0.368 ,准确率为 0.86488 :
[0.368153291721344, 0.86488]
来源:https://juejin.cn/post/7165348860364062727


猜你喜欢
- 本文涉及:Windows操作系统,Python,PyQt5,Qt Designer,PyCharm一、自适应原理 &
- SQL Server: Sql代码 Select TOP N * From TABLE Order By NewID() NewID()函数
- 高可用架构对于互联网服务基本是标配,无论是应用服务还是数据库服务都需要做到高可用。虽然互联网服务号称7*24小时不间断服务,但多多少少有一些
- 方法方法能给用户自定义的类型添加新的行为。它和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。接收者可以是值接
- 最近学习python并发,于是对多进程、多线程、异步和协程做了个总结。一、多线程多线程就是允许一个进程内存在多个控制权,以便让多个函数同时处
- 我们在网页中使用CSS来设置网页、表格和字体大小,一般使用的是网络上较流行的9磅字:<STYLE type=TEXT/CSS
- 本文所依赖的环境为:进程和线程的概念进程概念我们想运行一个程序,首先会将该程序从存储介质上通过IO总线加载进内存中,而后再通过cpu进行调度
- 本文实例讲述了python常见数制转换用法。分享给大家供大家参考。具体分析如下:1.进位制度Python中二进制是以0b开头的:例如: 0b
- 和朋友讨论时,我提到过一个观点,所有框架层设计中,最核心的是导航设计。最近更看到有国外同行提出“80%的可用性是导航!”因为良好的导航可以保
- 数据可视化是数据科学或机器学习项目中十分重要的一环。通常,你需要在项目初期进行探索性的数据分析(EDA),从而对数据有一定的了解,而且创建可
- 微软在 Github 上开源了一个 Python 静态类型检查工具:pyright ,引起了社区内的多方关注。微软在开源项目上的参与力度是越
- 一、概述MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值(long_query_time,单位
- (在lua中通过loadfile, setfenv实现)python当然也可以:cat config.pybar = 10foo=100ca
- 1. 读取数据用pandas中的read_csv()函数读取出csv文件中的数据:import pandas as pddf = pd.re
- lambda 语法lambda 函数的语法只包含一个语句,表现形式如下:lambda [arg1 [,arg2,.....argn]]:ex
- 目录实例001:数字组合实例002:“个税计算”实例003:完全平方数实例004:这天第几天实例005:三数排序实例006:斐波那契数列实例
- 继上一篇文章使用xlrd来读Excel之后,这一篇文章就来介绍下,如何来写Excel,写Excel我们需要使用第三方库xlwt,和xlrd一
- 下面是我们经常会用到且非常有用的MySQL命令。下面你看到#表示在Unix命令行下执行命令,看到mysql>表示当前已经登录MySQL
- 转换为字符串类型tips['sex_str'] = tips['sex'].astype(str)转换为数值
- 计算交并比:交的面积除以并的面积。要求矩形框的长和宽应该平行于图片框。不然不能用这样的公式计算。原理,从一维上来理解:两条红线的距离之和减去