2019年2月20日 星期三

深度學習 - 模型的高級架構

Deep Learning 基礎的模型都已經大概了解了。然而在業界與學界,都正在快速的發展奠基在基礎之上的高級模型,讓學習的效率更高對任務的處理更精準。這邊要練習幾個已經發展的高級模型:
  1. batch normalization (批標準化)
  2. depthwise separable convolution (深度可分離卷積)
  3. model ensembling (模型集成)
  • Batch normalization (批標準化)
    我們知道 normalization 對處理資料的重要性,見先前的練習,也可看CS231課程
    ,在梯度下降法的過程中,因為同時有多個參數一起在function 中做梯度下降,而參數間的差異過大會導致梯度下降的過程中不是最直接的朝最低點方向做梯度下降,所以我們做normalization 來讓資料在資料空間中的分佈是較接近的(如下圖表示)。

    而批標準化又是什麼呢!?

    標準化的過程是將數據減去其平均值使其中心為0,然後將數據除以其標準差使其標準差為1,這種做法可以讓數據分佈的中心為0,同時縮放到均方差為1。

    了解標準化用意之後,就可以理解為何需要批標準化。

    在訓練過程中,資料經過神經網絡輸出後,不會再保有中心是0、均方差為1的特性,所以在每一層layer之後再做一次標準化的動作,有助於梯度下降法尋找最小 loss。

    此做法有助於梯度傳播(這一點和殘差連接很像)。對於有些特別深的網絡,只有包含多個BatchNormalization 層時才能進行訓練。例如,BatchNormalization 廣泛用於 Keras 內置的許多高級卷積神經網絡架構,比如 ResNet50、Inception-V3 和 Xception。

    BatchNormalization 層通常在卷積層或密集連接層之後使用。
    用先前MNIST_CNN 的模型來練習加入BatchNormalization :
    #建構CNN網絡
    from keras import layers
    from keras import models
    model = models.Sequential()
    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Dropout(0.5))  #加入dropout層,預防過擬合
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.Flatten())
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.Dense(10, activation='softmax'))

    Sergey Ioffe, Christian Szegedy "Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift. " 2015 paper.


  • Depthwise separable convolution (深度可分離卷積)
    簡單來說,Depthwise separable convolution就是一個可以替代 Conv2D,還可以讓模型更加輕量(即更少的可訓練權重參數)、速度更快(即更少的浮點數運算),還可以讓任務性能提高幾個百分點. 見作者Francois Chollet 的 Paper.
    隨後這個架構又被使用到MobileNet上,因為其輕量的特性,可以使深度學習模型在行動裝置上訓練簡單的辨識模型,從而讓行動裝置加入AI的可行性又更進一步了。

    讓我又再次驚嘆!! Google 實在是太神啦啦啦啦啦!!

    另外,想了解更多細節,有 Blogger 有寫 paper 的中文心得,可以更好的理解。
    1.Tommy Huang
    2.Cheng-Shiang Li

    將 Depthwise separable convolution加入模型中訓練看看,一樣用MNIST_CNN 的模型 來練習。
    #建構CNN網絡
    from keras import layers
    from keras import models
    model = models.Sequential()
    #使用SeparableConv2D 建構模型
    model.add(layers.SeparableConv2D(32, 3,activation='relu',input_shape=(28, 28, 1)))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.SeparableConv2D(64, 3, activation='relu'))
    model.add(layers.MaxPooling2D(2))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.SeparableConv2D(64, 3, activation='relu'))
    model.add(layers.MaxPooling2D(2))
    model.add(layers.Dropout(0.5))
    model.add(layers.Flatten())
    model.add(layers.Dense(64, activation='relu'))
    model.add(layers.BatchNormalization())  #加入BatchNormalization
    model.add(layers.Dense(10, activation='softmax'))

  • model ensembling (模型集成)
    模型集成就是利用多個模型所預測或分類的結果,取其加權平均。以分類問題為例:
    preds_a = model_a.predict(x_val)
    preds_b = model_b.predict(x_val)
    preds_c = model_c.predict(x_val)
    preds_d = model_d.predict(x_val)
    final_preds = 0.5 * preds_a + 0.25 * preds_b + 0.1 * preds_c + 0.15 * preds_d

    就好比瞎子摸象,每個人(模型)摸到的地方不同,如果摸到鼻子,會以為是蛇,如果要知道大象的全部,就需要集合每個人摸到的結果。

    在做模型集成時,每個集成的模型要竟可能的好,且模型之間越不同越好,才能學習到不同的特徵。要盡量避免使用複製同一個模型,然後只使用不同的隨機初始值,或是改變數據的輸入順序,這樣做只會有些微的改變,因為模型的多樣性(diversity)太低了。

    作者Francois Chollet 和 Andrei Kolev曾經使用多種樹模型和深度神經網絡的集成,在Kaggle
    Higgs Boson Machine Learning Challenge 競賽中獲得第四名。

沒有留言:

張貼留言