【機器學習】李巨集毅——卷積神經網路CNN
CNN我們可以從兩個角度來理解其中的具體過程
Neuron Version Story(解釋版本1)
對於影象分類,其具體的流程如下所示:
將一張影象作為模型的輸入,輸出經過softmax之後將與理想向量用交叉熵的形式進行比較。那麼如何將圖片作為模型的輸入呢?
實際上每張圖片都是三維的張量,兩維表示長寬,一維表示通道(RGB),那麼就可以將這個張量拉長成一個向量,就可以作為模型的輸入了,該向量的每一個元素都是對應畫素在對應通道上的取值。
那麼如果將上述的向量輸入到一個全連線的網路中:
可以看到引數量非常的巨大!,因此我們應該嘗試來進行簡化!
觀察現象1:
假設我們a當前在分辨一張圖片是不是一隻鳥的時候,我們並不用將整張圖片完全都進行閱讀與處理,實際上我們只需要找這張圖片有沒有出現關於鳥的關鍵性特徵,例如鳥嘴、鳥的爪子等等,因此可以從這個思想進行簡化
簡化方法1:
每一個神經元結點只看一部分割槽域的內容,例如:
那個神經元只需要接受該$3\times 3$區域的資訊,因此只需要將該區域展開成向量作為該神經網路的輸入即可。並且多個神經元結點他們的觀測區域是可以重疊的、不同的觀測區域可以不同的大小、不同的通道等等。
典型設定
- 每一個觀測區域都是觀測全部通道,其大小稱為kernel size,通常為$(3\times 3)$
- 每一個觀測區域通常不止有一個神經元結點在守衛,通常有多個,例如64、128
- 觀測區域之間通常是有重疊的,例如上述stride就是距離,為2說明有1的交疊
- 如果在邊界發現超出了範圍,可以進行padding補值,那麼可以補0或者均值等等
觀察現象2:
同一個特徵可能出現在圖片中的不同位置,例如下面兩張圖片的鳥嘴是出現在圖片的不同區域的:
那麼是不是我需要在每一個區域都放一個可以偵測鳥嘴的神經元才可以呢?可是偵測鳥嘴這件事情是重複的,只不過是出現在不同的區域,那麼可以進行簡化。
簡化方法2:
那麼既然所做的事情是一樣的只不過是區域不同,那麼就讓這不同區域的都是偵測鳥嘴的神經元共享引數:
這樣就可以完成在不同區域檢測同一個特徵,同時減少引數量的目的。
典型設定
結合我們前面所說的一個觀測區域是由多個結點來守衛的,那麼可以認為每個區域所擁有的神經元個數都相同,並且其中每一個神經元所偵測的特徵也都相同,我們讓其共享引數,也就全部區域都只有一組引數了
那麼結合上面的各種方法,就把神經網路從全連線的範圍減小到了卷積網路的範圍,卷積神經網路的神經元滿足上述的條件。因此可以看到因為範圍小所以相對來說卷積神經網路的偏差是比較大的,但它是適用於特定的影像識別任務的。
Filter Version Story(解釋版本2)
這個角度是說,對於一層卷積層,我們有很多個Filter,可以認為每一個Filter都是為了偵測某一個特徵,其大小為設為$(3\times 3 \times channel)$,而其中的引數就是我們通過學習得到的。假設我們已知引數,現在來看其工作過程。
對於每一個Filter,會掃描整張圖片的所有區域,然後將對應元素相乘再求和得到一個數組,掃描之後所得到的矩陣就是該層Filter對影象的處理結果:
那麼如果有多個Filter,就可以得到多個類似的數值矩陣
假設當前我們有64個Filter,那麼得到的數值矩陣大小為$(4\times 4 \times 64)$,就可以將這個數值矩陣看成一個全新的圖片,其長寬為$4\times 4$,其通道數為64,再將其輸入到下一層的卷積之中,那麼下一層的Filter的大小就需要為$(3\times 3 \times 64)$了:
那麼有一個問題是我們掃描的大小一直是$3\times 3$,有沒有可能出現掃描的區域太小導致沒看到某個特徵的全部的現象?可以看下圖
第二層仍然是$3\times 3$,但是其掃描的是第一層的輸出結果,其掃描的區域相對於原始影象矩陣來說就是$5\times 5$,因此只要你層數足夠,後面是可以一次性掃描整張圖片的。
以上就是其工作流程。
這兩種介紹方式的區別在於:
- 第一種說Filter是共同引數,而第二種則是一個Filter掃描過每一個區域
觀察現象3:
如果對一張圖,將其奇數行和奇數列拿掉,圖片縮小為原來的四分之一,其特徵是不會改變的,我們仍然可以很明顯地看出是什麼內容,這樣縮小圖片的大小稱為pooling,可以有效地減小運算量。接下來介紹pooling具體怎麼執行。
pooling——max pooling
對於前述從Filter得到的數值矩陣中,如果採用max pooling,那麼就是將矩陣按照固定大小進行分組,然後每一組選出其中最大的數值來作為代表,這樣就縮小了矩陣的大小,如下圖:
那麼通常呢是在卷積之後就加上pooling,可以有效地減小計算量:
但這樣也會損失一定的精度,因此可以幾層卷積之後再進行一次pooling。
CNN的完整過程
經過前述的卷積+pooling,我們得到的是一個數值矩陣,那麼如何從數值矩陣得到我們最終想要的判斷類別的向量呢?請看下圖:
因此完整過程為:
- 將影象輸入後經過反覆的卷積和pooling後得到一個數值矩陣
- 將該數值矩陣Flatten,降成一個向量,作為一個全連線網路的輸入
- 經過全連線網路的處理後的輸出再經過一個softmax函式,得到最終的輸出向量
Spatial Transformer Layer
由於CNN對於一些影象的特定操作不能夠及時的反映出來,例如將訓練時的物體進行放大、縮小、旋轉等,CNN都很難能夠及時地辨認出來,因此可在CNN之間加上一個特殊的轉換層,這一層的目的在於能夠將一些圖片進行處理,處理成CNN能夠辨識的樣子,如下:
而將該層的引數和CNN的引數一起訓練就稱為End-to-end learn。
如何進行影象處理
具體的方式是將原始影象矩陣乘以一定的權重矩陣,得到目標影象矩陣,如下圖:
通過合理地設定$w^l_{nm,ij}$就可以使得原來矩陣的值往下移動。而其他的旋轉等操作也是類似的,實際上可以看成是經過一層神經元來帶來的操作
常見轉換
從上面可知,對於旋轉、平移、縮放這些affine transformation,只需要六個引數來構成一個矩陣和一個向量,再將原始位置向量進行運算即可得出最終結果,因此可以認為將原始影象矩陣方法該層神經網路中將會輸出六個引數構成矩陣和向量,然後再將原始矩陣和該引數進行計算即可得到目標影象:
這裡的$[x,y]$和$[x,y
]$代表的是索引!!,例如
代入$[x,y]=[2,2]$,那麼得到$[x,y
]=[1,1]$也就是說
$$
a^l_{22}=a^{l-1}_{1,1}
$$
但如果是下面這種情況:
那麼得到的索引不是整數,那麼只能進行四捨五入。但這也就帶來了問題
這樣的轉換是否可以進行梯度下降求解引數?
不可以!。梯度下降的含義是引數有微小的變化時輸出會有什麼變化,假設現在引數變化了而輸出變成了1.61和2.41,但這經過四捨五入之後也就還是那個索引,沒有變化無法帶來梯度。
改進
捨棄四捨五入的做法!,採用如下的辦法:
根據輸出與周圍座標的差距來進行加權和,這樣在輸出有微小變化的時候最終結果也有微小變化,這樣就可以進行梯度下降了。