卷積:如何成為一個很厲害的神經網路

原文:An Intuitive Explanation of Convolutional Neural Networks

作者:Ujjwal Karn

翻譯:Kaiser(王司圖)

動圖+在線練習版本:卷積:如何成為一個很厲害的神經網路 - 集智專欄

前言

  • 如果你對神經網路還是完全陌生的,建議閱讀9行Python代碼搭建神經網路來掌握一些基本概念。
  • 本文含有部分gif動圖,有可能無法播放,也需要訪問上面的「集智」鏈接查看。
  • 作為獎品的戰網點卡已全部送出,祝賀以下獲獎用戶:
    • 劉洋 - 知乎

    • 張震宇 - 知乎

    • 竹石 - 知乎

    • Sanada Yukimura - 知乎

    • Andras丶- 微博

什麼是卷積神經網路?又為什麼很重要?

卷積神經網路(Convolutional Neural Networks, ConvNets or CNNs)是一種在圖像識別與分類領域被證明特別有效的神經網路。卷積網路已經成功地識別人臉、物體、交通標誌,應用在機器人和無人車等載具。

圖1

在上面的圖1當中,卷積網路能夠識別場景而系統可以自動推薦相關標籤如「橋」、「鐵路」、「網球」等。圖2則展示了卷積網路識別日常事物如人、動物的例子。最近,卷積網路也已經在自然語言處理上顯示出了威力(比如句子分類)。

圖2

卷積網路,在今天的絕大多數機器學習應用中都是極重要的工具。但是,理解卷積網路並首次學著使用,這體驗有時並不友好。本文的主旨在於幫助讀者理解,卷積神經網路是如何作用於圖片的。

在本文,多層感知機(Multi-Layer Perceptrons, MLP)也被記作全連接層(Fully Connected Layers)。

LeNet架構(1990年代)

LeNet是最早用於深度學習了領域的卷積神經網路之一。Yann LeCun的這一傑作LeNet5得名於他自1988年以來的系列成功迭代。彼時LeNet架構還主要被用於識別郵政編碼等任務。

下面我們將直觀地感受一下,LeNet是如何學習識別圖像的。近幾年已經出現了很多建立在LeNet之上的新架構,但是基本概念還是來自於LeNet,並且理解了LeNet再學其他的也會更簡單。

圖3:簡單的ConvNet

圖3的卷積神經網路與LeNet的原始架構十分接近,把圖片分入四個類別:狗,貓,船,鳥(LeNet最早主要就是用來做這些)。如上圖所示,當獲得一張船圖作為輸入的時候,網路正確的給船的分類賦予了最高的概率(0.94)。輸出層的各個概率相加應為1.

圖3的卷積神經網路主要執行了四個操作:

  1. 卷積
  2. 非線性(ReLU)
  3. 池化或下採樣
  4. 分類(全連接層)

這些操作也是所有卷積神經網路的基石,所以理解好這些工作對於理解整個神經網路至關重要。接下來我們將嘗試最直觀地理解以上操作。

圖片是像素值的矩陣

本質上來講,每個圖片都可以表示為像素值組成的矩陣:

圖4:像素值矩陣

通道是代指圖片特定成分的習語。常見數碼相機拍出來的照片有三個通道——紅、綠、藍-可以想像為是三個2d矩陣(每種顏色對應一個)疊在一起,每個矩陣的值都在0-255之間。

另一方面,灰度圖像只有單通道。本文為簡單起見只考慮灰度圖像,這樣就是一個2d矩陣。矩陣中的每個像素值還是0到255——0表示黑,255表示白。

卷積

卷積網路是因為「卷積」操作而得名的。卷積的根本目的是從輸入圖片中提取特徵。卷積用一個小方陣的數據學習圖像特徵,可以保留像素之間的空間關係。這裡不深入探討卷積的數學原理,重在理解工作過程。

如上所述,每個圖片都是像素值矩陣。考慮一個5x5的圖像,其像素值為0和1,下面的綠色矩陣是灰度圖的特例(常規灰度圖的像素值取值0-255),同時考慮如下的3x3矩陣:

然後,5x5圖像和3x3矩陣之間的卷積計算,可由下圖的動畫所表示:

圖5:卷積操作。輸出矩陣叫卷積特徵或特徵映射

想一想以上操作是如何完成的,我們在原始圖片(綠色)上1像素、1像素地滑動橙色矩陣(也稱"stride"),並且在每個位置上,我們都對兩個矩陣的對應元素相乘後求和得到一個整數,這就是輸出矩陣(粉色)的元素。注意,3x3矩陣每次只「看見」輸入圖片的一部分。

3x3矩陣也叫「濾波器」、「核」或「特徵探測器」,在原圖上滑動濾波器、點乘矩陣所得的矩陣稱為「卷積特徵」、「激勵映射」或「特徵映射」。這裡的重點就是,理解濾波器對於原輸入圖片來說,是個特徵探測器。

