上一篇文章咱们介绍了深度学习的 Hello World,代码写起来相比其余语言的 Hello World 有点多,且其背后的不少原理你可能尚未彻底弄懂,但从宏观上来看,总体的思想是很好理解的。接下包括本篇在内的三篇文章,咱们来用深度学习解决三个实际问题,也是很是经典的三个问题,分别是:python
- 二分类问题(电影评论的好坏偏向性判断)
- 多分类问题(将新闻按照主题分类)
- 回归问题(根据房地产数据估算房地产价格)
咱们解决这三个问题用到的训练模型为:数组
今天是第一篇,咱们关注他们其中比较简单的二分类问题,代码在最后。微信
实际背景是 IMDB(互联网电影资料库,你能够理解为国外的豆瓣)有大量的关于电影的评论,可是因为数据量的问题,很难去人工手动判断一条评定是对电影的夸奖仍是批评,这须要借助人工智能的帮助,根据用户评论的内容去判断用户的评论是积极的仍是消极的(为使问题简化,咱们取的数据是倾向性很明显的数据),数据集来自 IMDB,Numpy 数据格式:每个单词对应一个索引数字,这样每一条评论就能够对应一个索引数字的序列,组成一维数组,也是一个一维向量,这样的多个一维向量组成二维数组,就对应对条评论。网络
背景介绍完了,整个过程分为以下几步,同时思考几个问题:函数
咱们从图中能够看出,随着训练网络迭代的次数愈来愈多,训练精度愈来愈大,训练损失愈来愈小,这是咱们指望的;可是同时差很少在第四次迭代后,验证损失愈来愈大,验证精度愈来愈小,这就跟指望不相符了,这不科学,那这是为何?学习
这是由于因为迭代次数过多,出现了过拟合。测试
随着训练数据迭代次数过多,训练出的模型为了更好的拟合训练集的数据,致使一些参数设置的会过于绝对,出现了过拟合,这是咱们在训练网络中常常会遇到的问题,所以咱们认为在迭代四次是比较好的,相似于数学概念上的极值,更多更少的迭代次数都不够好,所以咱们将 fit 中的迭代次数改成 4,再次训练网络。ui
最后在另外的两万五千条测试集上进行验证,效果还能够,基本知足要求,问题获得解答。更多的细节已经写在了下面代码相关注释内容部分了,有兴趣请自行阅读。this
#!/usr/bin/env python3 import matplotlib.pyplot as plt import numpy as np from keras import layers from keras import models from keras.datasets import imdb # IMDB 数据集,分类一个评论是正面的仍是反面的 def comment(): # num_words = 10000 表明取前一万高频词,加入低频词数据量会过大且做用较小,暂不考虑 # 25000 条训练数据,25000 条测试数据 (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000) # 训练集被处理成整数数列,每条数据表示一条评论中单词出现的次数(如 good 出现次数是 5 次) # [1, 14, 22, ... 19, 178, 32] # print(train_data[0]) # 用 0 表明负面评论,1 表明正面评论 # print(train_labels[0]) # print(max([max(sequence) for sequence in train_data])) # 单词与索引对照表 # 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 train_data[0]]) # 将评论翻译成可读语言 # this film was just brilliant casting location scenery story direction everyone's really suited the part they # print(decoded_review) # one-hot 方法预处理数据为向量 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') # 构造网络 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.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc']) # model.compile(optimizer=optimizers.RMSprop(lr=0.001), loss='binary_crossentropy', metrics=['accuracy']) # model.compile(optimizer=optimizers.RMSprop(lr=0.001), loss=losses.binary_crossentropy, # metrics=[metrics.binary_accuracy]) # 因为这里有反馈,所以须要有必定的数据进行数据进行验证,这里取前一万个数据进行验证操做 x_val = x_train[:10000] partial_x_train = x_train[10000:] y_val = y_train[:10000] partial_y_train = y_train[10000:] # validation_data 用于传递验证数据 history = model.fit(partial_x_train, partial_y_train, epochs=4, batch_size=512, validation_data=(x_val, y_val)) # History 是训练过程当中的全部数据 history_dict = history.history print(history_dict.keys()) history_dict = history.history loss_values = history_dict['loss'] val_loss_values = history_dict['val_loss'] epochs = range(1, len(loss_values) + 1) plt.rcParams['font.sans-serif'] = ['SimHei'] plt.plot(epochs, loss_values, 'bo', label='训练损失') plt.plot(epochs, val_loss_values, 'b', label='验证损失') plt.title('训练和验证损失') plt.xlabel('迭代') plt.ylabel('损失') plt.legend() plt.show() plt.clf() acc = history_dict['acc'] val_acc = history_dict['val_acc'] plt.plot(epochs, acc, 'bo', label='训练精度') plt.plot(epochs, val_acc, 'b', label='验证精度') plt.title('训练和验证精度') plt.xlabel('迭代') plt.ylabel('精度') plt.legend() plt.show() results = model.evaluate(x_test, y_test) # [0.3329389461231232, 0.8639600276947021] print(results) # [[0.1754326], [0.9990357], [0.855113]...] print(model.predict(x_test)) def vectorize_sequences(sequences, dimension=10000): results = np.zeros((len(sequences), dimension)) for i, sequence in enumerate(sequences): results[i, sequence] = 1. return results if __name__ == "__main__": comment()