3C科技 娛樂遊戲 美食旅遊 時尚美妝 親子育兒 生活休閒 金融理財 健康運動 寰宇綜合

Zi 字媒體

2017-07-25T20:27:27+00:00
加入好友
Keras 教學 - 利用二元分類器訓練 IMDB 深度學習演算法 前一篇文章介紹了機器學習最基本的 Hello World = MNIST 模型訓練。今天換一個 IMDB Reviews 的 Play Data 例子玩看看,對於如何透過 Keras 訓練神經網路的基本概念,可以參考前一篇「Keras MNIST 手寫辨識 x 深度學習的 HelloWorld」文章介紹。 二元分類或稱兩類分類可能是在機器學習中應用最廣泛問題。只要處理的問題只有兩個結果,就可以適用。在這個例子中,我們將根據 IMDB 評論的文本內容將電影評論分為「正面」評論和「負面」評論。 關於 IMDB Dataset 資料集 IMDB Dataset 是來自 Internet 電影數據庫 50,000 條評論文字。他們分為 25,000 條訓練數據和 25,000 條測試數據,每組皆包含包括 50% 的負面評論和 50% 的正面評論。 我們可以直接透過 Keras Datasets 函式庫載入已經整理好的資料集。這些資料集已經經過處理,會將評論依據單詞順序,排列為整數序列,其中每個整數代表字典中的特定單詞。如下: 1 2 from keras.datasets import imdb (train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000) num_words=10000 表示我們只採用前 10000 個常出現的字詞,此外在 label 中 0 表示負評 1 表示正評。 1 max([max(sequence) for sequence in train_data]) 也可以透過字典檔,將資料組合回評論文字。 1 2 3 4 5 6 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]])   # show decoded_review IMDB Reviews 資料前處理 我們無法將代表字典檔索引位置的整數資料直接送進網路進行訓練,因此需要對資料進行轉換。由於我們只採用前 10000 常用字詞作為資料集,因此輸入資料可以轉換為 10000 維度的 one-hot-encode,例如 [3, 18] 表示一個全部都是 0 的陣列,只有 index 3, 18 是 1。我們會將這樣的資料格式作為張量進行訓練,轉換如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as np   def vectorize_sequences(sequences, dimension=10000):     # Create an all-zero matrix of shape (len(sequences), dimension)     results = np.zeros((len(sequences), dimension))     for i, sequence in enumerate(sequences):         results[i, sequence] = 1.  # set specific indices of results[i] to 1s     return results   # Our vectorized training data x_train = vectorize_sequences(train_data) # Our vectorized test data x_test = vectorize_sequences(test_data) 將結果標記進行正規化 1 2 3 # Our vectorized labels y_train = np.asarray(train_labels).astype('float32') y_test = np.asarray(test_labels).astype('float32') 建立 CNN 網路架構 這裡我們預計使用三層網路,全連接層僅使用兩層 16 個神經元的網路,啟動函數設定為 relu,連接最後使用一個神經元輸出(表示正評或負評),並使用 sigmoid 作為最後輸出的啟動函數。由下而上網路架構如下: 預計採用的 CNN 詳細定義如下: 訓練 Dataset:25,000 測試 Dataset:25,000 優化器:RMSprop 損失函數:二元分類 Batch Size:512 Epochs:100 1 2 3 4 5 6 7 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')) 將優化器設定為 rmsprop,損失函數使用 binary_crossentropy,將網路進行 Compile 1 2 3 model.compile(optimizer='rmsprop',               loss='binary_crossentropy',               metrics=['accuracy']) 訓練 CNN 模型 先將準備訓練的 25000 筆資料集,抽出 10000 筆資料集用在訓練時期的驗證資料,好讓我們監控訓練過程的準確性變化。如下: 1 2 3 4 5 x_val = x_train[:10000] partial_x_train = x_train[10000:]   y_val = y_train[:10000] partial_y_train = y_train[10000:] 開始訓練模型 1 2 3 4 5 history = model.fit(partial_x_train,                     partial_y_train,                     epochs=100,                     batch_size=512,                     validation_data=(x_val, y_val)) 如果是是透過 Colab 的 GPU 進行訓練,每一個 Epoch 差不多 3 秒多一點,訓練結果如下: 訓練的過程會把相關資訊存放在 history,透過事後分析訓練過程的資訊可以幫助我們優化參數。 1 2 history_dict = history.history history_dict.keys() 訓練結果圖表分析 透過上面的方法可以取得訓練 History 包含的資訊,然後我們將資訊繪製成為圖表,首先觀察 loss 變化,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #@title import matplotlib.pyplot as plt   acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss']   epochs = range(1, len(acc) + 1)   # "bo" is for "blue dot" plt.plot(epochs, loss, 'bo', label='Training loss') # b is for "solid blue line" plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend()   plt.show() 執行結果: 接著透過以下程式產生圖表來觀察正確率的變化: 1 2 3 4 5 6 7 8 9 10 11 12 plt.clf()   # clear figure acc_values = history_dict['accuracy'] val_acc_values = history_dict['val_accuracy']   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('Loss') plt.legend()   plt.show() 執行結果: 由上面的數據可以看出來,以現在的網路架構,其實在第 3 次 Epoch 就已經獲得最佳的結果,之後的訓練已經造成過度擬合 (Over Fitting),因此在這個案例中將 Epoch 設定為 3 或 4 是取得最佳訓練模型的方法。今天的範例程式可以在 GitHub 取得 ipynb 檔案,需要請自行下載。 原來算比較久不一定比較好 R~實務上,建議透過訓練過程的監控,可以選擇某一個 Epoch 獲得表現最好的 Model 作為最佳解。此外,模型的參數也是很重要的,下一篇文章我們就來介紹一下各種參數的使用情境,敬請期待....... 分享到 Twitter(在新視窗中開啟) 按一下以分享至 Facebook(在新視窗中開啟) 分享到 LinkedIn(在新視窗中開啟) 點這裡寄給朋友(在新視窗中開啟) 按一下即可分享至 Skype(在新視窗中開啟) 分享到 Reddit(在新視窗中開啟) 分享到 Tumblr(在新視窗中開啟) 按一下以分享到 Telegram(在新視窗中開啟)

本文由toright提供 原文連結

寫了 5860316篇文章,獲得 23313次喜歡
精彩推薦