您的第一個 Keras 模型,支援遷移學習

1. 總覽

在本實驗室中,您將瞭解如何建構 Keras 分類器。我們不會嘗試找出神經網路層的完美組合,以便辨識花卉,而是會先使用名為遷移學習的技術,將強大的預先訓練模型套用至資料集。

本研究室包含有關類神經網路的必要理論解釋,也是開發人員學習深度學習的好起點。

本實驗室是「Keras 在 TPU 上運作」系列的第二部分。您可以按照下列順序或獨立執行這些操作。

ca8cc21f6838eccc.png

課程內容

  • 如何使用 softmax 層和交叉熵損失率,自行建構 Keras 圖像分類器
  • 如要作弊 😈,請使用遷移學習,而非自行建立模型。

意見回饋

如果您發現這個程式碼研究室有任何不妥之處,請告訴我們。您可以透過 GitHub 問題提供意見 [feedback link]。

2. Google Colaboratory 快速入門

這個實驗室使用 Google Collaboratory,您不需要進行任何設定。Colaboratory 是教育用的線上筆記本平台。提供免費的 CPU、GPU 和 TPU 訓練。

688858c21e3beff2.png

您可以開啟這個範例筆記本並執行多個儲存格,熟悉 Colaboratory。

c3df49e90e5a654f.png Welcome to Colab.ipynb

選取 TPU 後端

8832c6208c99687d.png

在 Colab 選單中,依序選取「執行階段」>「變更執行階段類型」,然後選取「TPU」。在本程式碼研究室中,您將使用支援硬體加速訓練的強大 TPU (Tensor Processing Unit)。首次執行時,系統會自動連線至執行階段。你也可以使用右上角的「連線」按鈕。

執行筆記本

76d05caa8b4db6da.png

按一下儲存格,然後使用 Shift + Enter 鍵,一次執行一個儲存格。您也可以依序點選「Runtime」>「Run all」執行整個筆記本

Table of contents

429f106990037ec4.png

所有筆記本都有目錄。您可以使用左側的黑色箭頭開啟報表。

隱藏的儲存格

edc3dba45d26f12a.png

部分儲存格只會顯示標題。這是 Colab 專屬的筆記本功能。您可以按兩下這些檔案,查看其中的程式碼,但通常不會有太多收穫。通常是支援或視覺化功能。您仍需要執行這些儲存格,才能定義其中的函式。

驗證

cdd4b41413100543.png

只要您使用授權帳戶進行驗證,Colab 就能存取您的私人 Google Cloud Storage 值區。上方的程式碼片段會觸發驗證程序。

3. [INFO] 類神經網路分類器 101

概述

如果您知道下個段落中的所有以粗體顯示的字詞,則可進行下一個練習。如果您是深度學習新手,歡迎繼續閱讀。

對於以一系列層建構的模型,Keras 提供 Sequential API。舉例來說,使用三個稠密層的圖片分類器,可在 Keras 中編寫如下:

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[192, 192, 3]),
    tf.keras.layers.Dense(500, activation="relu"),
    tf.keras.layers.Dense(50, activation="relu"),
    tf.keras.layers.Dense(5, activation='softmax') # classifying into 5 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

稠密類神經網路

這是用於分類圖片的最簡單類神經網路。由「神經元」層層排列的「神經元」組成。第一層會處理輸入資料,並將輸出內容饋送至其他層。之所以稱為「密集」,是因為每個神經元都會連結至前一層的所有神經元。

c21bae6dade487bc.png

您可以將圖片的所有像素 RGB 值扁平化為長向量,並將其用作輸入內容,藉此將圖片饋送至這類網路。這不是辨識圖片的最佳方法,但我們會在日後改善。

Neuron、啟動、RELU

「神經元」會計算所有輸入值的加權總和,並加入稱為「偏差」的值,然後透過稱為「活化函數」的函式提供結果。一開始不知道權重和偏誤。模型會以隨機方式初始化,並透過大量的已知資料訓練類神經網路,藉此「學習」。

644f4213a4ee70e5.png

最常見的活化函數稱為 RELU,用於直線式線性單位。如上圖所示,這是非常簡單的函式。

啟用 Softmax

由於我們將花分為 5 種類別 (玫瑰、鬱金香、蒲公英、雛菊、向日葵),上方的網路以 5 個神經元層為結尾。而中間層中的神經元是透過傳統版 RELU 活化函式啟用。但在上一層中,我們想要計算 0 到 1 之間的數字,代表這朵花成為玫瑰、鬱金香等的可能性。我們會使用名為「softmax」的活化函式。

