1. 總覽
在本實驗室中,您將瞭解如何將卷積層組裝成可辨識花朵的類神經網路模型。這次您將從頭開始自行建構模型,並運用 TPU 的強大功能在幾秒內完成訓練,然後反覆調整設計。
本實驗室包含卷積類神經網路的必要理論說明,是開發人員學習深度學習的良好起點。
本實驗室是「TPU 上的 Keras」系列實驗室的第 3 部分。你可以依下列順序執行這些步驟,也可以單獨執行。
- TPU 高速資料管道:tf.data.Dataset 和 TFRecords
- 建立第一個 Keras 模型 (採用遷移學習)
- [本實驗室] 卷積類神經網路 (搭配使用 Keras 和 TPU)
- 搭配使用 Keras 和 TPU,翻新 convnets、squeezenet 和 Xception 模型

課程內容
- 使用 Keras Sequential 模型建構卷積圖片分類器。
- 如要在 TPU 上訓練 Keras 模型
- 使用合適的捲積層微調模型。
意見回饋
如果您發現這個程式碼研究室有任何錯誤,請告訴我們。你可以透過 GitHub 問題 [意見回饋連結] 提供意見。
2. Google Colaboratory 快速入門
本實驗室使用 Google Colaboratory,您無須進行任何設定。Colaboratory 是線上筆記本平台,適用於教育用途。提供免費的 CPU、GPU 和 TPU 訓練。

您可以開啟這個範例筆記本,並執行幾個儲存格,熟悉 Colaboratory 的操作方式。
選取 TPU 後端

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

按一下儲存格並使用 Shift-ENTER,即可一次執行一個儲存格。您也可以依序選取「執行階段」>「全部執行」,執行整個筆記本。
Table of contents

所有筆記本都有目錄。你可以使用左側的黑色箭頭開啟這個選單。
隱藏的儲存格

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

只要使用已授權的帳戶進行驗證,Colab 就能存取您的私人 Google Cloud Storage bucket。上述程式碼片段會觸發驗證程序。
3. [INFO] 什麼是 Tensor Processing Unit (TPU)?
簡介

在 Keras 中於 TPU 上訓練模型的程式碼 (如果沒有 TPU,則改用 GPU 或 CPU):
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
我們今天將使用 TPU,以互動式速度 (每次訓練執行幾分鐘) 建構及最佳化花朵分類器。

為何選擇 TPU?
現代 GPU 是以可程式化的「核心」為基礎架構,這種架構非常靈活,可處理各種工作,例如 3D 算繪、深度學習、物理模擬等。另一方面,TPU 會將傳統向量處理器與專用矩陣乘法單元配對,並擅長處理大型矩陣乘法運算占主導地位的任何工作,例如類神經網路。

插圖:密集類神經網路層,以矩陣乘法表示,一次透過類神經網路處理一批八張圖片。請執行一行 x 欄的乘法,確認這確實是圖像所有像素值的加權總和。雖然有點複雜,但卷積層也可以表示為矩陣乘法 ( 請參閱第 1 節的說明)。
硬體
MXU 和 VPU
TPU v2 核心由矩陣乘法單元 (MXU) 和向量處理單元 (VPU) 組成,前者用於執行矩陣乘法,後者則用於執行所有其他工作,例如活化、softmax 等。VPU 會處理 float32 和 int32 運算。另一方面,MXU 則是以混合精度 16-32 位元浮點格式運作。

混合精確度浮點和 bfloat16
MXU 會使用 bfloat16 輸入和 float32 輸出計算矩陣乘法。中繼累計作業會以 float32 精確度執行。

