在深度學習的領域中,面對大型圖像的學習,我們可以採用卷積神經網路(Convolution Neural Network)。就字面意義而言,這是結合了卷積與神經網路,就結論而言,主要是希望訓練出一組卷積核(Kernel),令其擁有適當之權重,以便對圖像進行預測,那為什麼卷積核行得通?單一卷積核對圖像處理的意義是什麼呢?

圖像濾波與卷積運算

在先前專欄〈淺談圖片雜訊處理〉與〈傅立葉轉換與影像處理〉中,我從圖像頻率的角度談過圖像濾波處理,如果使用OpenCV,可以透過blur、medianBlur等函式或fft模組,來進行濾波運算。

實際上,我們也可以透過filter2D,自行指定卷積核來進行對應的處理,例如,在blur的均值濾波處理中,若ksize指定3x3,相當於filter2D指定了一個3x3、元素值全是1/3的卷積核來進行操作。

就簡單的理解方式而言,卷積核中心會逐一對齊圖像中每個像素,而卷積核元素與會罩住的各像素各自相乘後加總。就方才提及的3x3卷積核而言,其運算結果,就是取罩住的九個像素值之平均作為新像素值。

於是,這就引發了一個問題:若卷積核中心對齊的是圖像邊緣像素呢?關於不足的部份,我們可以指定填補方式,最簡單的作法就是全部填0,也可以是複製鄰近像素等其他策略。

blur處理對應的卷積核容易理解,那麼,其他的卷積核呢?

例如,用來尋找邊緣的Laplace運算,若是3x3的卷積核,會是,卷積核的元素值來源,是從圖像頻率的觀點開始,若圖像頻率高,波(灰階或各通道顏色)的斜率變化就大,波的一階導數是頻率,波的二階導數是斜率變化。

如果求圖像x方向的二階導數,將之整理為矩陣,會是,若是求y方向的二階導數,整理後的矩陣會是,此時,將兩個矩陣相加,就會是方才看到的卷積核,而將x、y兩個方向的二階導數相加,符合Laplace運算的定義;若對於以上的推導過程有興趣,你可以參考〈Laplacian 運算〉。

卷積為什麼叫卷積

那麼,方才我們所看到的卷積運算,為什麼會稱為「卷積」呢?

卷積的原文為convolution,也可以翻為摺積、疊積等,動詞為convolute,也就是「捲起」之意,就維基百科〈摺積〉條目的內容來看,是一個特徵函數f與經過翻轉和平移的函數g,相乘後的積分結果(圍成的曲邊梯形的面積),相當於把兩個函數捲起來成為一個函數,在〈卷積為什麼叫「卷」積〉有個將一張紙捲起來的生動比喻,可以作為理解的輔助。

就圖像而言,它是二維的,因此特徵函數會是f(x,y),而g(x,y)會是圖像在x,y的值(灰階或各通道顏色),而且,由於圖像以像素為單位,真正使用的會是離散卷積(而不是連續卷積),也就是:積分時的dx、dy最小就是1,最後構成的形式會是ΣΣf(s,t)*g(x-s,y-s),其中的兩個Σ,各會是t與s的負無限到正無限,白話來說,就是將g函式距離(-s,-t)的值與f在(s,t)的值相乘後加總。

然而,實際上,在圖像處理時的卷積核大小是有限的,如果卷積核是3x3,t與s的範圍會取[-1,0,1],若將方才的離散形式整理為矩陣,f是卷積核,g是圖像,而最後的運算方式,就會是將f上下翻轉後、再予以左右翻轉,然後與圖像上罩住的每個像素各自相乘後加總。

有些人可能會覺得奇怪,卷積核怎麼還要上下左右翻轉?畢竟不少文件或書籍,在說明相關作法時,都是直接與每個像素各自相乘後加總。事實上,一方面這是為了簡化說明,另一方面是說明時使用的卷積核,元素值多半都是上下左右對稱。

在維基百科〈Kernel (image processing)〉我們可以看到,其中的卷積範例,運算時,確實就是將卷積核上下左右翻轉,而在〈2D Convolution using Python & NumPy〉,我們也可以看到,其示範的實作中,確實也將指定的卷積核翻轉了。

卷積神經網路

在入門深度學習時,使用深度神經網路時,多半會經歷過手寫圖片辨識之類的練習,圖像在處理時會打平為一維向量,作為神經網路的輸入值,這類網路稱為全連接網路,圖像被打平為一維向量的結果是,忽略了像素與像素之間的位置關係,輸入與輸出就像是個線性映射。

某些程度上,這就像模型硬是記住了來源圖片個別像素位置與分類的關係,在《Deep Learning with PyTorch》第八章談到,全連接網路無法達到區域訊息的平移不變性,也就是說,如果圖片中的數字從左上移至右下,作為新圖片要模型預測,那麼就可能是錯誤的結果。

方才看到卷積核,其實會用來罩住圖像的一個區域,如果卷積運算結合深度學習網路,令卷積中的每個元素值,來自大量圖像資料訓練後的結果,那麼,就可以顧及區域訊息的平移不變性,這是使用卷積神經網路的出發點。

因為基本上,卷積核就是在對像素加權計算後求和,在圖像處理上,已經有不少專家,用了各種方式尋找、推導出抽取特徵的卷積核,方才的Laplace運算是一例,Sobel運算也是用來抽取圖像邊緣,原理也是基於二階偏導數,至於透過卷積神經網路來訓練卷積核,其實就是想基於大量資料來學習、產生一堆卷積核。

對此,你可以想像成:訓練的成果是一堆濾鏡,每個濾鏡用來抽取不同的特徵,而圖像經過這堆濾鏡將得到足以預測結果的資訊,只不過,如同前一篇專欄〈思考模型的可解釋性〉所談到的,對於訓練後的成果,很大程度上失去了解釋性,對於各自被訓練出來的卷積核,各自抽取了什麼特徵,我們往往很難解釋(而透過特定設計的Laplace、Sobel則是可以解釋)。

跟卷積神經網路相關的,還有池化的問題,雖然說卷積核比較容照顧到區域資訊,然而,有沒有可能一張大圖像的資訊,正好是分布在左上與右下之類呢?

為了能顧及這個可能性,將卷積運算後的圖像資訊,進一步抽取特徵,就是池化之目的,例如,平均池化是取指定區域大小的像素之平均,最大池化則是挑選出最大特徵,池化之後的圖像會變小,因此也稱為降採樣(downsampling)。

卷積+深度學習網路

在認識深度學習網路之前,我們可以先認識迴歸之類的機器學習,去學習可解釋的模型是如何學習的,這有助於我們認知到:在深度學習網路中,各個神經元、神經層,其實是在犧牲了可解釋性,以一個更大的模型來擬合資料,從而進行預測。

卷積神經網路也是類似的道理,它也是個更大的模型,當中有著許多的卷積核、卷積層。

如果你對於它們的原理感到陌生,可以試著從可解釋的卷積核開始認識,像是模糊處理、雜訊去除、Laplace、Sobel運算等。

這麼一來,對於卷積神經網路中的填補、池化等觀念,就不會感到神秘或在原理上捉摸不定了。

專欄作者

熱門新聞

Advertisement