2021年9月23日 星期四

機器學習筆記 : 捲積神經網路 (CNN) 閱讀摘要

以下是最近看 "精通機器學習 (第二版)" 這本書第 14 章 CNN 的筆記 : 
  1. 為何人腦對於語音與圖片能如此輕鬆辨識? 答案是人類的知覺是在意識範圍之外發生的, 發生的地點是在大腦專門處理視覺, 聽覺或其他知覺的模組裡面. 當知覺意識到達我們的意識時, 它就已經具備高層次的特徵了. 你無法解釋你是如何認出那是一隻可愛的小狗. 
  2. 捲積神經網路 CNN 源自對人類大腦皮質的研究. CNN 不止能應用在視覺感知, 也能用在語音辨識與自然語言處理. 
  3. 1981 年諾貝爾生醫獎得主 David HobelTorsten Wiesel 在 1958 年開始對貓與猴子視覺皮層進行一系列實驗研究, 發現視覺皮層的許多神經元都有一個小型的局部感受區, 它們只會對視野內的有限區域做出反應. 這些神經元的感受區可能會重疊, 將它們合在一起就形成了整個視野. 此外他們還發現有些神經元只對水平線的圖像有反應, 有些只對不同方向的線條有反應. 而且有些神經元的感受區較大, 會對複雜的圖像做出反應. 他們從這些觀察得出一個看法 : 高層的神經元會使用相鄰的低層神經元的輸出. 這些研究成果催生了 1980 年代出現的新認知機 (neocognitron), 而這就是後來捲積神經網路 CNN 的濫觴. 
  4. Yann LeCun 等人在 1998 年發表的 LeNet-5 論文介紹了捲積層與池化層這兩個新元件, 這是機器學習很重要的里程碑. 
  5. 捲積 (convolution) 是將一個函數轉移到另一個函數的逐點乘法積分運算, 它與傅立葉變換以及拉普拉斯變換有很深的關係. CNN 的捲積層使用的其實只是跟捲積很類似交叉相關 (cross-correlation) 運算. 
  6.  為何不使用全連接的深度神經網路 (即 MLP 多層感知機) 來做圖像識別呢? 這對於 MNIST 之類的小圖片沒有問題, 但是對於大圖像卻因為需要大量參數而束手無策. 例如 100x100 的圖片有 1 萬個像素, 若第一層有 1000 個神經元, 則光是第一層就有 1000 萬個連接了. CNN 使用部分連接的階層以及權重共享 (即使用相同的捲積核) 來解決此問題. 
  7. CNN 最重要的部分就是捲積層, 第一個捲積層的神經元不會連接輸入圖像的每一個像素, 只會連接它們的感受區範圍內的像素. 同樣地, 第二個捲積層的各神經元也只連接第一層的一個小矩形內的神經元. 這種結構使網路的第一個隱藏層專注於低階的小特徵, 而在下一個隱藏層將它們組合成較大的高階特徵, 此與現實世界中人腦辨識圖像的階層式結構非常類似, 這就是為何 CNN 用於圖像辨識如此成功的原因.
  8. 多層感知器是由一長串神經元組成的階層, 但輸入圖像必須展平為 1D 才能傳入神經網路, 這樣就喪失了許多空間特徵. 但在 CNN 中, 各階層都是用 2D 表示的, 因此使神經元更容易與 2D 的輸入配對. 
  9. 神經元的權重可以用大小與感受區一樣的小圖示來表示, 稱為過濾器 (filter) 或捲積核 (convolution kernel). 讓所有神經元都使用同一種過濾器會輸出一張特徵圖 (feature map), 此特徵圖會凸顯圖像中最能觸發過濾器的區域. 過濾器不需要人工去定義 (但數量必須由我們決定), 在訓練過程中捲積層會自動學習對眼前的任務最實用的過濾器, 而捲積層上面的階層則會學習如何將它們組成更複雜的圖樣. 
  10. 只有第一個捲積層適合使用像 5x5 這麼大的捲積核 (步幅可用 2), 這樣可以降低圖像的空間維度, 但又不會損失太多資訊. 其他捲積層不要使用太大的捲積核, 使用 5x5 捲積核還不如用兩層 3x3 疊起來. 
  11. 每張特徵圖中的所有神經元都使用同一組參數 (即同一組權重與偏權值), 這樣可大幅降低模型得參數數量. 但不同張特徵圖使用不同組的參數, 捲積層會對其輸入套用多個可訓練的過濾器, 以便在輸入中到處偵測不同的特徵. CNN 與 DNN 的不同在於, 當 CNN 在一個地方學會辨識一個圖樣後就可在任何其他位置辨識它; 而 DNN 只能在它學會辨識的那個固定位置進行辨識. 
  12. 輸入圖像是由多個子階層 (sublayer) 組成, 每個顏色通道 (color channel) 為一個子階層, 一般使用 R, G, B 三原色各一個通道, 而灰階圖像則只有一個通道. 拍攝額外光頻譜的圖片 (例如衛星照片) 可能含有更多顏色通道, 例如紅外線等. 
  13. 在 TensorFlow 中每張輸入圖像的形狀 (shape) 都使用 [高, 寬, 通道] 的 3D 張量來表示, 而小批次訓練資料則使用 [小批次大小, 高, 寬, 通道] 的 4D 張量來表示. 捲積層的權重張量形狀為 4D 的 [fh, fw, fn', fn], 偏差項則是 1D 的 [fn]. 
  14. CNN 有一個問題是捲積層需要使用大量的 RAM (尤其是訓練期間), 因為在倒傳遞時需要使用順向傳遞時算出來的所有中間值, 雖然比起全連接層的恐怖數量來說, CNN 需要進行的浮點運算已經少了非常多, 但其計算量仍然要占用大量的記憶體, 特別是在訓練期間, 在順向傳遞過程中算出來的東西都必須保留下來給逆向傳遞時使用. 如果因為 RAM 不足導致訓練時系統崩潰, 可以嘗試下列方法 : 
    (1). 將小批次的大小降低
    (2). 透過增大步幅 (stride) 來降低維數
    (3). 移除部分階層
    (4). 將 32-bit 浮點數改成 16-bit 浮點數
    (5). 將 CNN 分散到多台電腦執行
  15. CNN 第二個元素池化層 (pooling layer) 主要的目的就是抽取輸入圖像的子樣本, 藉由縮小圖像來減低計算負擔與記憶體耗用量, 同時參數數量也降低了, 從而減少過擬 (over fitting) 的風險. 池化層的每個神經元都接到上一層有限數量的神經元輸出, 其結構與運作與捲積層類似, 同樣有一個小型的矩形感受區, 你必須決定它的大小, 步幅, 與填補方式. 但是池化層的神經元沒有權重 (池化核只是一個無狀態的滑動窗口), 它的工作只是使用 max(挑最大值) 或 mean(計算平均值) 等聚合函數來彙集感受區內的輸入. 採用 max 池化還有一個好處, 對於小幅度的平移對於輸出結果具有不變性 (invariance), 亦即池化核上下左右移動幾個像素對輸出結果影響不大, 但 max 池化的缺點是破壞性很強, 因為對於 2D 輸入而言它的輸出是輸入大小面積的 1/4. 
  16. max 池化的表現比 mean 池化通常要好, 因為 max 池化只保留了最強的特徵, 而捨棄所有沒有意義的特徵, 讓下一層有更明確的信號可以處理, 而且其平移不變性勝過 mean 池化, 所需的計算也比較少.
  17. 過濾器的數量離 CNN 輸出層越近就要越多, 因為低階特徵的數量通常很少, 但將它們組成高階特徵的方法有很多種. 我們通常會在經過每一個池化層後將過濾器的數量加倍, 因為池化層會將各個空間維度除以 2, 故可放心將下一層的特徵圖數量加倍, 不必擔心參數數量, 記憶體使用量, 與計算負擔會爆炸. 
  18. CNN 的後端是全連接網路, 由兩個隱藏稠密層與一個稠密輸出層組成, 要注意的是須將其輸入壓平, 因為稠密網路接收的是各個實例的 1D 特徵陣列. 另外為了降低過擬還要加入兩個 50% 卸除率的 Dropout 層. 
  19. 除了典型的 CNN 架構外, 歷年來 ILSVRC ImageNet 挑戰賽參賽贏家也提出了非常多的 CNN 變體結構, 將前五位錯誤率 (top-five error rate) 在六年內從 26% 降到 2.3%. 其中 2015 年冠軍得主 Kaiming He 等人提出的 Residual Network (ResNet) 較為特殊, 它使用具有跳接 (skip connection) 或短路連接 (shortcut connection) 結構的 152 層的 CNN 網路, 透過跳接連結, 傳給某階層的信號同時也會被加到高幾層的輸出, 即使有好幾層還沒開始學習, 信號仍能輕鬆跨過整個網路開始向前邁進, 使得訓練速度獲得大幅提升. 由於跳接是把輸入 x 同時也加到網路的輸出, 使得訓練神經網路的目標從模擬目標函數 h(x) 變成模擬目標函數與輸入的差 h(x)-x, 故這種學習被稱為殘差學習 (residual learning). ILSVRC 2017 挑戰賽冠軍架構 SENet 擴展了 GoggLeNet 的 inception 網路與 ResNet 網路, 加入一個稱為 SE block 的小型神經網路, 取得前五位錯誤率 2.25% 的驚人成就. 
  20. YOLO (You Only Look Once) 是 Josph Redmon 於 2015 年提出的一種非常快速與準確之物體偵測神經網路結構, 目前已升級至第三版 YOLOv3, 其速度快到可以即時處理視訊, 參見 Redmon 的展示網頁. YOLO 會為每個格子輸出 5 個外框, 每個外框都有一個 objectiveness 分數與 20 個類別機率, 所以每個格子共有 45 個數字 : 5 個外框, 每個有 4 個座標, 加上 5 個 objectiveness 分數與 20 個類別機率. 
  21. 除了常用的 2D 捲積層 keras.layers.Conv2D 外, TensorFlow 還提供了其他的捲積層 :
    (1). keras.layers.Conv1D : 給時間序列或文字輸入用的 1D 捲積層
    (2). keras.layers.Conv3D : 給 3D 圖像輸入 (例如 PET 掃描圖片) 用的捲積層
    (3). dilation_rate : 任何捲積層超參數 dilation_rate 設為 2 以上者
    (4). tf.nn.depthwise_conv2d : 建立深向 (depthwise) 捲積層用


"精通機器學習 (第二版)" 這本書的程式碼範例可在 GitHub 下載 :



下面是閱讀 "TensorFlow 自然語言處理" 第 5 章 "CNN 捲積神經網路|句子分類" 的摘要筆記 :
  1. CNN 神經網路主要由卷積層, 池化層, 全連接層構成, CNN 與單純的全連結神經網路不同, 它的卷積層具有更少的參數, 故不用擔心記憶體溢出問題, 它在圖片分類, 物體偵測, 語音辨識, 與句子分類等方面已達到最先進的表現. 
  2. 卷積層會用一個權重矩陣 (又稱為過濾器 filter) 滑過整個輸入矩陣, 透過卷積運算生成輸出結果. 卷積層與下一個舉積層之間可能會穿插池化層用來降低輸入的維度, 同時可讓 CNN 具有影像平移不變性, 且能迫使 CNN 在訊息比較少的情況下學習.
  3. CNN 網路後端通常會串接全連接層, 且全連接層的權重占了 CNN 參數的很大部分, 這是因為卷積層的參數很少的關係. 有用全連接層的 CNN 比沒有使用全連接層的模型表現好很多, 原因是卷積層尺寸較小, 學習到的多半是局部的特徵, 而全連結層則可提供關於這些局部特徵如何連結在一起的整體概念. 
  4. CNN 的結構設計在學習階段可保留輸入的空間訊息, 對二維資料來說在卷積與池化層仍保有二維特徵, 只有在後面串接全連接層時才會因為展平而被破壞. 
  5. 卷積層若採用較大的步幅就可以降低輸入的維度, 其效果與池化層類似, 所以有時也會用較大的步幅來進行卷積操作以取代 CNN 中的池化層以降低計算複雜度. 但較大的步幅會產生強烈的降維效果, 為了解決此問題, 會採用填充的方法, 將零填充到輸入的邊界, 這樣輸出的大小就會與輸入一樣. 
  6. 池化操作之所以被導入 CNN 主要是要用來降低中間輸出的大小 (降維), 並且使 CNN 具有平移不便特性. 池化的作法比不使用填充的卷積所造成的降維效果還要受歡迎, 因為我們可以決定在何處加入池化層來降維, 而不是被迫看著出現降維. 在未使用填充情況下的被迫降維會使 CNN 模型可擁有的層數受到極大限制. 
  7. 卷積層會學習圖片中的空間特徵, 較前面的卷積層學會較低層級的特徵, 例如圖片中不同方向的連線; 而比較後面的卷積層則會學習較高層級的特徵, 例如圖片中的形狀 (三角形, 圓形等), 或物體中教大的區塊 (狗臉, 尾巴, 車頭等). 中間的池化層會讓這些學習到的特徵具有平移不變性, 就算特徵出現的位置偏移, CNN 還是可以識別出該特徵. 最後全連結層會把 CNN 學習到的高階特徵組合起來, 以生成具有整體性的表達方式. 







沒有留言 :