類神經網路訓練通常能抵禦因浮點數精確度降低而產生的雜訊。在某些情況下,雜訊甚至有助於最佳化工具收斂。傳統上,16 位元浮點數精度用於加速運算,但 float16 和 float32 格式的範圍差異很大。將精確度從 float32 降為 float16 通常會導致溢位和下溢。雖然有解決方案,但通常需要額外作業才能讓 float16 正常運作。
因此,Google 在 TPU 中導入了 bfloat16 格式。bfloat16 是經過截斷的 float32,與 float32 的指數位元和範圍完全相同。此外,TPU 會以混合精度計算矩陣乘法,並使用 bfloat16 輸入,但輸出為 float32,因此通常不需要變更程式碼,就能享有精度降低帶來的效能提升。
Systolic array
MXU 會使用所謂的「脈動陣列」架構,在硬體中實作矩陣乘法,讓資料元素流經硬體運算單元陣列。(在醫學上,「收縮」是指心臟收縮和血流,這裡則是指資料流動。)
矩陣乘法的基本元素是兩個矩陣中,一個矩陣的列與另一個矩陣的欄之間的點積 (請參閱本節頂端的插圖)。以矩陣乘法 Y=X*W 來說,結果的一個元素會是:
Y[2,0] = X[2,0]*W[0,0] + X[2,1]*W[1,0] + X[2,2]*W[2,0] + ... + X[2,n]*W[n,0]
在 GPU 上,您可以將這個點積程式設計到 GPU「核心」,然後在盡可能多的「核心」上平行執行,嘗試一次計算結果矩陣的每個值。如果產生的矩陣為 128x128 大小,則需要 128x128=16K 個「核心」,這通常是不可能的。最大的 GPU 約有 4000 個核心。另一方面,TPU 會為 MXU 中的運算單元使用最少的硬體:只有 bfloat16 x bfloat16 => float32 乘法累加器,沒有其他元件。這些單元非常小,TPU 可以在 128x128 MXU 中實作 16K 個單元,並一次處理這個矩陣乘法。

插圖:MXU 脈動陣列。運算元素是乘法累加器。一個矩陣的值會載入陣列 (紅點)。其他矩陣的值會流經陣列 (灰色點)。垂直線會將值向上傳播。水平線會傳播部分總和。使用者可自行驗證,當資料流經陣列時,右側會輸出矩陣乘法運算的結果。
此外,在 MXU 中計算點積時,中間總和只會在相鄰的運算單元之間流動。這類值不需要儲存及從記憶體或暫存器檔案中擷取。因此,在計算矩陣乘法時,TPU 脈動陣列架構在密度和電力方面具有顯著優勢,且速度也比 GPU 快上不少。
Cloud TPU
在 Google Cloud Platform 上要求「Cloud TPU v2」時,您會取得具有 PCI 連接 TPU 板的虛擬機器 (VM)。TPU 板有四個雙核心 TPU 晶片。每個 TPU 核心都具備 VPU (向量處理單元) 和 128x128 MXU (矩陣乘法單元)。這個「Cloud TPU」通常會透過網路連線至要求該 TPU 的 VM。因此,完整圖片如下所示:

插圖:您的 VM,以及透過網路連結的「Cloud TPU」加速器。「Cloud TPU」本身是由 VM 和 PCI 連接的 TPU 板組成,板上則有四個雙核心 TPU 晶片。
TPU Pod
在 Google 的資料中心,TPU 會連線至高效能運算 (HPC) 互連,因此可視為一個非常大的加速器。Google 將這些節點稱為 Pod,最多可包含 512 個 TPU v2 核心或 2048 個 TPU v3 核心。

插圖:TPU v3 Pod。透過 HPC 互連網路連線的 TPU 板和機架。
在訓練期間,系統會使用 all-reduce 演算法在 TPU 核心之間交換梯度 ( 這裡有 all-reduce 的詳細說明)。訓練中的模型可透過訓練大量批次,充分運用硬體資源。

插圖:在 Google TPU 的 2D 環面網格 HPC 網路中,使用 all-reduce 演算法訓練期間的梯度同步。
軟體
大型批量訓練
TPU 的理想批量大小為每個 TPU 核心 128 個資料項目,但每個 TPU 核心 8 個資料項目時,硬體就能展現良好的使用率。請注意,一個 Cloud TPU 有 8 個核心。
在本程式碼研究室中,我們將使用 Keras API。在 Keras 中,您指定的批次是整個 TPU 的全域批量大小。系統會自動將批次分割為 8 個,並在 TPU 的 8 個核心上執行。

