今天開始進入應用篇。在介紹 CNN 之前,先來看一段日本五專學生利用圖像分類做的獲獎作品,透過分辨魚的種類自動將魚分裝,大幅減少漁夫作業時間。評審員給出有五億日圓商業價值的高評價,構成簡單且快速,相當具有實用性。
ーー影片出處:第一回高等専門学校深度學習競賽
那麼這個魚種分類是怎麼做到的,就是今天要介紹的 CNN。
卷積神經網路 (CNN,Convolutional Neural Network)算是深度學習領域裡面最熱門的研究範疇,主要是用來做電腦視覺(Computer Vision,CV)。一門讓電腦學習「看」的科學。
既然是看的科學,電腦能夠識別的資料就是圖片。
圖片的資料構成除了尺寸的高度(H)和寬度(W),還有一個深度叫通道(Channel),彩色的話會有3個通道也就是紅綠藍(RGB)三色疊起來的顏色數值,每一格我們稱作像素(Pixel)。這個就是輸入層的資料數目:H × W × C。
如果是黑白圖片(Gray Scale,灰度圖)就只會有一個 Channel。
CNN 的核心思想是,提取圖片局部的重要特徵來做判別,畢竟圖片和文字不同,資料量非常龐大。舉個例子,一張1024×1024×3的 RGB 圖片大約是314萬個神經元,如果直接拿整張圖片做學習恐怕非常沒有效率且不太可行。
最早起源是由福島邦彥提出的 Neocognitron(1980年),主要是模仿兩個負責人類視野的神經細胞,因此給了 Yann LeCun 靈感產生了 LeNet(1998年)這個 CNN 最早的基本模型。
Neocognitron | LeNet | 功用 |
---|---|---|
S細胞 | 卷積層 | 提取局部特徵 |
C細胞 | 池化層 | 從局部特徵濃縮成重要特徵 |
add-if silent | 反向傳播 |
學習(訓練) |
我們可以從列表看到兩者其實構成差不多,最大的差異在於1980年時還沒有反向傳播(Backpropagation),導致了學習性能上的落差。
打到這一篇的時候特地回到 Day2 確認了一下 AI 時間軸,反向傳播是1986年才出現,有時候真的是諸多條件滿足了才有辦法做技術上的突破。
而 CNN 的基本架構就是在神經網路之前加上卷積層和池化層先提取局部重要特徵。
藉由濾鏡(filter,或叫 kernel ) 的滑動掃完整個輸入提取局部特徵產生特徵地圖(Feature Map)。
—— 圖片 * 濾鏡 = 特徵地圖,出處:Convolutional Neural Network
特徵地圖就是濾鏡的數字和圖片重疊的區域數字相乘做加總。
那濾鏡怎麼提取特徵呢?
以數字的7為例,很明顯的特徵是上方有一個水平線,中間有個斜線,下方有個直線,
所以我們可以用3個濾鏡來提取這些特徵,符合特徵的區域數字會被放大。
步幅(Stride)
上面動畫的濾鏡每次滑動一格叫 1 stride,如果一次移動兩格就叫 2 stride。主要是用來縮放特徵地圖的大小,stride 越大特徵地圖越小。
填充(Padding)
像7的水平線在最上面的邊界處,我們設的水平線是在中間,這樣無法抓到水平線特徵,這時可以靠填充將邊界外面一圈都填0,讓濾鏡可以超出邊界來擷取特徵。
有時候為了讓特徵地圖的尺寸和原本的圖像一樣也會先用填充來擴大尺寸。
這邊有兩個公式方便我們計算出步幅或是特徵地圖大小:
透過步幅算出特徵地圖的大小
※ input,output,filter 取其高度或寬度的數值
以上圖數字7為例用 stride = 1 求 特徵地圖大小:
Output = (8+0×2-3)/1 + 1 = 6(特徵地圖為6×6大小)
針對想要的特徵地圖大小算出需要多大步幅
以上圖數字7為例反過來求 6×6 特徵地圖的Stride:
Stride = (8+0×2-3)/(6-1) = 1
縮小尺寸,也就是降低取樣(downsampling)。從特徵地圖只提取主要的特徵來降低參數,可以避免過度擬合,同時減少圖像尺寸進而降低所需的計算處理。
方法有兩個:
最大池化(Max Pooling)
局部區域取最大值來當作該區的代表。比如說 2×2 局部區域:
平均池化(Average Pooling)
局部區域取平均值來當作該區的代表。
兩者差別在於要凸顯出最顯著特徵用最大池化,但相對的丟失的訊息比較多,反之提取較完整的局部特徵用平均池化。通常用最大池化比較多,池化層單純做運算後面沒有激勵函數。
另外透過池化層還可以取得特徵不變的特性。
透過這個範例可以很直觀的看出池化層的作用。也就是圖片被池化層縮小了也看得出特徵。
原圖打洞 | 擷取下來拼湊的圖 |
---|---|
ーー出處:Youtube - Pooling Layer ? |
連接到輸出做分類。
全連接層的輸入是一維感知器,所以要接續全連接層之前,需先將上一層的輸出做拉平(flatten)成為一維。
如同其他的神經網路一樣,CNN 也是把一連串的隱藏層疊起來做深度的處理。
CONV-POOL 重複做 N 回後接 FC 做 M 回,最後在輸出前用 Softmax 轉成想要分類的個數。
INPUT-(CONV-POOL)×N-FC×M
-SOFTMAX-OUTPUT
※ 記得 POOL 因為是做運算,沒有激勵函數。而接 FC 之前要先用 flatten 轉回一維。
這邊可以看一下 LeNet 和 ILSVRC 2012年冠軍的 AlexNet 的架構差異:
—— 出處: wikimedia
除了2012年的 AlexNet 以外,後續也有許多不同的架構設計。
GoogleNet(Google 團隊)
2014年 ILSVRC 冠軍,使用了 Inception模型和 GAP
—— 出處:GoogleNet 論文
ResNet(Microsoft 團隊)
2015年 ILSVRC 冠軍,超過人類的識別率。高達152層的深度學習。
使用了殘差學習(Residual learning),透過 Skip connection(層和層的跳接),
即便某層發生梯度消失,全體也很難發生梯度消失。構成如下:
—— 出處:ResNet 論文
這邊簡單介紹一下殘差,主要是用來解決當深度學習的層數加深,訓練集的訓練誤差會變大的退化問題(Degradation)。
如果這一層學到的特徵和上一層的結果一樣(恆等映射,identity mapping),理論上不會出現退化問題。
這邊有個名詞叫殘差(Residual),用 F(x)代表。
F(x) = 學到的特徵 - 輸入
所以如果殘差為 0 代表沒有學到新的東西不會退化,也就是上圖的
輸入x 跳過中間的 F(x) 直接變成 F(x)+ x 跳接的用意。
透過對 F(x)+ x 做最佳化(函數微分),數學式上會在做梯度下降時添加一個常數項使得梯度下降時傳遞的參數不會小於1,也就是不會發生梯度消失。因為跳接(Skip connection)像電路的短路,所以又叫短路連接(shortcut connection)。
殘差學習至少需要2層做跳接。更詳細的部分,有興趣的人可以參考補充資料。
轉移學習主要是將學習完成的模型應用在相關但不同的問題,例如識別汽車的模型可以應用於識別卡車。用來解決新對象的資料不足以及減少重新訓練所需要的龐大計算時間。
像 GoogleNet 和 ResNet 這種以 ImageNet 龐大圖像資料集為對象訓練完成的模型,可以只保留前面擷取特徵的參數部分,改變分類用的部分重新做訓練(微調)即可。
比方說針對 ImageNet(分類 1000 類) 訓練完畢的 ResNet18 轉移到只有 10 類別的 CIFAR10 資料集上工作,具體要做的模型修改只有兩件事:
這樣就完成了模型修改,當然還沒有經過超參數調整及訓練,準確率非常的差。而轉移學習也分成好幾種種類,這邊有個概念即可。
圖像學習的微調通常是變更全連接層的部份以及softmax的分類數。