IMDB数据进行分类

文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

文章目录:​​​​​​

        1)引入依赖包

        2)获取数据集

        3)数据预处理 

        4)定义模型

        5)训练模型

        6)模型评估


1)引入依赖包

- `tensorflow`: TensorFlow机器学习框架。
- `tensorflow.keras.datasets.imdb`: IMDb电影评论数据集,用于情感分类任务。
- `tensorflow.keras.models`: Keras模型的API,用于构建神经网络模型。
- `tensorflow.keras.layers`: Keras层的API,用于构建神经网络层。
- `tensorflow.keras.optimizers`: Keras优化器的API,用于配置模型的训练优化算法。
- `numpy`: 用于处理数值计算和数组操作的库。
- `matplotlib.pyplot`: 用于绘制数据可视化图表的库。

        目的是为了在TensorFlow中准备进行文本分类任务。通过导入IMDB电影评论数据集,可以使用这个数据集来训练和评估模型。使用TensorFlow中的模型、层和优化器等组件,可以构建一个神经网络模型,并使用该模型对电影评论进行情感分类。最后,使用NumPy和Matplotlib库来处理数据和可视化结果。

import tensorflow as tf
from tensorflow.keras.datasets import imdb
from tensorflow.keras import models, layers, optimizers
import numpy as np
import matplotlib.pyplot as plt

2)获取数据集

这行代码从IMDB电影评论数据集中加载训练数据和测试数据。该数据集已经经过预处理,评论文本被转换为整数序列,每个整数代表字典中的一个单词。加载数据时,`num_words=10000`参数指定了仅保留训练数据中出现频率最高的前10,000个单词,其他单词被标记为特殊符号"\<UNK\>"。

加载后的数据被分为训练数据和测试数据,分别存储在`train_data`、`train_labels`、`test_data`和`test_labels`中。`train_data`和`test_data`是整数序列列表,代表电影评论的单词索引序列。`train_labels`和`test_labels`是包含0和1的列表,表示评论的情感类别,0表示负面情感,1表示正面情感。

加载数据时,限制保留最常见的单词有助于减少特征空间的维度,从而简化模型训练和推理的计算复杂度。

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

train_data[0]train_labels[0]分别是IMDB数据集中的第一条评论文本和对应的情感类别标签。由于数据经过预处理,评论文本已经被转换为整数序列,每个整数代表字典中的一个单词 

print(train_data[0],train_labels[0])
[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32] 1
print("Words: ", train_data[2])
print("Labels: ", train_labels[2])
Words:  [1, 14, 47, 8, 30, 31, 7, 4, 249, 108, 7, 4, 5974, 54, 61, 369, 13, 71, 149, 14, 22, 112, 4, 2401, 311, 12, 16, 3711, 33, 75, 43, 1829, 296, 4, 86, 320, 35, 534, 19, 263, 4821, 1301, 4, 1873, 33, 89, 78, 12, 66, 16, 4, 360, 7, 4, 58, 316, 334, 11, 4, 1716, 43, 645, 662, 8, 257, 85, 1200, 42, 1228, 2578, 83, 68, 3912, 15, 36, 165, 1539, 278, 36, 69, 2, 780, 8, 106, 14, 6905, 1338, 18, 6, 22, 12, 215, 28, 610, 40, 6, 87, 326, 23, 2300, 21, 23, 22, 12, 272, 40, 57, 31, 11, 4, 22, 47, 6, 2307, 51, 9, 170, 23, 595, 116, 595, 1352, 13, 191, 79, 638, 89, 2, 14, 9, 8, 106, 607, 624, 35, 534, 6, 227, 7, 129, 113]
Labels:  0

3)数据预处理 

reversed_word_index是一个将整数编码映射回单词的字典。在IMDB数据集中,整数编码3以下的值被保留用于特殊用途。

通过使用reversed_word_index,我们可以将整数序列转换回原始的文本形式。下面的代码将整数序列train_data[2]转换为文本:

