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

用 Keras 玩 Machine Learning

用 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. 用 Keras 玩 Machine Learning
    SJ Chou
    [email protected]
    https://blog.toright.com

    View Slide

  2. Outline
    ● 機器學習到深度學習
    ● 認識 Keras
    ● 用 Keras 訓練 MNIST 手寫辨識 / IMDB Reviews
    ● 認識訓練參數 / 損失函數與優化器
    ● 認識卷積神經網路 (CNN)
    ● 少量資料訓練卷積神經網路

    View Slide

  3. 程式 與 機器學習 的差別
    傳統程式開發
    規則
    資料
    答案
    機器學習
    (監督式學習)
    答案
    資料
    規則
    程式設計的過程需要歸納出「規則」,進而轉化為程式
    碼。
    機器學習用來應付當「規則」無法透過程式來直接描述
    的情況下,可以透過大量的「資料」與「答案」來建立「規
    則」

    View Slide

  4. 類神經網路是什麼?
    類神經網路就像一個龐大的「多項
    式」,需要大量計算才能求得最佳解。
    如今類神經網路已經發展出非常多
    樣的網路模型,透過不同的神經元連
    接方式、資料處理方式、參數調整方
    式、收斂方式來建立 AI 模型,應付各
    種問題。

    View Slide

  5. 深度學習的基本概念
    深度學習的基本架構,透過不同的「網路層」
    連接方式,可以產生不同的 AI Model,解決
    不同的問題。
    層 (資料轉換)
    層 (資料轉換)
    預測值 Y’ 標準答案 Y
    損失函數
    損失分數
    優化器
    權重
    權重
    輸入資料 X

    View Slide

  6. ● 機率建模 (Probabilistic modeling)
    ○ 單純貝式分類器
    ○ 邏輯斯回歸 (Logistic Regression)
    ● Kernel Methods
    ○ SVM - 將資料投影到高維空間,進而尋找最佳決策邊界。難以用在大量的資料集,像是影像處理領域。屬於淺層工作法,
    其中「特徵工程」就變得相當重要。
    ● 決策樹、隨機森林、梯度提昇機器
    ○ 決策樹 (Decision tree)
    ○ 隨機森林 (Random Forest):集合大量決策樹組合輸出 值,在 2010 ~ 2014 廣授歡迎。
    ○ 梯度提昇機 (Gradient Boosting Machines, GBM):適合處理非感知資料,透過迭代訓練逐步提昇模型的弱點,也稱為弱預
    測模型。
    除了神經網路以外的機器「淺層學習」
    特徵工程 (Feature Engineering):為資料精心安排量好的表示法

    View Slide

  7. 為什麽現在「深度學習」高速發展?
    基於三個原因
    硬體設備提昇:GPU, CUDA 平行運算 (Nvidia)
    資料爆炸:伴隨網路發展,產生大量的資料、標記內容
    演算法:更好的啟動函數、更好的權重初始化方法、更好的最佳化方式

    View Slide

  8. 認識 Keras & Keras Features
    Keras 是一個開源專案,透過 Python 實做的深度學習高階 API 函式庫。採用 MIT License,主要作者維護者是
    Google 工程師 François Chollet。
    ● 相同的程式碼可以在 CPU 或 GPU 上執行
    ● 提供 API 快速建構神經網路雛型
    ● 內建函式庫支援卷神經網路、循環神經網路以及任何組合
    ● 可建構任何形式的深度學習模型,包含對抗神經網路、神經圖靈機
    ● 內建 Play Dataset,可以進行一些演算法的實驗

    View Slide

  9. Keras Programming Stack

    View Slide

  10. 深度學習的
    HelloWorld
    MNIST 手寫辨識

    View Slide

  11. 如何使用 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

    View Slide

  12. 如何使用 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

    View Slide

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

    View Slide

  14. 如何使用 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

    View Slide

  15. 如何使用 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 範例連結

    View Slide

  16. 如何使用 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 上升的情況。

    View Slide

  17. 如何使用 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 很快就在假設空間裡收斂。

    View Slide

  18. 換一個例子玩看看
    IMDB Reviews

    View Slide

  19. 換個資料集試試:IMDB Review Dataset
    訓練 Dataset:25,000
    測試 Dataset:25,000
    優化器:RMSprop
    損失函數:二元分類
    Batch Size:512
    Epochs:100
    這裡我們使用三層網路,全連接層僅使用兩層 16 個神
    經元的網路,啟動函數設定為 relu,連接最後使用一個
    神經元輸出(表示正評或負評),並使用 sigmoid 作為
    最後輸出的啟動函數。

    View Slide

  20. 換個資料集試試:IMDB Review Dataset
    透過圖表我們可以發現很早就已經發生 Over Fitting Demo Time
    CoLab 範例

    View Slide

  21. 原來算比較久不一
    定比較好 R~
    建議:透過訓練過程的監控,可以選擇某一個 Epoch,獲得表現最好的 Model

    View Slide

  22. 如何選擇 Keras 訓練參數?

    View Slide

  23. 損失函數與優化器:構成學習程序的關鍵
    神經網路架構很重要,網路架構形成假設空間,如果假設空間無法涵蓋最佳權重,任憑如何運算
    (fit) 效果也不會好!

    View Slide

  24. 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 已經提供許多實做完整的優化器與
    損失函數,讓我們可以針對問題進行不同參數的
    搭配訓練,透過數次的實驗找出最適合解決問題
    的模型架構。

    View Slide

  25. 如何選擇損失函數?
    二元分類問題:二元交叉熵 (Binary Crossentropy)
    只有兩類的分類問題
    多類別分類問題:分類交叉熵 (Categorical Crossentropy)
    超過兩類的分類問題,如文章分類
    回歸問題:均方差 (Meansquared Error)
    擅長處理連續性的資料,如預測天氣溫度、房價
    序列學習問題:連結時序分類 (Connectionist Temporal Classification, CTC)

    View Slide

  26. 損失函數如何選擇適合搭配的啟動函數
    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 的範圍

    View Slide

  27. 網路的神經元數量一定越多越好嗎?
    神經元表示維度空間,越多的神經元表示假設空間越大,自由度
    越高,相對的計算成本會更加昂貴。
    但維度太高有可能學習到不想要的 Pattern,造成 overfitting!

    View Slide

  28. 如何選擇參數與避免過度適配 (Over
    Fitting)
    ● 減少網路容量,避免神經元數量太多
    ● 更多訓練資料,避免訓練資料太少
    ● 神經元不得少於結果輸出的個數
    ● 使用權重常規化:避免較大的權重
    值主導整個模型
    ● 使用丟棄法:在 Layer 輸出加入雜訊,讓網路比較不會
    死記訓練資料

    View Slide

  29. 回顧
    可以調整參數有哪些? ● 神經網路架構
    ● 啟動函數
    ● 損失函數
    ● 優化器
    ● Epoch
    ● Batch Size

    View Slide

  30. 卷積神經網路
    CNN, Convolutional Neural Networks

    View Slide

  31. 卷積神經網路 (Convolutional Neural Networks)
    CNN 在影像辨識中發揮很大的成效,卷積層可以學習到影像中的特徵,比如形狀、紋理、顏色等等
    ...但卷積
    層的訓練是很耗費運算的一項工作~如果沒有大量的資料不容易訓練出優異的卷積層網路。
    卷積如何運算 https://gaussian37.github.io/dl-concept-cnn/
    Convolutional Neural Networks

    View Slide

  32. 資料集的組成 (調整參數與資訊洩漏)
    為什麽要分為「訓練、驗證、測試」三種資料集?
    由於在訓練模型的過程中,我們會不停的調整參數,好讓準確性提高
    (對於驗證資料集越來越高
    )。但是每一次調整都會
    將驗證資料集的資訊洩漏到模型中,如果沒有切割出乾淨的「測試資料」,就會在調整參數時被我們
    手動 Over Fitting。
    最終我們期望訓練出來的模型是可以預測「未來的資料」的,因此把測試資料分開是比較好的作法。
    訓練 驗證 測試 未來真正的預測資料

    View Slide

  33. CNN 需要大量的樣本,如果樣本資料不夠
    多的時候怎麼辦?
    K 折驗證:把所有樣本除了測試以外剩下的資料分成 K 群,每次都用不同的組合訓練 Model,最後取平均值作為評估的
    依據。
    訓練 驗證 測試
    訓練 驗證 測試
    訓練
    訓練
    驗證 測試
    訓練
    訓練
    驗證 測試
    訓練
    樣本足夠的情況

    View Slide

  34. 少量資料也能訓練
    卷積神經網路
    資料擴增法 (Data augmentation)
    預先訓練神經網路的特徵萃取法 (Feature extraction with a pertrained network)
    微調預先訓練神經網路法 (Fine-tuning a pretrained network)

    View Slide

  35. 方法一
    資料擴增法
    當訓練影像不足或取得困難時,我們可以透過對既有影像進
    行變化處理,藉此產生更多的影像數據送進 CNN 神經網路
    進行訓練。

    View Slide

  36. 資料擴增法 (Data augmentation)
    如果我們的訓練影像 Dataset 不足,可以透過資料擴增法增加樣本數量。實現方法為將原本的影像進行隨機縮放、旋
    轉、平移、翻轉等影像處理技巧,來創造更多的訓練樣本。
    以下使用 2,000 張貓狗照片樣本進行訓練,差不多在 5 Epoch 時就達到最小值,正
    確率約 0.7,少量資料造成 Over Fitting,效果不佳~

    View Slide

  37. 資料擴增法 - 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
    產生的樣本
    透過影像資料產生更多樣本

    View Slide

  38. 資料擴增法 - 效果
    將貓與狗的訓練樣本由 2,000 擴增為 3,200,並且在網路最後一層 Dropout 50%,可將正確率提昇至 0.85
    Demo Time
    CoLab 範例

    View Slide

  39. 方法二
    預先訓練神經網路的特徵萃取法
    我們知道 CNN 卷積層的訓練需要很多數據與運算資源,在
    資料集不足的情況下,從頭訓練卷積層不是一個聰明的方
    法。何不直接採用大神訓練好的卷積層,加速 AI Time to
    Market。

    View Slide

  40. 預先訓練神經網路的特徵萃取法
    (Feature extraction with a pertrained network)
    站在巨人的肩膀上,直接使用一些典型網路已經訓練好的 Convolutional Base 來擷取特徵,透過特徵重新訓練自己的
    Full Connection 分類網路。
    由於訓練 Convolutional Layer 成本是很高的,太少的樣本不足以訓練出具有特徵擷取意義的網路。
    Convolutional Base

    View Slide

  41. 什麼是 CNN 特徵!?
    由於卷積網路可以學習影像特徵,越接近 Input 的 Layer 所能
    理解的特徵越「普適」而且抽象,像是紋理、顏色等等。越後面
    的 Layer 所學習到的特徵越接近物體的描述,像是耳
    朵、眼睛
    等等。

    View Slide

  42. 預先訓練神經網路的特徵萃取法 - 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

    View Slide

  43. 預先訓練神經網路的特徵萃取法 - 抽取特徵
    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 抽取特徵

    View Slide

  44. 預先訓練神經網路的特徵萃取法 - 訓練
    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 範例

    View Slide

  45. 方法三
    微調預先訓練神經網路法
    使用已經訓練好的模型進行調整與重新訓練

    View Slide

  46. 微調預先訓練神經網路法
    (Fine-tuning a pretrained network)
    解凍 (Freeze) 一些卷積基底「頂部」的某些層用於特徵擷取,並對新加入的
    Full
    Connection Layer 進行聯合訓練。由於稍稍調整了原本 CNN 基底的表示法,所以
    叫做「微調」。
    解凍卷積基底
    新加入的 FC
    重新訓練
    採用預先訓練法大約 0.9 正確率,接下來解凍部份
    CNN 基底重新進行訓練。

    View Slide

  47. 微調預先訓練神經網路法
    (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)
    解凍

    View Slide

  48. 微調預先訓練神經網路法
    將 VGG16 CNN Base 部份 Layer 進行解凍,重新進行聯合學習,在這個案例可以提昇
    約 1% 左右的正確率,讓整體正確率到達 97%
    其實如果不解凍 CNN 也是會有不錯的效果,大約正確率是 96%
    Demo Time
    CoLab 範例

    View Slide

  49. The End
    2020/06/30
    SJ Chou
    [email protected]
    https://blog.toright.com

    View Slide