在向量上套用 softmax 時,系統會採用每個元素的指數,然後對向量進行正規化,一般會使用 L1 常式 (絕對值總和),讓各個值加總為 1,並解讀為機率。

ef0d98c0952c262d.png d51252f75894479e.gif

交叉熵損失

神經網路已根據輸入圖片產生預測結果,我們需要評估這些結果的準確度,也就是網路的預測結果與正確答案之間的距離,通常稱為「標籤」。請記住,資料集中的所有圖片都有正確的標籤。

任何距離都可以,但就分類問題而言,所謂的「交叉熵距離」最有效。我們將這個函式稱為誤差或「損失」函式:

7bdf8753d20617fb.png

漸層下降

「訓練」神經網路其實是指使用訓練圖片和標籤調整權重和偏誤,以便盡量減少交叉熵損失函式。運作方式如下:

交叉熵是指權重、偏誤、訓練圖片像素及其已知類別的功能。

如果我們計算交叉熵相對於所有權重和偏誤的偏微分,就會取得「梯度」,這是針對特定圖片、標籤和權重和偏誤的現值計算而得。請記住,我們可以擁有數百萬個權重和偏誤,因此計算梯度聽起來好像是許多工作。幸好 TensorFlow 會自動執行這項操作。漸層的數學特性是指向「上方」。由於我們希望交叉熵偏低,因此我們會朝相反方向前進。我們會根據梯度的一部分更新權重和偏差。接著,我們會在訓練迴圈中使用下一批的訓練圖片和標籤,再次執行相同的操作。希望這個例子能創造出交叉熵,但不保證這個下限不會重複。

漸層 descent2.png

小批次和動量

只要只用一張範例圖片計算漸層效果,即可立即更新權重和偏誤,但以批次方式進行,例如,128 張圖片能夠產生較理想的漸層,更能充分代表不同範例圖片所施加的限制,因此可能更快地聚集在解決方案中。迷你批次的大小是可調整的參數。

這項技巧有時也稱為「隨機梯度下降」,還有另一個更顯著的優勢:使用批次處理也意味著使用較大的矩陣,而這類技術通常更容易對 GPU 和 TPU 進行最佳化。

然而,收斂法還是有點混亂,即使漸層向量全為零,甚至會停止。這代表我們已經找到最低限度了?不一定。漸層元件可在最小值或最大值上設為零。如果漸層向量含有數百萬個元素,且所有元素都是零,則每個零對應於最小值的機率,且沒有任何一個元素對應於最大值的機率相當低。而且在許多維度的空間中很常見,我們不想停下來。

52e824fe4716c4a0.png

插圖:馬鞍縫。漸層為 0,但並非在所有方向的最小值。(圖片出處 維基百科:由 Nicoguaro 提供 - 自己的作品,CC BY 3.0)

解決方法是為最佳化演算法增加成長動能,讓演算法不必停下腳步,順利滑行。

詞彙

batchmini-batch:一律對訓練資料和標籤進行訓練。這有助於演算法收斂。「batch」維度通常是資料張量的第一個維度。舉例來說,[100, 192, 192, 3] 的張量包含 100 張 192x192 像素和三個值 (RGB) 的 100 張圖片。

交叉熵損失:分類器中經常使用的特殊損失函式。

稠密層:神經元層,每個神經元都會連接至上一層的所有神經元。

特徵:神經網路的輸入內容有時稱為「特徵」。要準確判斷資料集的哪些部分 (或零件組合) 並提供給類神經網路以獲得準確的預測結果,就稱為「特徵工程」。

標籤:在監督式分類問題中,「類別」或正確答案的另一個名稱

學習率:在訓練迴圈的每個疊代中更新權重和偏誤的梯度比例。

logits:套用活化函式前一層神經元層的輸出內容稱為「logits」。這個詞源自「邏輯函式」(也稱為「S 函數」),這是過去最受歡迎的活化函式。「Logits 前方的 Neron outputs」會縮短為「logits」。

loss:比較神經網路輸出內容與正確答案的錯誤函式

神經元:計算輸入值的加權總和、加入偏差,並透過啟用函式提供結果。

one-hot 編碼:類別 3 之 3 會編碼為 5 個元素的向量,除了第三個 1 之外,其他所有零。