如需其他效能提示,請參閱 TPU 效能指南。如果批次大小非常大,部分模型可能需要特別注意,詳情請參閱 LARSOptimizer。
幕後花絮:XLA
Tensorflow 程式會定義運算圖形。TPU 不會直接執行 Python 程式碼,而是執行 TensorFlow 程式定義的運算圖。在幕後,名為 XLA (加速線性代數編譯器) 的編譯器會將運算節點的 Tensorflow 圖形轉換為 TPU 機器碼。這個編譯器也會對程式碼和記憶體配置執行許多進階最佳化作業。當工作傳送至 TPU 時,系統會自動進行編譯。您不必在建構鏈中明確加入 XLA。

圖解:如要在 TPU 上執行,Tensorflow 程式定義的運算圖會先轉換為 XLA (加速線性代數編譯器) 表示法,然後由 XLA 編譯為 TPU 機器碼。
在 Keras 中使用 TPU
Tensorflow 2.1 以上版本支援透過 Keras API 使用 TPU。Keras 支援 TPU 和 TPU Pod。以下範例適用於 TPU、GPU 和 CPU:
try: # detect TPUs
tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()
strategy = tf.distribute.TPUStrategy(tpu)
except ValueError: # detect GPUs
strategy = tf.distribute.MirroredStrategy() # for CPU/GPU or multi-GPU machines
# use TPUStrategy scope to define model
with strategy.scope():
model = tf.keras.Sequential( ... )
model.compile( ... )
# train model normally on a tf.data.Dataset
model.fit(training_dataset, epochs=EPOCHS, steps_per_epoch=...)
在這個程式碼片段中:
TPUClusterResolver().connect()會在網路上尋找 TPU。在大多數 Google Cloud 系統 (AI Platform 工作、Colaboratory、Kubeflow、透過「ctpu up」公用程式建立的深度學習 VM) 上,這項工具都能在沒有參數的情況下運作。這些系統會透過 TPU_NAME 環境變數得知 TPU 所在位置。如要手動建立 TPU,請在您使用的 VM 上設定 TPU_NAME 環境變數,或使用明確的參數呼叫TPUClusterResolver:TPUClusterResolver(tp_uname, zone, project)TPUStrategy是實作分配和「全縮減」梯度同步演算法的部分。- 這項策略是透過範圍套用。模型必須在策略範圍() 內定義。
tpu_model.fit函式預期會收到 tf.data.Dataset 物件,做為 TPU 訓練的輸入內容。
常見的 TPU 移植作業
- 雖然在 TensorFlow 模型中載入資料的方法有很多種,但使用 TPU 時,必須使用
tf.data.DatasetAPI。 - TPU 的速度非常快,因此在 TPU 上執行時,擷取資料通常會成為瓶頸。您可以使用 TPU 效能指南中的工具,偵測資料瓶頸和其他效能提示。
- 系統會將 int8 或 int16 數字視為 int32。TPU 沒有以少於 32 位元運作的整數硬體。
- 系統不支援部分 TensorFlow 作業。請參閱這份清單。好消息是,這項限制只適用於訓練程式碼,也就是透過模型的前向和後向傳遞。您仍可在資料輸入管道中使用所有 TensorFlow 作業,因為這些作業會在 CPU 上執行。
- TPU 不支援
tf.py_func。
4. [INFO] Neural network classifier 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, ... )

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

您可以將圖像的所有像素 RGB 值攤平成長向量,並做為輸入內容,饋送至這類網路。這並非圖像辨識的最佳技術,但我們之後會加以改良。
神經元、啟動、RELU
「神經元」會計算所有輸入的加權總和,加上稱為「偏差」的值,然後透過所謂的「活化函數」饋送結果。權重和偏差一開始是未知的。這些權重會隨機初始化,並透過大量已知資料訓練類神經網路「學習」。

最常用的活化函數稱為 RELU,也就是線性整流函數。如上圖所示,這項函式非常簡單。
Softmax 啟用
上述網路以 5 個神經元的層級結尾,因為我們要將花朵分類為 5 個類別 (玫瑰、鬱金香、蒲公英、雛菊、向日葵)。中間層的神經元會使用經典的 ReLU 活化函數啟動。不過,在最後一層中,我們想計算介於 0 和 1 之間的數字,代表這朵花是玫瑰、鬱金香等的機率。為此,我們會使用名為「softmax」的活化函數。
對向量套用 Softmax 時,會先計算每個元素的指數,然後將向量正規化,通常是使用 L1 範數 (絕對值總和),使值加總為 1,並可解讀為機率。