對於同一張照片,不同的濾波器將會產生不同的特徵映射。比如考慮下面這張輸入圖片:

下表可見各種不同卷積核對於上圖的效果。只需調整濾波器的數值,我們就可以執行諸如邊緣檢測、銳化、模糊等效果——這說明不同的濾波器會從圖片中探測到不同的特徵,比如邊緣、曲線等。

另一種對卷積操作很好的理解方式就是觀察圖6的動畫:

(gif體積過大,無法上傳)

一個濾波器(紅框)在圖片上滑動(卷積)產生特徵映射。在同一個圖片上,另一個濾波器(綠框)的卷積產生了不同的特徵映射。須知,卷積操作捕捉的是原圖的局部依賴性。另外,注意觀察兩個不同的濾波器怎樣產生不同的特徵映射。其實不管是圖片,還是兩個濾波器,本質上都不過是我們剛才看過的數值矩陣而已。

在實踐當中,卷積神經網路在訓練過程中學習濾波器的值,當然我們還是要在訓練之前需要指定一些參數:濾波器的個數,濾波器尺寸、網路架構等等。濾波器越多,從圖像中提取的特徵就越多,模式識別能力就越強。

特徵映射的尺寸由三個參數控制,我們需要在卷積步驟之前就設定好:

  • 深度(Depth): 深度就是卷積操作中用到的濾波器個數。如圖7所示,我們對原始的船圖用了三個不同的濾波器,從而產生了三個特徵映射。你可以認為這三個特徵映射也是堆疊的2d矩陣,所以這裡特徵映射的「深度」就是3。

圖7

  • 步幅(Stride):步幅是每次滑過的像素數。當Stride=1的時候就是逐個像素地滑動。當Stride=2的時候每次就會滑過2個像素。步幅越大,特徵映射越小。

  • 補零(Zero-padding):有時候在輸入矩陣的邊緣填補一圈0會很方便,這樣我們就可以對圖像矩陣的邊緣像素也施加濾波器。補零的好處是讓我們可以控制特徵映射的尺寸。補零也叫寬卷積,不補零就叫窄卷積。

非線性

圖3所示,每個卷積操作之後,都有一個叫ReLU的附加操作。ReLU的全稱是糾正線性單元(Rectified Linear Unit),是一種非線性操作,其輸出如下:

圖8:ReLU

ReLU是以像素為單位生效的,其將所有負值像素替換為0。ReLU的目的是向卷積網路中引入非線性,因為真實世界裡大多數需要學習的問題都是非線性的(單純的卷積操作時線性的——矩陣相乘、相加,所以才需要額外的計算引入非線性)。

圖9可以幫助我們清晰地理解,ReLU應用在圖6得到的特徵映射上,輸出的新特徵映射也叫「糾正」特徵映射。(黑色被抹成了灰色)

圖9:ReLU

其他非線性方程比如tanhsigmoid也可以替代ReLU,但多數情況下ReLU的表現更好。

池化

空間池化(也叫亞採樣或下採樣)降低了每個特徵映射的維度,但是保留了最重要的信息。空間池化可以有很多種形式:最大(Max),平均(Average),求和(Sum)等等。

以最大池化為例,我們定義了空間上的鄰域(2x2的窗)並且從糾正特徵映射中取出窗里最大的元素。除了取最大值以額外,我們也可以取平均值(平均池化)或者把窗里所有元素加起來。實際上,最大池化已經顯示了最好的成效。

圖10顯示了對糾正特徵映射的最大池化操作(在卷積+ReLU之後),使用的是2x2的窗。

圖10:最大池化

我們以2格的步幅(Stride)滑動2x2的窗,並且取每個區域的最大值。圖10同樣顯示了池化可以減少特徵映射的維度。

圖11所示的網路中,池化操作分別應用於每個特徵映射(注意正因如此,我們從三個輸入映射得到了三個輸出映射)。

圖11:對糾正特徵映射應用池化

圖12即為池化操作施加在圖9所得糾正特徵映射上的效果。

圖12:池化

池化的功能室逐步減少輸入表徵的空間尺寸。特別地,池化

  • 使輸入表徵(特徵維度)更小而易操作
  • 減少網路中的參數與計算數量,從而遏制過擬合
  • 增強網路對輸入圖像中的小變形、扭曲、平移的魯棒性(輸入里的微小扭曲不會改變池化輸出——因為我們在局部鄰域已經取了最大值/平均值)。
  • 幫助我們獲得不因尺寸而改變的等效圖片表徵。這非常有用,因為這樣我們就可以探測到圖片里的物體,不論那個物體在哪。

截至目前:

圖13

