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

1. 總覽

在本研究室中,您將瞭解如何建構 Keras 分類器。我們不會嘗試找出最佳的類神經網路層組合來識別花朵,而是先使用稱為遷移學習的技術,將強大的預先訓練模型調整至我們的資料集。

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

本研究室是「Keras on TPU」的第 2 部分這是 Gemini 版 Google Workspace 系列課程之一您可以依照下列順序執行這些操作,也可以獨立執行。

ca8cc21f6838eccc.png

課程內容

  • 使用 softmax 層和交叉熵損失建立自己的 Keras 圖片分類器
  • 要趕上 😈?,請採用遷移學習技術,不要自行建構模型。

意見回饋

如果您在這個程式碼研究室中發現不尋常的狀況,請告訴我們。您可以透過 GitHub 問題提供意見 [feedback link]。

2. Google Colaboratory 快速入門

本研究室使用 Google 協作工具,因此您不需要進行任何設定。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 鍵,即可逐一執行儲存格。您也可以透過「執行階段 >」全部執行

Table of contents

429f106990037ec4.png

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

隱藏的儲存格

edc3dba45d26f12a.png

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

驗證

cdd4b41413100543.png

Colab 有機會存取您的私人 Google Cloud Storage 值區,但您必須使用已授權的帳戶進行驗證。上方的程式碼片段會觸發驗證程序。

3. [資訊] 類神經網路分類器 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,但並非在所有方向的最小值。(圖片出處 Wikimedia: by Nicoguaro - Own Work, CC BY 3.0)

解決方法是為最佳化演算法增加成長動能,讓演算法能在不停歇的加速點前進。

詞彙

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

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

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

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

labels:「類別」的另一個名稱或是更正監督式分類問題的答案

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

logits:套用活化函式前一層神經元層的輸出內容稱為「logits」。字詞取自「邏輯函式」a.k.a.「sigmoid 函式」這個模型過去是最常使用的活化函數,「Logistic 函式前方的遠端輸出」已縮短為「logits」。

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

neuron:計算輸入內容的加權總和、加上偏誤,並透過活化函式提供結果。

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

relu:固定線性單元。神經元經常使用的活化函數。

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

softmax:一種特殊的活化函數,用於向量、增加最大元件與所有其他元件之間的差異,並將向量正規化為 1 的總和,讓該向量被解為機率向量。做為分類器中的最後一個步驟。

tensor:Tensor就像矩陣,不過可以任意數量的維度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 後,您就能取得不含最終 softmax 層的預先訓練模型,以便新增自己的模型:

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 使用遷移學習的效果會更好。預先訓練的權重然後提供絕佳的初始值,而且也可以透過訓練進行調整,讓模型更準確地反映您的問題。

最後,請注意在稠密 softmax 層之前插入的 Flatten() 層。密集圖層適用於平面資料向量,但我們不知道預先訓練模型傳回的內容為何。這就是為什麼需要簡化。下一章我們將深入探討卷積架構,其中會說明卷積層傳回的資料格式。

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

解決方案

以下是解決方案筆記本。如果遇到問題,可以使用此功能。

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

涵蓋內容

  • 🤔? 如何在 Keras 中編寫分類器
  • 🤓? 上設定了「softmax」最後一層,且有交叉熵損失
  • 😈? 遷移學習
  • 🤔? 訓練第一個模型
  • 🧐? 瞭解訓練期間的損失和準確率

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

5. 恭喜!

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

TPU 實務

Cloud AI 平台提供 TPU 和 GPU:

最後,我們非常喜歡使用者的意見。如果您在研究室中發現任何錯誤,或認為需要改善,請告訴我們。您可以透過 GitHub 問題提供意見 [feedback link]。

HR.png

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

tensorflow logo.jpg
www.tensorflow.org