交叉熵損失
現在類神經網路會根據輸入圖片產生預測結果,我們需要測量預測結果的準確度,也就是網路提供的結果與正確答案 (通常稱為「標籤」) 之間的距離。請注意,資料集中的所有圖片都有正確標籤。
任何距離都適用,但對於分類問題,所謂的「交叉熵距離」最有效。我們將此稱為誤差或「損失」函式:

梯度下降法
「訓練」類神經網路實際上是指使用訓練圖片和標籤調整權重和偏誤,盡量減少交叉熵損失函式。運作方式如下:
交叉熵是權重、偏差、訓練圖片的像素及其已知類別的函式。
如果我們計算相對於所有權重和所有偏差的交叉熵偏導數,就會得到「梯度」,這是針對特定圖片、標籤,以及權重和偏差的現值計算而得。請注意,我們可能有數百萬個權重和偏差,因此計算梯度聽起來像是大量的工作。幸好,Tensorflow 會為我們執行這項作業。梯度的數學特性是「向上」指向。由於我們希望交叉熵較低,因此要朝相反方向移動。我們會根據梯度的一小部分更新權重和偏差值。接著,我們會在訓練迴圈中,使用下一批訓練圖片和標籤,重複執行相同的操作。希望這會收斂到交叉熵最小的位置,但無法保證這個最小值是唯一的。

小批次和動量
您可以在單一範例圖片上計算梯度,並立即更新權重和偏差,但如果對一批 (例如 128 張) 圖片執行這項操作,梯度就能更準確地呈現不同範例圖片施加的限制,因此更有可能更快收斂至解決方案。小批次的大小是可調整的參數。
這項技術有時稱為「隨機梯度下降」,還有另一項更實用的優點:處理批次資料也代表要處理較大的矩陣,而這類矩陣通常更容易在 GPU 和 TPU 上進行最佳化。
不過,收斂過程可能還是有點混亂,如果梯度向量全為零,甚至可能會停止。這是否表示我們已找到最小值?不一定。梯度分量在最小值或最大值時可為零。如果梯度向量有數百萬個元素,且全為零,則每個零都對應到最小值,且沒有任何一個對應到最大值的機率相當小。在多維空間中,鞍點相當常見,我們不希望停留在鞍點。

插圖:鞍點。梯度為 0,但並非所有方向的最小值。(圖片出處: Wikimedia:作者 Nicoguaro - Own work,CC BY 3.0)
解決方法是為最佳化演算法增加一些動量,讓演算法能順利通過鞍點,不會停滯不前。
詞彙
批次或小批:訓練一律會對訓練資料和標籤批次執行。這麼做有助於演算法收斂。「批次」維度通常是資料張量的第一個維度。舉例來說,形狀為 [100, 192, 192, 3] 的張量包含 100 張 192x192 像素的圖片,每個像素有三個值 (RGB)。
交叉熵損失:分類器常用的特殊損失函式。
稠密層:神經元層,其中每個神經元都會連結至前一層的所有神經元。
特徵:神經網路的輸入內容有時稱為「特徵」。找出要將資料集中的哪些部分 (或部分組合) 輸入類神經網路,才能獲得準確預測結果,這門技術稱為「特徵工程」。
標籤:監督式分類問題中的「類別」或正確答案的別名
學習率:在訓練迴圈的每次疊代中,權重和偏差值更新的梯度比例。
logits:在套用活化函數之前,神經元層的輸出內容稱為「logits」。這個詞彙源自「邏輯函數」,又稱「S 函數」,這是最常用的活化函數。「Neuron outputs before logistic function」縮短為「logits」。
損失:比較類神經網路輸出內容與正確答案的錯誤函式
神經元:計算輸入內容的加權總和、加入偏差,並透過活化函數提供結果。
One-hot 編碼:5 個類別中的第 3 個類別會編碼為 5 個元素的向量,除了第 3 個元素是 1 以外,其餘都是零。
relu:線性整流函數。神經元的熱門活化函數。
sigmoid:另一種曾廣受歡迎的活化函數,在特殊情況下仍有用處。
softmax:一種特殊活化函數,可作用於向量、增加最大元件與所有其他元件之間的差異,並將向量正規化為總和為 1,因此可解讀為機率向量。用做分類器的最後一個步驟。
張量:「張量」類似矩陣,但維度數量任意。1 維張量是向量。2 維張量是矩陣。然後,您就可以使用 3、4、5 個以上的維度張量。
5. [新資訊] 卷積類神經網路
簡介
如果下一段粗體字詞你都瞭解,即可直接進行下一個練習。如果您才剛開始接觸卷積類神經網路,請繼續閱讀。