至此我們已經了解了卷積、ReLU和池化是如何運轉的,這些層對於所有的卷積神經網路都是最基礎的單元。如圖13所示,我們有兩組「卷積+ReLU+池化」層——其中第二組對第一組的輸出施加了六個濾波器,產生了六個特徵映射。ReLU分別作用域這六個特徵映射,再對生成的糾正特徵映射使用最大池化。

這些層合力提取出有用的特徵,為網路引入了非線性並降低了維度,還使特徵對尺寸和平移保持不變性。

第二個池化層的輸出相當於全連接層的輸入,我們將在下一節繼續探討。

全連接層

全連接層(Fully Connected layer)就是使用了softmax激勵函數作為輸出層的多層感知機(Multi-Layer Perceptron),其他很多分類器如支持向量機也使用了softmax。「全連接」表示上一層的每一個神經元,都和下一層的每一個神經元是相互連接的。

卷積層和池化層呢個的輸出代表了輸入圖像的高級特徵,全連接層的目的就是用這些特徵進行分類,類別基於訓練集。比如圖14所示的圖像分類任務,有四種可能的類別。(注意,圖14沒有顯示出所有的神經元節點)

圖14:全連接層——每個節點都與相鄰層的所有節點相連

除了分類以外,加入全連接層也是學習特徵之間非線性組合的有效辦法。卷積層和池化層提取出來的特徵很好,但是如果考慮這些特徵之間的組合,就更好了。

全連接層的輸出概率之和為1,這是由激勵函數Softmax保證的。Softmax函數把任意實值的向量轉變成元素取之0-1且和為1的向量。

聯合起來——反向傳播訓練

綜上,卷積+池化是特徵提取器,全連接層是分類器。

注意圖15,因為輸入圖片是條船,所以目標概率對船是1,其他類別是0.

  • 輸入圖像 = 船
  • 目標向量 = [0, 0, 1 ,0]

圖15:訓練卷積神經網路