relu:固定線性單元。神經元常用的啟用函式。

sigmoid:過去廣受歡迎的活化函數,在特殊情況下仍可派上用場。

softmax:這是一種特殊的啟用函式,可作用於向量,增加最大元件與所有其他元件之間的差異,並將向量標準化,使其總和為 1,以便解讀為機率向量。用於分類器的最後一個步驟。

張量:「張量」就像矩陣,但有任意維度數量。1 維度張量是向量。2 維度張量就是矩陣。接著,就能使用有 3、4、5 或更多維度的張量。

4. 遷移學習

對於圖像分類問題,密集層可能不夠。我們必須瞭解卷積層,以及它們的多種排列方式。

但我們也提供捷徑!有經過完整訓練的捲積類神經網路可供下載。可以切斷最後一個層 (softmax 分類頭) 再自行取代。所有經過訓練的權重和偏差都會維持原樣,您只需重新訓練新增的 softmax 層。這種技術稱為「遷移學習」,但只要用在類神經網路經過預先訓練的資料集「夠近」的程度,這種技術就能發揮效用。

實作課程

請開啟下列筆記本,執行儲存格 (Shift-ENTER),然後按照指示操作,即可看到「已完成工作」標籤。

c3df49e90e5a654f.png Keras Flowers transfer learning (playground).ipynb

其他資訊

透過遷移學習,您可以同時享有頂尖研究人員開發的進階卷積類神經網路架構,以及大量圖片資料集的預先訓練。在這個案例中,我們要從在 ImageNet 上訓練的網路中遷移學習過程。ImageNet 是一種圖片資料庫,內含許多植物和室外場景的圖片,而這些圖像就足以讓花朵使用。

b8fc1efd2001f072.png

示例:使用已訓練的複雜卷積類神經網路做為黑箱,只重新訓練分類頭。這就是遷移學習。我們稍後會說明這些複雜的卷積層排列方式如何運作。目前這是其他人的問題。

在 Keras 中遷移學習

在 Keras 中,您可以從 tf.keras.applications.* 集合將預先訓練模型執行個體化。舉例來說,MobileNet V2 就是一個很好的捲積架構,在大小合理範圍內。選取 include_top=False 後,您會取得預先訓練模型,但沒有最終的軟性最大值層,因此您可以自行新增:

pretrained_model = tf.keras.applications.MobileNetV2(input_shape=[*IMAGE_SIZE, 3], include_top=False)
pretrained_model.trainable = False

model = tf.keras.Sequential([
    pretrained_model,
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(5, activation='softmax')
])

請注意 pretrained_model.trainable = False 設定。會凍結預先訓練模型的權重和偏誤,因此您只能訓練 softmax 層。這類問題通常只涉及相對少的權重,可以快速完成,也不需要非常龐大的資料集。不過,如果您有大量資料,轉移學習搭配 pretrained_model.trainable = True 使用,效果會更好。預先訓練的權重會提供優異的初始值,而且仍可透過訓練調整,以便更符合您的問題。

最後,請注意在密集軟性最大值層前插入的 Flatten() 層。密集圖層適用於平面資料向量,但我們不知道預先訓練模型傳回的內容為何。因此我們需要進行平坦化處理。下一章我們將深入探討卷積架構,其中會說明卷積層傳回的資料格式。

採用這種做法可將準確率提高近 75%。

解決方案

以下是解決方案筆記本。如有需要,您可以使用這項功能。

c3df49e90e5a654f.png Keras Flowers transfer learning (solution).ipynb

涵蓋內容

  • 🤔 如何使用 Keras 編寫分類器
  • 🤓 使用 softmax 最後一層和交叉熵損失函數進行設定
  • 😈 遷移學習
  • 🤔 訓練第一個模型
  • 🧐? 瞭解訓練期間的損失和準確率

請花點時間研讀這份檢查清單,

5. 恭喜!

您現在可以建構 Keras 模型。請繼續進行下一個實驗室,瞭解如何組合卷積層。

TPU 實務

Cloud AI 平台提供 TPU 和 GPU:

最後,我們非常歡迎您提供意見回饋。如果您在這個研究室中發現任何錯誤,或您認為需要改善,請告訴我們。您可以透過 GitHub 問題提供意見 [意見回饋連結]。

HR.png

Martin Görner ID small.jpg
作者:Martin Görner
Twitter:@martin_gorner

tensorflow logo.jpg
www.tensorflow.org