word_index = imdb.get_word_index()
reversed_word_index = dict([(value, key) for (key, value) in word_index.items()])
" ".join([ reversed_word_index.get(i-3, "?") for i in train_data[2]])
"? this has to be one of the worst films of the 1990s when my friends i were watching this film being the target audience it was aimed at we just sat watched the first half an hour with our jaws touching the floor at how bad it really was the rest of the time everyone else in the theatre just started talking to each other leaving or generally crying into their popcorn that they actually paid money they had ? working to watch this feeble excuse for a film it must have looked like a great idea on paper but on film it looks like no one in the film has a clue what is going on crap acting crap costumes i can't get across how ? this is to watch save yourself an hour a bit of your life"

vectorize_sequences函数用于将整数序列向量化,将其转换为二进制矩阵表示形式。

函数的输入是整数序列列表sequences,以及要表示的维度dimension(默认为10000)。

函数首先创建一个全零矩阵results,其形状为(len(sequences), dimension),其中len(sequences)是序列的数量。

然后,对于每个序列,函数将矩阵results中对应的索引位置设置为1,表示该索引对应的单词在序列中出现。

最后,函数返回向量化后的结果矩阵results。

def vectorize_sequences(sequences, dimension=10000):
  results = np.zeros((len(sequences), dimension))
  for i, sequence in enumerate(sequences):
    results[i, sequence] = 1
  return results

根据IMDB数据集的载入方式,train_datatest_data分别是训练集和测试集的整数序列。通过调用vectorize_sequences函数,将这些整数序列向量化为二进制矩阵表示。

因此,x_train是训练集的向量化结果,其形状为(训练样本数量, 10000),其中10000是指定的维度。

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

x_train.shape

根据IMDB数据集的载入方式,train_labelstest_labels分别是训练集和测试集的标签,表示影评的情感分类(正面或负面)。

为了在训练和评估模型时使用这些标签,需要将它们转换为NumPy数组,并将数据类型转换为浮点型。

y_train = np.asarray(train_labels).astype("float32")
y_test = np.asarray(test_labels).astype("float32")

y_train.shape

4)定义模型

  • 第一层是输入层,具有16个神经元,并使用ReLU激活函数。
  • 第二层也具有16个神经元,并使用ReLU激活函数。
  • 第三层是输出层,具有1个神经元,并使用Sigmoid激活函数。

模型的输入形状是(10000,),表示输入数据的维度为10000。这对应于之前使用vectorize_sequences函数转换后的训练数据。

要构建完整的模型,还需要进行编译和配置模型的优化器、损失函数和评估指标。

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000, )))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

     x_val是用于验证的部分训练数据,它由x_train中的前10000个样本组成。这样做是为了在训练过程中对模型进行验证,以便及时检测过拟合等问题。

        因此,x_val的形状是(10000, 10000),表示有10000个验证样本,每个样本具有10000个特征。

x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

x_val.shape
(10000, 10000)

5)训练模型

以上代码使用rmsprop优化器、binary_crossentropy损失函数进行模型编译,并使用部分训练数据(partial_x_trainpartial_y_train)进行训练。训练过程中进行了20个周期的训练,每个批次的大小为512。验证数据(x_valy_val)被用来评估模型的性能。

训练过程中的训练损失、训练准确率、验证损失和验证准确率等指标会保存在history对象中。