卷積網路的訓練過程可以概括如下:

  • Step 1: 用隨機數初始化所有的濾波器和參數/權重
    • Step 2: 網路將訓練圖片作為輸入,執行前向步驟(卷積,ReLU,池化以及全連接層的前向傳播)並計算每個類別的對應輸出概率。

      • 假設船圖的輸出概率是[0.2, 0.4, 0.1, 0.3]
      • 因為第一個訓練樣本的權重都是隨機的,所以這個輸出概率也跟隨機的差不多
    • Step 3: 計算輸出層的總誤差(4類別之和)

      • 總誤差=∑12(目標概率?輸出概率)2總誤差=∑12(目標概率?輸出概率)2
    • Step 4: 反向傳播演算法計算誤差相對於所有權重的梯度,並用梯度下降法更新所有的濾波器/權重和參數的值,以使輸出誤差最小化。

      • 權重的調整程度與其對總誤差的貢獻成正比。
      • 當同一圖像再次被輸入,這次的輸出概率可能是[0.1, 0.1, 0.7, 0.1],與目標[0, 0, 1, 0]更接近了。
      • 這說明我們的神經網路已經學習著分類特定圖片了,學習的方式是調整權重/濾波器以降低輸出誤差。
      • 如濾波器個數、濾波器尺寸、網路架構這些參數,是在Step 1之前就已經固定的,且不會在訓練過程中改變——只有濾波矩陣和神經元突觸權重會更新。

    以上步驟訓練了卷積網路——本質上就是優化所有的權重和參數,使其能夠正確地分類訓練集里的圖片。

    當一個新的(前所未見的)的圖片輸入至卷積網路,網路會執行前向傳播步驟並輸出每個類別的概率(對於新圖像,輸出概率用的也是訓練過的權重值)。如果我們的訓練集足夠大,網路就有望正確分類新圖片,獲得良好的泛化(generalization)能力。

    注意 1: 以上步驟已被極大簡化,且數學細節均以忽略,這是為了讓訓練過程更直觀。

    注意 2: 上例中,我們用了兩組卷積+池化層,其實這些操作可以在一個卷積網路內重複無數次。如今有些表現出眾的卷積網路,都有數以十計的卷積+池化層!並且,不是每個卷積層後面都要跟個池化層。由圖16可見,我們可以有連續多組卷積+ReLU層,後面再加一個池化層。

    圖16

    可視化卷積神經網路

    一般來說,卷積層越多,能學會的特徵也就越複雜。比如在圖像分類中,一個卷積神經網路的第一層學會了探測像素中的邊緣,然後第二層用這些邊緣再去探測簡單的形狀,其他層再用形狀去探測高級特徵,比如臉型,如圖17所示——這些特徵是Convolutional Deep Belief Network學得的。這裡只是一個簡單的例子,實際上卷積濾波器可能會探測出一些沒有意義的特徵。

    圖17:Convolutional Deep Belief Network學習的特徵

    Adam Harley做了一個非常驚艷的卷積神經網路可視化,這個網路是用MNIST手寫數字資料庫訓練而來的。我強烈推薦大家玩一玩,以便更深地理解卷積神經網路的細節。

    如下我們將看到網路是如何識別輸入數字"8"的。注意,圖18沒有把ReLU過程單獨顯示出來。

    圖18:可視化卷積神經網路

    輸入圖像有1024個像素(32x32圖片),第一個卷積層(Convolution Layer 1)有六個不同的5x5濾波器(Stride = 1)。由圖可見,六個不同的濾波器產生了深度為6的特徵映射。

    Convolutional Layer 1 後面跟著Pooling Layer 1, 對六個特徵映射分別進行2x2的最大池化(Stride = 2)。你可以在動態網頁中的每個像素上活動滑鼠指針,觀察其在前一個卷積層里對應的4x4網格(如圖19)。不難發現,每個4x4網格里的最亮的像素(對應最大值)構成了池化層。

    圖19:可視化池化操作

    之後我們有三個全連接(FC)層:

    • FC 1: 120神經元
    • FC 2: 100神經元
    • FC 3: 10神經元,對應10個數字——也即輸出層

    圖20,輸出層10個節點中的每一個,都與第二個全連接層的100個節點相連(所以叫「全連接」)。

    注意輸出層里的唯一的亮點對應著8——這說明網路正確的識別了手寫數字(越亮的節點代表越高的概率,比如這裡8就擁有最高的概率)。

    圖20:可視化全連接層

    該可視化的3D版可見於這裡。

    其他卷積網路架構

    卷積神經網路始自1990年代起,我們已經認識了最早的LeNet,其他一些很有影響力的架構列舉如下:

    • 1990s至2012:從90年代到2010年代早期,卷積神經網路都處於孵化階段。隨著數據量增大和計算能力提高,卷積神經網路能搞定的問題也越來越有意思了。

    • AlexNet(2012):2012年,Alex Krizhevsky發布了AlexNet,是LeNet的更深、更寬版本,並且大比分贏得了當年的ImageNet大規模圖像識別挑戰賽(ILSVRC)。這是一次非常重要的大突破,現在普及的卷積神經網路應用都要感謝這一壯舉。

    • ZF Net(2013):2013年的ILSVRC贏家是Matthew Zeiler和Rob Fergus的卷積網路,被稱作ZF Net,這是調整過架構超參數的AlexNet改進型。

    • GoogleNet(2014):2014的ILSVRC勝者是來自Google的Szegedy et al.。其主要貢獻是研發了Inception Module,它大幅減少了網路中的參數數量(四百萬,相比AlexNet的六千萬)。

    • VGGNet(2014):當年的ILSVRC亞軍是VGGNet,突出貢獻是展示了網路的深度(層次數量)是良好表現的關鍵因素。

    • ResNet(2015): Kaiming He研發的Residual Network是2015年的ILSVRC冠軍,也代表了卷積神經網路的最高水平,同時還是實踐的默認選擇(2016年5月)。

    • DenseNet(2016年8月): 由Gao Huang發表,Densely Connected Convolutional Network的每一層都直接與其他各層前向連接。DenseNet已經在五個高難度的物體識別基礎集上,顯式出非凡的進步。

    (翻譯部分 完)

    經過本文和之前的系列文章,您應該已經掌握了卷積神經網路的基本原理。接下來我們嘗試用流行的Python深度學習庫Keras,動手實地搭建一個LeNet。

    實踐是神經網路的唯一標準

    回顧LeNet的架構,補全第二組卷積+激勵+池化,搭建出經典的LeNet網路。

    提示:

    • 第二組卷積層有16個濾波器,尺寸為8x8。
    • 第二組激勵層使用tanh函數
    • 第二組最大池化層的尺寸和步幅均為3x3

    請在下方的Python開發環境中補全代碼,並點擊藍色按鈕【運行】檢查答案是否正確。

    (需訪問:卷積:如何成為一個很厲害的神經網路 - 集智專欄)

    如下圖,第二組卷積+激勵+池化層的參數設置有誤,就會得到紅色提示,並指出具體的錯誤所在。


    推薦閱讀:

    【專知薈萃16】主題模型Topic Model知識資料全集(基礎/進階/論文/綜述/代碼/專家,附PDF下載)
    5分鐘教你如何布局人工智慧
    美日巨型機器人已經運達決戰現場!希望誰贏呢?
    AI晶元四大流派論劍,中國能否彎道超車?|半導體行業觀察
    大家來預測一下吳恩達三個新項目之一deeplearning.ai之後,接下來的兩個項目將會是什麼項目?

    TAG:人工智能 | 卷积神经网络CNN | Python |