Upgrade to Pro — share decks privately, control downloads, hide ads and more …

用 Keras 玩 Machine Learning

SJ Chou
June 28, 2020

用 Keras 玩 Machine Learning

Keras 是一個開源專案,透過 Python 實做的深度學習高階 API 函式庫。透過 Keras 可以快速的進入 Machine Learning 領域,這份投影片提供了 Google Colab 相關程式範例,邊做邊學~

SJ Chou

June 28, 2020
Tweet

More Decks by SJ Chou

Other Decks in Technology

Transcript

  1. Outline • 機器學習到深度學習 • 認識 Keras • 用 Keras 訓練

    MNIST 手寫辨識 / IMDB Reviews • 認識訓練參數 / 損失函數與優化器 • 認識卷積神經網路 (CNN) • 少量資料訓練卷積神經網路
  2. 程式 與 機器學習 的差別 傳統程式開發 規則 資料 答案 機器學習 (監督式學習)

    答案 資料 規則 程式設計的過程需要歸納出「規則」,進而轉化為程式 碼。 機器學習用來應付當「規則」無法透過程式來直接描述 的情況下,可以透過大量的「資料」與「答案」來建立「規 則」
  3. • 機率建模 (Probabilistic modeling) ◦ 單純貝式分類器 ◦ 邏輯斯回歸 (Logistic Regression)

    • Kernel Methods ◦ SVM - 將資料投影到高維空間,進而尋找最佳決策邊界。難以用在大量的資料集,像是影像處理領域。屬於淺層工作法, 其中「特徵工程」就變得相當重要。 • 決策樹、隨機森林、梯度提昇機器 ◦ 決策樹 (Decision tree) ◦ 隨機森林 (Random Forest):集合大量決策樹組合輸出 值,在 2010 ~ 2014 廣授歡迎。 ◦ 梯度提昇機 (Gradient Boosting Machines, GBM):適合處理非感知資料,透過迭代訓練逐步提昇模型的弱點,也稱為弱預 測模型。 除了神經網路以外的機器「淺層學習」 特徵工程 (Feature Engineering):為資料精心安排量好的表示法
  4. 認識 Keras & Keras Features Keras 是一個開源專案,透過 Python 實做的深度學習高階 API

    函式庫。採用 MIT License,主要作者維護者是 Google 工程師 François Chollet。 • 相同的程式碼可以在 CPU 或 GPU 上執行 • 提供 API 快速建構神經網路雛型 • 內建函式庫支援卷神經網路、循環神經網路以及任何組合 • 可建構任何形式的深度學習模型,包含對抗神經網路、神經圖靈機 • 內建 Play Dataset,可以進行一些演算法的實驗
  5. 如何使用 Keras 訓練神經網路 - 建立網路 準備 MNIST 資料集 (7 萬張

    0~9 手寫圖片) 使用 Keras 建立網路 from keras.datasets import mnist (train_images, train_labels), (test_images, test_labels) = mnist.load_data() from keras import models from keras import layers network = models.Sequential() network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,))) network.add(layers.Dense(10, activation='softmax')) 層 (資料轉換) 層 (資料轉換) 預測值 Y’ 標準答案 Y 損失函數 損失分數 優化器 權重 權重 輸入資料 X
  6. 如何使用 Keras 訓練神經網路 - 設定網路與資料處理 準備「優化器、損失函數、評量準則」 network.compile(optimizer='rmsprop', # 優化器 loss='categorical_crossentropy',

    # 損失函數 metrics=['accuracy']) # 評量準則 處理資料格式 (正規劃) fix_train_images = train_images.reshape((60000, 28 * 28)).astype('float32') / 255 fix_test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255 from keras.utils import to_categorical fix_train_labels = to_categorical(train_labels) # [3,...] => [[0.,0.,0.,1.,...],...] fix_test_labels = to_categorical(test_labels) 層 (資料轉換) 層 (資料轉換) 預測值 Y’ 標準答案 Y 損失函數 損失分數 優化器 權重 權重 輸入資料 X
  7. 如何使用 Keras 訓練神經網路 - 訓練網路 訓練模型 network.fit(fix_train_images, # 輸入資料 X

    fix_train_labels, # 標準答案 Y epochs=5, # epochs 表示要跑幾次 batch_size=128) # batch 表示分批訓練的每一次訓練使用幾筆資料 層 (資料轉換) 層 (資料轉換) 預測值 Y’ 標準答案 Y 損失函數 損失分數 優化器 權重 權重 輸入資料 X
  8. 如何使用 Keras 訓練神經網路 - 測試網路 評估模型 test_loss, test_acc = network.evaluate(

    fix_test_images, # 輸入資料 X fix_test_labels) # 標準答案 Y print('test_loss:', test_loss) print('test_acc:', test_acc) 層 (資料轉換) 層 (資料轉換) 預測值 Y’ 標準答案 Y 損失函數 損失分數 優化器 權重 權重 輸入資料 X
  9. 如何使用 Keras 訓練神經網路 - 追蹤訓練 過程 network.fit(fix_train_images, # 輸入資料 X

    fix_train_labels, # 標準答案 Y epochs=20, # epochs 表示要跑幾次 batch_size=128, # batch 表示分批訓練的每一次訓練使用幾筆資料 validation_data=(fix_test_images, fix_test_labels)) # 每一次 epoch 結束後就拿測試資料來驗證 Demo Time CoLab 範例連結
  10. 如何使用 Keras 訓練神經網路 - 看圖分析 (loss) history_dict = result.history loss_values

    = history_dict['loss'] val_loss_values = history_dict['val_loss'] epochs = range(1, len(loss_values) + 1) import matplotlib.pyplot as plt plt.plot(epochs, loss_values, 'bo', label='Training loss') plt.plot(epochs, val_loss_values, 'b', label='Validation loss') plt.title('Training and validation loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend() plt.show() Validation loss 不一定會跟隨 Training loss 一起降低,當 Model Over Fitting Train Data 時,就會發生 Validation loss 上升的情況。
  11. 如何使用 Keras 訓練神經網路 - 看圖分析 (accuracy) plt.clf() acc = history_dict['accuracy']

    val_acc = 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('Accuracy') plt.legend() plt.show() 訓練的過程中 Accuracy 後期並有沒太大的變化, Model 很快就在假設空間裡收斂。
  12. 換個資料集試試:IMDB Review Dataset 訓練 Dataset:25,000 測試 Dataset:25,000 優化器:RMSprop 損失函數:二元分類 Batch

    Size:512 Epochs:100 這裡我們使用三層網路,全連接層僅使用兩層 16 個神 經元的網路,啟動函數設定為 relu,連接最後使用一個 神經元輸出(表示正評或負評),並使用 sigmoid 作為 最後輸出的啟動函數。
  13. Keras Optimizer and Losses Function • 優化器 Optimizer ◦ SGD

    ◦ RMSprop ◦ Adagrad ◦ Adadelta ◦ Adam ◦ Adamax ◦ Nadam • 損失函數 Losses ◦ mean_squared_error ◦ mean_absolute_error ◦ mean_absolute_percentage_error ◦ mean_squared_logarithmic_error ◦ squared_hinge ◦ hinge ◦ categorical_hinge ◦ logcosh ◦ categorical_crossentropy ◦ sparse_categorical_crossentropy ◦ binary_crossentropy ◦ kullback_leibler_divergence ◦ poisson ◦ cosine_proximity 由於 Keras 已經提供許多實做完整的優化器與 損失函數,讓我們可以針對問題進行不同參數的 搭配訓練,透過數次的實驗找出最適合解決問題 的模型架構。
  14. 如何選擇損失函數? 二元分類問題:二元交叉熵 (Binary Crossentropy) 只有兩類的分類問題 多類別分類問題:分類交叉熵 (Categorical Crossentropy) 超過兩類的分類問題,如文章分類 回歸問題:均方差

    (Meansquared Error) 擅長處理連續性的資料,如預測天氣溫度、房價 序列學習問題:連結時序分類 (Connectionist Temporal Classification, CTC)
  15. 損失函數如何選擇適合搭配的啟動函數 Problem type 問題類型 Last-layer activation 輸出層的啟動函數 Loss function 損失函數

    Binary classifiction 二元分類 sigmoid binary_crossentropy Multiclass, single-label classification 多分類 / 單選題 softmax categorical_crossentropy Multiclass, multilabel classification 多分類 / 多選題 sigmoid binary_crossentropy Regression to arbitrary values 回歸 (天氣/房價) / 任意值 None mse Regression to value between 0 and 1 回歸 / 可正規化 sigmoid mse or binary_crossentropy softmax:稱為歸一化函數,輸出 值的「總和 = 1」 sigmoid:稱為 S 型函數,輸出值介於 0~1 的範圍
  16. 如何選擇參數與避免過度適配 (Over Fitting) • 減少網路容量,避免神經元數量太多 • 更多訓練資料,避免訓練資料太少 • 神經元不得少於結果輸出的個數 •

    使用權重常規化:避免較大的權重 值主導整個模型 • 使用丟棄法:在 Layer 輸出加入雜訊,讓網路比較不會 死記訓練資料
  17. 資料擴增法 - Keras ImageDataGenerator ImageDataGenerator( rotation_range=40, # 隨機旋轉的角度 width_shift_range=0.2, #

    隨機水平平移的 % 比例 height_shift_range=0.2, # 隨機垂直平移的 % 比例 shear_range=0.2, # 隨機傾斜的角度 zoom_range=0.2, # 隨機縮放的比例 horizontal_flip=True, # 隨機左右翻轉 fill_mode='nearest') # 邊界像素填補,由於影像調 整後周圍會出現缺少的像素,設定 nearest 會以最接近的像素填補 四張透過 ImageDataGenerator 產生的樣本 透過影像資料產生更多樣本
  18. 預先訓練神經網路的特徵萃取法 (Feature extraction with a pertrained network) 站在巨人的肩膀上,直接使用一些典型網路已經訓練好的 Convolutional Base

    來擷取特徵,透過特徵重新訓練自己的 Full Connection 分類網路。 由於訓練 Convolutional Layer 成本是很高的,太少的樣本不足以訓練出具有特徵擷取意義的網路。 Convolutional Base
  19. 預先訓練神經網路的特徵萃取法 - VGG16 除了 VGG Keras 還有提供更多典型網路: # 載入 VGG

    網路 Convolutional Base from keras.applications import VGG16 conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150, 150, 3)) conv_base.summary() • DenseNet • NASNet • InceptionResNetV2 • ResNet 50 • Inception v3 • Xception • VGG16 • VGG19 • MobileNet • MobileNet V2
  20. 預先訓練神經網路的特徵萃取法 - 抽取特徵 def extract_features(directory, sample_count): features = np.zeros(shape=(sample_count, 4,

    4, 512)) labels = np.zeros(shape=(sample_count)) generator = datagen.flow_from_directory( directory, target_size=(150, 150), batch_size=batch_size, class_mode='binary') i = 0 for inputs_batch, labels_batch in generator: features_batch = conv_base.predict(inputs_batch) features[i * batch_size : (i + 1) * batch_size] = features_batch labels[i * batch_size : (i + 1) * batch_size] = labels_batch i += 1 if i * batch_size >= sample_count: break return features, labels 透過已經訓練好的卷積網路 來萃取特徵,這裡的程式將圖 片影像直接送入卷積網路,將 計算出的數值儲存起來,後續 會用來訓練分類網路。 要訓練的圖片先透過既有的 CNN 抽取特徵
  21. 預先訓練神經網路的特徵萃取法 - 訓練 from keras import models from keras import

    layers from keras import optimizers model = models.Sequential() model.add(layers.Dense( 256, activation= 'relu', input_dim= 4 * 4 * 512)) model.add(layers.Dropout( 0.5)) model.add(layers.Dense( 1, activation= 'sigmoid' )) model.compile(optimizer=optimizers.RMSprop(lr= 2e-5), loss= 'binary_crossentropy' , metrics=[ 'acc']) history = model.fit(train_features, train_labels, epochs= 30, batch_size= 20, validation_data=(validation_features, validation_labels)) 透過這樣的方法可以獲得將約 0.9 的正確性 ,效果比資料擴增法又好上一點。如果合併 兩種方法 (資料擴充 + 特增萃取),成本會高 一些,但是可以提升到 0.95 的正確性。 用特徵來訓練而不是圖片 Demo Time CoLab 範例
  22. 微調預先訓練神經網路法 (Fine-tuning a pretrained network) 解凍 (Freeze) 一些卷積基底「頂部」的某些層用於特徵擷取,並對新加入的 Full Connection

    Layer 進行聯合訓練。由於稍稍調整了原本 CNN 基底的表示法,所以 叫做「微調」。 解凍卷積基底 新加入的 FC 重新訓練 採用預先訓練法大約 0.9 正確率,接下來解凍部份 CNN 基底重新進行訓練。
  23. 微調預先訓練神經網路法 (Fine-tuning a pretrained network) conv_base.trainable = True for layer

    in conv_base.layers: if layer.name == 'block5_conv1' : layer.trainable = True # 解凍 CNN 基底 else: layer.trainable = False model.compile(loss='binary_crossentropy' , optimizer=optimizers.RMSprop(lr= 1e-5), # 低學習率 metrics=[ 'acc']) history = model.fit_generator( train_generator, steps_per_epoch= 100, epochs=100, validation_data=validation_generator, validation_steps= 50) 解凍
  24. 微調預先訓練神經網路法 將 VGG16 CNN Base 部份 Layer 進行解凍,重新進行聯合學習,在這個案例可以提昇 約 1%

    左右的正確率,讓整體正確率到達 97% 其實如果不解凍 CNN 也是會有不錯的效果,大約正確率是 96% Demo Time CoLab 範例