文章目录
一、数据集介绍与可视化展示
1.数据集介绍
实验采用的是IMDB数据集,共包含50000条评论样本,各自都有一个鲜明的态度,要么是正面评论,要么就是负面评论。
数据集中的评论已经被预处理,由单词序列转化为了整数序列,每一个整数都对应着字典上的某个单词。
该数据集load_data()默认的test_split为0.5,所以划分出25000个训练样本,25000个测试样本。
load_data()中出现的参数num_words=10000表示仅保留train_data中前10000个最常出现的单词
在原来的数据中总共有88585个单词,但大部分都仅仅出现了一次,这些单词对我们分类的工作毫无帮助,还会增加工作处理,所以我们将其舍弃,只取用前10000个单词。
test_data与train_data是由评论列表所组成的数组(numpy.ndarray),每条评论是由整数序列所表示的列表(list);
test_labels与train_labels是由01所组成的数组(numpy.ndarray),0表示负面,1表示正面。
2.数据展示——评论解码
word_index是一个将单词映射为整数的字典;
dict()函数用于创建一个字典,此时是通过将word_inde中元素的键值对逆转,得到一个可以由整数索引到单词的字典。
str.join(item),将序列中的元素以指定的字符连接生成一个新的字符串,此处就是以空格作为分隔,将train_data[0]对应的单词连接为一个字符串
其内部就是使用字典reverse_word_index
get(i-3,'?'),表示如果有i-3对应的键值,则返回对应值,若不存在,则返回?
Decodes the review. Note that the indices are offset by 3
because 0, 1, and 2 are reserved indices for “padding,”“start of sequence,” and “unknown.”
通过具体实验,说明前三项的值,如果不进行减3处理将导致语意混乱
二、数据处理与说明
1.train_data处理(列表处理)
根据上图所示,每条评论列表对应的长度不同,但神经网络使用的是连续批次的数据,所以要把列表转化为张量。
方法一:将列表填充至相同的长度,将他们转为形状相同的整数张量(之后可用Embeding层处理)
方法二:对列表进行one-hot编码将其转化为01表示的向量,向量维度则为10000(之后可用Dense层处理,它可处理浮点数向量数据)
np.zeros((len(sequences), dimension)),也就是初始化一个初值为0,行为25000,列为10000的二维数组
2.train_labels处理(标签向量化)
将01由之前的int64转为float32
网络最终输出的是预测值,为浮点数,为了后续的计算,此处就需要将标签内容同样转为浮点数
三、网络构建与说明
1.网络选择
利用Sequential类定义模型,层线性堆叠
对于输入数据为向量,标签为标量情况,适合采用带有relu激活的全连接层(Dense)的简单堆叠
最后一层以sigmoid作为激活函数,该函数可以将一个实数压缩至0到1之间,所以可以用来作为分类的概率
2.参数选择与说明
想要构建Dense层的堆叠,首先要解决两个关键的问题:
1.使用多少层
2.每层要选择多少个隐藏单元
一个隐藏单元是该层表示空间的一个维度,空间维度可以直观理解为“网络学习内部表示时所拥有的自由度”。
隐藏单元越多,网络越能学到更加复杂的表示,但网络的计算代价也会更大,而且可能导致容易过拟合。
本次实验直接依照下方代码进行架构,后续博客补充解释
每个带有relu激活的Dense层都实现了:
output = relu(dot(w, input) + b)
w为权重矩阵,b为偏置向量
w形状为(输入矩阵第1轴,隐藏单元个数)
b为向量,故需要通过广播实现形状不同的张量相加
激活函数用于扩展假设空间,充分利用多层表示的优势
3.损失函数与优化器选择
损失函数,衡量当前任务是否成功完成
对于二分类问题,最好使用 binary_crossentropy(二元交叉熵)损失
对于输出概率值的模型,交叉熵(crossentropy)往往是最好的选择
交叉熵是来自于信息论领域的概念,用于衡量概率分布之间的距离,在这个例子中就是真实分布与预测值之间的距离
优化器,决定如何基于损失函数对网络进行更新
对于当前问题,我们选择rmsprop优化器(均方根反向传播)
评价指标,用于判断模型的性能,但不用于网络参数的更新
对于当前问题,我们选择accuracy,即准确率,表示判定正确次数与所有判定次数的比例
四、图像绘制与分析
1.绘制训练损失与验证损失
2.绘制训练精度与验证精度
3.图像分析
本地图像与课本图像存在微小差异,原因是网络中参数随机初始化的值存在不同
训练损失逐轮降低,训练精度逐轮升高
验证损失与验证精度在第四轮达到最佳的效果
过拟合:对训练数据过度优化,最终学到的表示仅针对于训练数据,无法泛化到训练集之外的数据。
最简单的解决思路就是4轮之后停止训练
五、训练最终模型
1.运行代码展示
2.运行结果展示
六、代码
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from keras.datasets import imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(
num_words=10000)
#数据处理
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1.
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')
#构建网络
from keras import models
from keras import layers
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]
# partial_x_train = x_train[10000:]
# y_val = y_train[:10000]
# partial_y_train = y_train[10000:]
#
# model.compile(optimizer='rmsprop',
# loss='binary_crossentropy',
# metrics=['acc'])
# history = model.fit(partial_x_train,
# partial_y_train,
# epochs=20,
# batch_size=512,
# validation_data=(x_val, y_val))
#
# import matplotlib.pyplot as plt
# 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 = history_dict['acc']
# val_acc = history_dict['val_acc']
# plt.plot(epochs, acc, 'bo', label='Training acc')
# plt.plot(epochs, val_acc, 'b', label='Validation acc')
# plt.title('Training and validation accuracy')
# plt.xlabel('Epochs')
# plt.ylabel('Accuracy')
# plt.legend()
# plt.show()
#训练
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=4, batch_size=512)
results = model.evaluate(x_test, y_test)
print(results)