插圖:使用兩個連續的濾鏡篩選圖片,每個濾鏡由 4x4x3=48 個可學習權重組成。
以下是 Keras 中簡單的卷積類神經網路:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=3, filters=24, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=6, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])

卷積類神經網路 101
在卷積網路的層中,一個「神經元」只會對上方一小塊圖像區域的像素進行加權總和。它會新增偏差值,並透過活化函數饋送總和,就像一般稠密層中的神經元一樣。然後使用相同權重,在整張圖片上重複執行這項作業。請注意,在密集層中,每個神經元都有自己的權重。在此,單一「權重修補程式」會以兩個方向滑過圖片 (即「捲積」)。輸出值數量與圖片中的像素數量相同 (但邊緣需要一些邊框間距)。這是篩選作業,使用 4x4x3=48 個權重的篩選器。
不過,48 個權重並不夠。如要增加自由度,請使用一組新的權重重複相同作業。系統會產生一組新的篩選器輸出內容。以輸入圖片中的 R、G、B 通道類比,我們將輸出內容稱為「通道」。

這兩組 (或更多組) 權重可以透過新增維度加總為一個張量。這會提供卷積層權重張量的通用形狀。由於輸入和輸出通道的數量是參數,我們可以開始堆疊和串連捲積層。

插圖:卷積類神經網路將資料「立方體」轉換為其他資料「立方體」。
步進卷積、最大池化
以 2 或 3 的步幅執行捲積時,我們也可以縮減結果資料方塊的水平維度。常見做法有兩種:
- 步進式卷積:滑動篩選器,但跨距 >1
- 最大集區化:套用 MAX 作業的滑動視窗 (通常在 2x2 修補程式上,每 2 像素重複一次)

插圖:將運算視窗滑動 3 像素,輸出值就會減少。步幅式捲積或最大集區化 (在步幅為 2 的 2x2 視窗上取最大值) 是縮減水平維度資料立方體的方法。
Convolutional classifier
最後,我們將最後一個資料立方體攤平,並透過密集、softmax 啟用的層饋送,附加分類標題。典型的捲積分類器可能如下所示:

插圖:使用捲積和 Softmax 層的圖片分類器。它使用 3x3 和 1x1 濾鏡。maxpool 層會取 2x2 資料點群組的最大值。分類標頭是透過具有 Softmax 啟動的稠密層實作。
在 Keras 中
上述的捲積堆疊可以寫成 Keras 程式碼,如下所示:
model = tf.keras.Sequential([
# input: images of size 192x192x3 pixels (the three stands for RGB channels)
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu', input_shape=[192, 192, 3]),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=32, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=32, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Conv2D(kernel_size=3, filters=16, padding='same', activation='relu'),
tf.keras.layers.Conv2D(kernel_size=1, filters=8, padding='same', activation='relu'),
tf.keras.layers.Flatten(),
# classifying into 5 categories
tf.keras.layers.Dense(5, activation='softmax')
])
model.compile(
optimizer='adam',
loss= 'categorical_crossentropy',
metrics=['accuracy'])
6. 您的自訂轉換網路
實作
讓我們從頭開始建構及訓練卷積類神經網路。使用 TPU 可讓我們快速疊代。請開啟下列筆記本、執行儲存格 (Shift-ENTER),並按照標示「WORK REQUIRED」的指示操作。
Keras_Flowers_TPU (playground).ipynb
目標是超越遷移學習模型 75% 的準確度。該模型已預先在數百萬張圖片的資料集上訓練,而我們這裡只有 3670 張圖片,因此該模型具有優勢。至少可以比照辦理嗎?
其他資訊
有幾層、多大?
選取圖層大小是藝術,而非科學。您必須在參數 (權重和偏差) 過少和過多之間取得適當平衡。如果權重太少,類神經網路就無法呈現花朵形狀的複雜性。如果特徵過多,模型就容易「過度配適」,也就是專門處理訓練圖片,但無法一般化。如果參數過多,模型訓練速度也會變慢。在 Keras 中,model.summary() 函式會顯示模型的結構和參數計數:
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 192, 192, 16) 448
_________________________________________________________________
conv2d_1 (Conv2D) (None, 192, 192, 30) 4350
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 96, 96, 30) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 96, 96, 60) 16260
_________________________________________________________________
...
_________________________________________________________________
global_average_pooling2d (Gl (None, 130) 0
_________________________________________________________________
dense (Dense) (None, 90) 11790
_________________________________________________________________
dense_1 (Dense) (None, 5) 455
=================================================================
Total params: 300,033
Trainable params: 300,033
Non-trainable params: 0
_________________________________________________________________
以下提供幾項訣竅:
- 多層結構是深層類神經網路發揮效用的關鍵。以這個簡單的花朵辨識問題為例,5 到 10 層就足夠。
- 使用小型篩選器。一般來說,3x3 濾鏡在任何地方都適用。
- 您也可以使用 1x1 濾鏡,價格便宜。它們並不會「篩選」任何內容,而是計算通道的線性組合。並以實際篩選器替換。(下一節會進一步說明「1x1 捲積」)。
- 對於這類分類問題,請使用最大集區層 (或步幅 >1 的捲積) 頻繁地進行下採樣。您不在意花朵的位置,只在意花朵是玫瑰還是蒲公英,因此遺失 x 和 y 資訊並不重要,且篩選較小的區域成本較低。
- 網路結尾的篩選器數量通常會與類別數量相近 (原因請見下方的「全域平均集區化」訣竅)。如果分類數達到數百個,請在連續層中逐步增加篩選器數量。以含有 5 個類別的花朵資料集為例,只使用 5 個篩選器是不夠的。您可以在大多數層中使用相同的篩選器數量 (例如 32 個),並在結尾減少篩選器數量。
- 最後的稠密層成本高昂。這類層的權重可能比所有捲積層加總的權重還多。舉例來說,即使最後一個資料立方體的輸出非常合理,只有 24x24x10 個資料點,100 個神經元的稠密層仍會耗費 24x24x10x100=576,000 個權重!請謹慎思考,或嘗試全域平均集區化 (見下文)。
全域平均池化
您不必在卷積類神經網路的結尾使用昂貴的稠密層,而是可以將傳入的資料「立方體」分割成與類別數量相同的多個部分、計算這些部分的平均值,然後透過 Softmax 活化函數饋送這些值。這種建構分類標題的方式不會產生權重費用。在 Keras 中,語法為 tf.keras.layers.GlobalAveragePooling2D().

解決方案
解決方案筆記本在此。如果遇到困難,可以參考這項工具。
Keras_Flowers_TPU (solution).ipynb
涵蓋內容
- 🤔 玩過卷積層
- 🤓 實驗過最大集區化、步幅、全域平均集區化等。
- 😀 在 TPU 上快速疊代實際模型
請花點時間在腦中瀏覽這份檢查清單。
7. 恭喜!
您已建構第一個現代卷積類神經網路,並透過 TPU 在短短幾分鐘內反覆運算其架構,將準確率提升至 80% 以上。請繼續下一個實驗室,瞭解現代的卷積架構:
- TPU 高速資料管道:tf.data.Dataset 和 TFRecords
- 建立第一個 Keras 模型 (採用遷移學習)
- [本實驗室] 卷積類神經網路 (搭配使用 Keras 和 TPU)
- 搭配使用 Keras 和 TPU,翻新 convnets、squeezenet 和 Xception 模型
TPU 實務
TPU 和 GPU 可在 Cloud AI Platform 上使用:
- 在 Deep Learning VM 上
- 在 AI 平台筆記本中
- 在 AI Platform Training 工作中
最後,我們非常重視意見回饋。如果您在本實驗室中發現任何錯誤,或認為有需要改進之處,請告訴我們。你可以透過 GitHub 問題 [意見回饋連結] 提供意見。

|