model.compile(optimizer='rmsprop', loss=tf.keras.losses.binary_crossentropy, metrics=['acc'])
history = model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=512, validation_data=(x_val, y_val))
Epoch 1/20
30/30 [==============================] - 3s 52ms/step - loss: 0.5330 - acc: 0.7746 - val_loss: 0.4231 - val_acc: 0.8489
Epoch 2/20
30/30 [==============================] - 1s 17ms/step - loss: 0.3316 - acc: 0.8992 - val_loss: 0.3476 - val_acc: 0.8619
Epoch 3/20
30/30 [==============================] - 0s 17ms/step - loss: 0.2448 - acc: 0.9217 - val_loss: 0.2844 - val_acc: 0.8908
Epoch 4/20
30/30 [==============================] - 1s 18ms/step - loss: 0.1957 - acc: 0.9357 - val_loss: 0.2764 - val_acc: 0.8887
Epoch 5/20
30/30 [==============================] - 0s 17ms/step - loss: 0.1554 - acc: 0.9517 - val_loss: 0.2775 - val_acc: 0.8891
Epoch 6/20
30/30 [==============================] - 1s 20ms/step - loss: 0.1304 - acc: 0.9591 - val_loss: 0.3038 - val_acc: 0.8815
Epoch 7/20
30/30 [==============================] - 1s 22ms/step - loss: 0.1105 - acc: 0.9661 - val_loss: 0.3001 - val_acc: 0.8857
Epoch 8/20
30/30 [==============================] - 1s 23ms/step - loss: 0.0920 - acc: 0.9745 - val_loss: 0.3402 - val_acc: 0.8772
Epoch 9/20
30/30 [==============================] - 1s 19ms/step - loss: 0.0775 - acc: 0.9791 - val_loss: 0.3302 - val_acc: 0.8821
Epoch 10/20
30/30 [==============================] - 1s 23ms/step - loss: 0.0651 - acc: 0.9833 - val_loss: 0.3735 - val_acc: 0.8778
Epoch 11/20
30/30 [==============================] - 1s 18ms/step - loss: 0.0547 - acc: 0.9862 - val_loss: 0.3760 - val_acc: 0.8797
Epoch 12/20
30/30 [==============================] - 0s 17ms/step - loss: 0.0439 - acc: 0.9897 - val_loss: 0.4291 - val_acc: 0.8683
Epoch 13/20
30/30 [==============================] - 1s 18ms/step - loss: 0.0368 - acc: 0.9921 - val_loss: 0.4361 - val_acc: 0.8736
Epoch 14/20
30/30 [==============================] - 0s 16ms/step - loss: 0.0302 - acc: 0.9939 - val_loss: 0.4589 - val_acc: 0.8744
Epoch 15/20
30/30 [==============================] - 0s 16ms/step - loss: 0.0242 - acc: 0.9950 - val_loss: 0.4899 - val_acc: 0.8719
Epoch 16/20
30/30 [==============================] - 0s 16ms/step - loss: 0.0178 - acc: 0.9971 - val_loss: 0.5240 - val_acc: 0.8692
Epoch 17/20
30/30 [==============================] - 0s 17ms/step - loss: 0.0153 - acc: 0.9979 - val_loss: 0.5700 - val_acc: 0.8699
Epoch 18/20
30/30 [==============================] - 1s 18ms/step - loss: 0.0118 - acc: 0.9990 - val_loss: 0.5900 - val_acc: 0.8666
Epoch 19/20
30/30 [==============================] - 1s 19ms/step - loss: 0.0094 - acc: 0.9990 - val_loss: 0.6247 - val_acc: 0.8653
Epoch 20/20
30/30 [==============================] - 1s 23ms/step - loss: 0.0078 - acc: 0.9991 - val_loss: 0.6550 - val_acc: 0.8654
print(model.summary)

6)模型评估

history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(loss_values) + 1)

plt.plot(epochs, loss_values, 'bo', label='Training Loss')
plt.plot(epochs, val_loss_values, 'b', label='Validation Loss')
plt.title("Training and validation loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.show()

plt.clf()

acc_values = history_dict['acc']
val_acc_values = history_dict['val_acc']

plt.plot(epochs, acc_values, 'bo', label='Trainig Accuracy')
plt.plot(epochs, val_acc_values, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.show()

model.evaluate(x_test, y_test)

 [0.7144433856010437, 0.8525999784469604]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值