提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
笔者权当做笔记,借鉴的是《Python 深度学习》这本书,里面的代码也都是书上的代码,用的是jupyter notebook 编写代码
提示:以下是本篇文章正文内容,下面案例可供参考
一、电影影评二分类问题
使用的是IMDM数据集,总共包含50 000条严重两极分化的评论。包含50%的正面评论和50%的负面评论;数据集分为25 000条训练数据和25 000条测试数据。IMDB数据集内置于Keras库,里面的评论都经过了预处理,转换成整数序列,其中每一个整数代表的是字典中的某个单词。
第一次加载IMDB数据集是先进行下载的,大约80MB。
二、步骤
1.导入Keras
import keras
2、加载IMDB数据集
from keras.datasets import imdb
import numpy as np
# num_words=10 000 限制的是前10 000个最常出现的单词
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
train_data[0] # 数据中都是整数序列
train_labels[0] # 标签0为负面,1为正面
# 由于我们限制为前10000个最常见的单词,所以单词索引都不会超过10 000
max([max(sequence) for sequence in train_data])
train_data.shape # 训练数据的形状显然是(25 000, )
# 将一条评论解码为英文单词
# 将单词映射为整数索引的字典(keys, values)
word_index = imdb.get_word_index()
# 键值颠倒,将整数索引映射为单词items是键值对
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
# 将评论解码,0 1 2 是为填充,所以要减去3
decoded_review = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
decoded_review
3.准备数据
我们不能将整数序列直接输入神经网络。需要将列表转换为张量。目前我们先用one-hot编码
one-hot编码是0和1组成的向量,指定索引的值为1其余都是0.
def vectorize_sequence(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension)) # 创建一个形状是sequences,dimension的零矩阵
for i, sequence in enumerate(sequences): # enumerate自动排索引
results[i, sequence] = 1. # 将i指定索引置为1(results矩阵相当于就是在第几个序列里面对应的单词置为1)
return results
x_train = vectorize_sequence(train_data) # 将训练数据向量化
x_test = vectorize_sequence(test_data) # 将测试数据向量化
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')
4、构建网络
from keras import models
from keras import layers
from keras import optimizers, losses, metrics
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'))
model.summary()
1、16个隐藏单元都要与权重w做点积,外加一个偏置向量b;所以第一层有160016个参数
2、下一层16个单元,上一层的输出是16,外加一个偏置向量b;所以这一层就是17 * 16 == 272个参数
3、输出层,输出是一个概率值,上一层输出是这一次的输入是16外加一个偏置向量b所以这一层是17个参数
# 编译模型
# loss='binary_crossentropy'是常用的二分类的交叉熵函数(二元交叉熵)
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
# 留出验证集
x_val = x_train[:10000] # 将数据切割,前1000个数据当成验证集
partial_x_train = x_train[10000:] # 后面的当成训练集
y_val = y_train[:10000]
partial_y_train = y_train[10000:]
# history会记录训练的过程
history = model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=512, validation_data=(x_val, y_val))
上述的history中记录了训练的损失值和准确率,验证的损失值和准确率
history_dict = history.history
history_dict.keys()
5、绘制图像
import matplotlib.pyplot as plt
loss_values = history_dict.get('loss')
val_loss_values = history_dict.get('val_loss')
epochs = range(1, len(loss_values) + 1)
# 绘制loss图像
plt.title('Training and validation loss')
plt.plot(epochs, loss_values, 'bo', label='Train loss')
plt.plot(epochs, val_loss_values, 'b', label='Validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
plt.clf() # 清空图像
acc = history_dict.get('accuracy')
val_acc = history_dict.get('val_accuracy')
# 绘制loss图像
plt.title('Training and validation accuracy')
plt.plot(epochs, acc, 'bo', label='Train accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
6、重新训练一个新的模型
我们会发现模型在训练数据上的表现越来越好,但是在测试集上却不是这样,这种叫做过拟合现象。过拟合好像在后面才会提到,这里书中用到了,观察到哪一步测试数据集上的loss不再降低。这里是到了第四轮,测试的数据集中的loss开始上升。所以我们可以把训练三轮。
# 重新训练一个新的模型
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'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=3, batch_size=512)
results = model.evaluate(x_test, y_test)
这种简单的方法得到了88%的精度
7、使用训练好的网络在新数据上生成预测结果
# 预测模型
model.predict(x_test)
输出的值都是概率值,或者说是确信度。
总结
这个是我单纯看书跟着敲的,权当作笔记了,后续还要继续学习。强推《Python 深度学习》🙂