上一篇文章咱們介紹了深度學習的 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()