【问题2】:电影评论分类(二分类)-----使用 keras工具用两层神经网络进行预测分析
1:本次实验的数据集是keras自带的数据集,这个数据集第一次导入的时候,会很慢。因为需要从外网下载数据。 如果下载中遇到困难,评论留邮箱,发数据。。 只需将我传给的数据放在keras的datasets文件夹底下,就OK了。。
2:我们首先看一下数据集,这个数据集50000条。 训练集25000,测试集25000。 每一条数据都已经将单词转换为对应的数字。 我们还需要将每条数据转换为对应的one_hot编码。。 因为如果你不转, 每个样本的长度不一,将不能进行训练。。
3:我们本次用的工具是keras,因为其构建网络比较方便。最后我们还画出了训练集和验证集的损失图,以及准确率图。 根据图像我们可以大概判断什么时候出现了过拟合。 这样有利于我们得出合适的epochs值。
下面是代码。 每步都有详细的解释。
from keras.datasets import imdb
import numpy as np
from keras import layers, models
import matplotlib.pyplot as plt
# num_words的意思是仅保留训练数据中前10000个常用词
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=10000)
# print(x_train[0]) # 第一条数据
# print(y_train[0]) # 第一条数据对应的标签
# # 将数字转化为对应的词
# word_index = imdb.get_word_index()
# reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
# decoded_review = ' '.join([reverse_word_index.get(i-3, '?') for i in x_train[0]]) # 测试一下,将第一个样本转换为文字
# print(decoded_review)
# 将每条数据转换为one_hot编码
def data2one_hot(seq, dimension=10000):
results = np.zeros((len(seq), dimension))
for num, s in enumerate(seq):
results[num, s] = 1.
return results
# 将特征数据转换为one_hot编码
x_train = data2one_hot(x_train)
x_test = data2one_hot(x_test)
# 将标签向量化
y_train = np.asarray(y_train).astype('float32')
y_test = np.asarray(y_test).astype('float32')
def get_model():
network = models.Sequential()
network.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
network.add(layers.Dense(16, activation='relu'))
network.add(layers.Dense(1, activation='sigmoid')) # 因为是二分类问题,所以此处采用sigmoid函数
network.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy']) # 监控精度
return network
x_val = x_train[:10000] # 验证集
x_train_ = x_train[10000:] # 训练集
y_val = y_train[:10000]
y_train_ = y_train[10000:]
# 获取模型并加以训练
model = get_model()
history = model.fit(x_train_, y_train_, epochs=5, batch_size=512, validation_data=(x_val, y_val))
history_dict = history.history
print(history_dict.keys()) # ['val_acc', 'loss', 'acc', 'val_loss' ]
fig, axs = plt.subplots(nrows=1, ncols=2)
ax = axs[0]
# 画出训练集和验证集的损失
loss_value = history_dict['loss']
val_loss_value = history_dict['val_loss']
epochs = range(1, len(loss_value)+1) # x轴
ax.plot(epochs, loss_value, 'bo', label='loss_value')
ax.plot(epochs, val_loss_value, 'b', label='val_loss_value')
ax.set_xlabel('Epochs')
ax.set_ylabel('Loss')
ax.set_title('Loss_value and Val_loss_value')
# 画准确率
ax = axs[1]
acc_train = history_dict['acc']
acc_val = history_dict['val_acc']
epochs = range(1, len(acc_train)+1) # x轴
ax.plot(epochs, acc_train, 'bx', label='acc_train')
ax.plot(epochs, acc_val, 'b', label='acc_val')
ax.set_xlabel('Epochs')
ax.set_ylabel('accuracy')
ax.set_title('acc_train and acc_val')
plt.show()
# 最后将模型epochs=3 取测试集上进行测试
# model = get_model()
# model.fit(x_train, y_train, epochs=3, batch_size=512)
# result = model.evaluate(x_test, y_test)
# print(result)
电脑性能好的小伙伴可以将epochs设置稍微大点。 可以明显看出在 epochs=3时已经出现了过拟合。所有我们将epochs值设为3更好。