文本分类项目实战:电影评论 (tensorflow2.0官方教程翻译)

本文会将文本形式的影评分为“正面”或“负面”影评。这是一个二元分类(又称为两类分类)的示例,也是一种重要且广泛适用的机器学习问题。

我们将使用包含来自网络电影数据库的50,000条电影评论文本的IMDB数据集,这些被分为25,000条训练评论和25,000条评估评论,训练和测试集是平衡的,这意味着它们包含相同数量的正面和负面评论。

本章节使用tf.keras,这是一个高级API,用于在TensorFlow中构建和训练模型,有关使用tf.keras的更高级文本分类教程,请参阅MLCC文本分类指南

2.0.0-alpha0

1. 下载IMDB数据集

IMDB数据集与TensorFlow一起打包,它已经被预处理,使得评论(单词序列)已被转换为整数序列,其中每个整数表示字典中的特定单词。

以下代码将IMDB数据集下载到您的计算机(如果您已经下载了它,则使用缓存副本):

参数 num_words=10000 保留训练数据中最常出现的10,000个单词,丢弃罕见的单词以保持数据的大小可管理。

2. 探索数据

我们花一点时间来理解数据的格式,数据集经过预处理:每个示例都是一个整数数组,表示电影评论的单词。每个标签都是0或1的整数值,其中0表示负面评论,1表示正面评论。

Training entries: 25000, labels: 25000

评论文本已转换为整数,其中每个整数表示字典中的特定单词。以下是第一篇评论的内容:

[1, 14, 22, 16, 43, 530, 973, ...., 32, 15, 16, 5345, 19, 178, 32]

电影评论的长度可能不同,以下代码显示了第一次和第二次评论中的字数。由于对神经网络的输入必须是相同的长度,我们稍后需要解决此问题。

(218, 189)

2.1. 将整数转换成文本

了解如何将整数转换回文本可能很有用。 在这里,我们将创建一个辅助函数来查询包含整数到字符串映射的字典对象:

现在我们可以使用decode_review函数显示第一次检查的文本:

" this film was just brilliant casting location scenery story direction .....that was shared with us all"

3. 预处理数据

影评(整数数组)必须转换为张量,然后才能馈送到神经网络中。我们可以通过以下两种方法实现这种转换:

在本教程中,我们将使用第二种方法。

由于电影评论的长度必须相同,我们将使用pad_sequences函数来标准化长度:

我们再看一下数据的长度:

(256, 256)

并查看数据:

4. 构建模型

神经网络通过堆叠层创建而成,这需要做出两个架构方面的主要决策:

在本示例中,输入数据由字词-索引数组构成。要预测的标签是 0 或 1。接下来,我们为此问题构建一个模型:

这些层按顺序堆叠以构建分类器:

  1. 第一层是Embedding层。该层采用整数编码的词汇表,并查找每个词索引的嵌入向量。这些向量是作为模型训练学习的,向量为输入数组添加维度,生成的维度为:(batch, sequence, embedding).
  2. 接下来,GlobalAveragePooling1D层通过对序列维度求平均值,针对每个样本返回一个长度固定的输出向量。这样,模型便能够以尽可能简单的方式处理各种长度的输入。
  3. 该长度固定的输出向量会传入一个全连接 (Dense) 层(包含 16 个隐藏单元)
  4. 最后一层与单个输出节点密集连接。应用sigmoid激活函数后,结果是介于 0 到 1 之间的浮点值,表示概率或置信水平。

4.1. 隐藏单元

上述模型在输入和输出之间有两个中间层(也称为“隐藏”层)。输出(单元、节点或神经元)的数量是相应层的表示法空间的维度。换句话说,该数值表示学习内部表示法时网络所允许的自由度。

如果模型具有更多隐藏单元(更高维度的表示空间)和/或更多层,则说明网络可以学习更复杂的表示法。不过,这会使网络耗费更多计算资源,并且可能导致学习不必要的模式(可以优化在训练数据上的表现,但不会优化在测试数据上的表现)。这称为过拟合,我们稍后会加以探讨。

4.2. 损失函数和优化器

模型需要一个损失函数和一个用于训练的优化器。由于这是一个二元分类问题,并且模型输出概率(网络最后一层使用sigmoid 激活函数,仅包含一个单元),那么最好使用binary_crossentropy(二元交叉熵)损失。

这不是损失函数的唯一选择,例如,您可以选择mean_squared_error(均方误差)。但对于输出概率值的模型,交叉熵(crossentropy)往往是最好 的选择。交叉熵是来自于信息论领域的概念,用于衡量概率分布之间的距离,在这个例子中就是真实分布与预测值之间的距离。。

在后面,当我们探索回归问题(比如预测房子的价格)时,我们将看到如何使用另一种称为均方误差的损失函数。

现在,配置模型以使用优化器和损失函数:

5. 创建验证集

在训练时,我们想要检查模型在以前没有见过的数据上的准确性。通过从原始训练数据中分离10,000个示例来创建验证集。(为什么不立即使用测试集?我们的目标是仅使用训练数据开发和调整我们的模型,然后仅使用测试数据来评估我们的准确性)。

6. 训练模型

以512个样本的小批量训练模型40个周期,这是x_trainy_train张量中所有样本的40次迭代。在训练期间,监控模型在验证集中的10,000个样本的损失和准确性:

Epoch 40/40 15000/15000 [==============================] - 1s 54us/sample - loss: 0.0926 - accuracy: 0.9771 - val_loss: 0.3133 - val_accuracy: 0.8824

7. 评估模型

让我们看看模型的表现,将返回两个值,损失(表示我们的错误的数字,更低的值更好)和准确性。

25000/25000 [==============================] - 1s 45us/sample - loss: 0.3334 - accuracy: 0.8704 [0.33341303256988525, 0.87036]

这种相当简单的方法实现了约87%的准确度,使用更先进的方法,模型应该接近95%。

8. 创建准确性和损失随时间变化的图表

model.fit()返回一个History对象,其中包含一个字典,其中包含训练期间发生的所有事情:

有四个条目:在训练和验证期间,每个条目对应一个监控指标,我们可以使用这些来绘制训练和验证损失以进行比较,以及训练和验证准确性:

<Figure size 640x480 with 1 Axes>

png

在该图中,点表示训练损失和准确度,实线表示验证损失和准确度。

可以注意到,训练损失随着周期数的增加而降低,训练准确率随着周期数的增加而提高。在使用梯度下降法优化模型时,这属于正常现象(该方法应在每次迭代时尽可能降低目标值)。

验证损失和准确率的变化情况并非如此,它们似乎在大约 20 个周期后达到峰值。这是一种过拟合现象:模型在训练数据上的表现要优于在从未见过的数据上的表现。在此之后,模型会过度优化和学习特定于训练数据的表示法,而无法泛化到测试数据。

对于这种特殊情况,我们可以在大约 20 个周期后停止训练,防止出现过拟合。稍后,您将了解如何使用回调自动执行此操作。

最新版本:https://www.mashangxue123.com/tensorflow/tf2-tutorials-keras-basic_text_classification.html 英文版本:https://tensorflow.google.cn/beta/tutorials/keras/basic_text_classification 翻译建议PR:https://github.com/mashangxue/tensorflow2-zh/edit/master/r2/tutorials/keras/basic_text_classification.md