0引言

前幾年有一個樂高玩具愛好者,買了兩噸的樂高積木,不知道是幾百萬個(

https://www。

sohu。com/a/155077588_79

8050

),他想把這些積木分成不同的類別。一開始他想人工分揀,發現人生苦短;後來他訓練了一個卷積神經網路,然後用這個網路對這些積木進行分類。

卷積神經網路可不僅僅是用來分揀玩具的,它已經存在於我們生產和生活的各個角落了:我們的人臉識別應用,相當一部分使用了卷積神經網路;卷積神經網路還可以用來識別車輛車牌號,幫助保安大叔管理出入的車輛;最近出現的“換頭軟體”,可以把影片中某個人的臉,換成另一個人的,這也是基於卷積神經網路做到的;等等。

那麼,什麼是卷積神經網路呢?

1卷積神經網路

卷積神經網路(Convolutional Neural Networks, CNN),是神經網路的一種,它使用卷積核(Convolutional kernel)從資料中提取重要資訊,使用影象填充(padding)的策略儘量保留原始資料的資訊,使用池化(pooling)等策略來避免過擬合(為了避免過擬合,人們提出了非常多的策略)。

1.1一張圖片在電腦中的表示

假設我們有一張圖片,是6*6的,顯示的是數字6。如圖1-1,一個方塊代表一個畫素點,其中紅色部分就是阿拉伯數字”6”。對人來說,受過義務教育的人很容易就能識別出這張圖片裡的數字。

卷積神經網路簡介

圖1-1 一張圖片的示意圖

在機器中,這張圖片的存在形式是一個矩陣,如圖1-2。我們用數學符號來表示這個矩陣:

卷積神經網路簡介

卷積神經網路簡介

圖1-2 畫素點矩陣

機器是如何“看”這個矩陣的呢?

1.2CNN是如何看影象的

傳統人工神經元要求我們把矩陣fig”拉直”,得到一個長度為36的向量:

卷積神經網路簡介

然後,以這個向量為輸入,去訓練或者計算。

傳統神經元處理圖片資料的時候,有一個問題,就是把矩陣的6行粗暴地放到一行,導致相鄰畫素點被硬生生分隔開了。兩個相鄰的畫素點,就像是氣溫曲線上的兩個相鄰點一樣,具有時空上的關聯性,是有資訊量的。經典神經元的做法會破壞這部分資訊。

CNN認為,一個視神經細胞只能感受到有限區域內的影象,不能接收整個影象的資訊。要觀察一張圖片,我們需要神經元掃描一遍影象。如圖1-3,我們把影象分割成4個3*3的小塊,然後讓一個神經元分別觀察這4個小塊,結果就是,我們得到4個輸出,也就是一個長度為4的向量y=(y1,y2,y3,y4)。神經元一次觀察中處理的影象小塊,就是我們常聽說的感受野(receptive field),或者叫感受區域(大家瞎翻譯,個人認為”感受區域”比較好記一點,不過同行都叫感受野,咱們也只能叫感受野)。這個向量的元素之間是有空間關係的,我們用矩陣來表示:

卷積神經網路簡介

。這麼一看,圖1-3中的小圖片就是對大圖片的一個縮略表示(高階說法就是抽象表示);矩陣fig_new就是對矩陣fig的一個縮略表示。

卷積神經網路簡介

圖1-3 CNN中的神經元看影象的方式

這就是CNN看影象的方式,用多個神經元分別看影象的不同區域,以這些神經元的輸出,作為對影象的縮略表示。

當然了,前面所說的看圖方式是比較粗糙的。我們還是讓每個神經元看一個3*3的小區域;使用16個神經元去看影象的小區域,分別是

卷積神經網路簡介

其中,

卷積神經網路簡介

表示矩陣fig的第1行到第3行的第1列到第3列。這裡使用的矩陣索引方式是python的,因此第1列或者行的index是0;“0:3”表示從0開始,執行加一操作,直到得到最後一個小於3的數為止,最後得到一個數列(0,1,2)。

卷積神經網路簡介

卷積神經網路簡介

,我們在影象上跳了一個畫素點;我們可以上下左右地跳——跳躍的畫素點個數,叫做卷積步長(stride),大小是可以調整的。

前面,我們介紹的是卷積神經網路的大致思想。那麼,CNN具體是如何處理輸入的呢,為什麼有時候也被叫做神經網路呢?

1.3一個簡單的卷積核

卷積神經網路為什麼是神經網路呢?CNN裡有一種東西叫卷積核,一個卷積核實際上是一個人工神經元,示意圖如圖1-4。

注意,CNN通常使用的啟用函式是修正線性單元(

Rectified linear unit,ReLU

):

卷積神經網路簡介

relu啟用函式的影象如圖,是一個分段線性函式。

卷積神經網路簡介

圖1-4 CNN的卷積核

卷積神經網路簡介

圖1-5 relu啟用函式

注意卷積核的輸入向量(x1,x2,x3,。。。),就是我們前面從原始影象中分拆出來的小區域:

卷積神經網路簡介

卷積核在觀察第1個小區域的時候,輸入是

卷積神經網路簡介

我們還是需要把感受野內的小塊影象拉直,然後輸入到神經元裡。

神經元接受這塊影象後的輸出就是:

卷積神經網路簡介

假設卷積核的權重是

卷積神經網路簡介

,為了直觀,我們通常用矩陣來表示和記錄權重:

卷積神經網路簡介

那麼這個神經元的輸出是:

卷積神經網路簡介

這樣,卷積核接受整個影象後的輸出就是:

卷積神經網路簡介

1.4光板CNN——卷積層

如果我們只用一個卷積核去處理影象,只能得到一個縮圖,資訊損失的有點多。通常我們會用N個卷積核去掃描影象,得到N個縮圖。這N個卷積核就形成了我們常說的卷積層。

我們把N各縮圖都拉直了,形成一個N*4*4的向量,作為一個softmax迴歸模型的輸入,就可以用來做分類任務了。

這N個卷積核構成了一個卷積層,是CNN的核心部分,我們可以基於這種神經元來構建多層的網路。

卷積核在這個分類器中的作用,就是提取好的特徵;然後把這些特徵教給softmax去分類。這個分類器有些問題:卷積層的引數似乎有一些多;softmax層接收的特徵似乎有些多。如果我們使用這個分類器,會發現訓練非常慢,還容易過擬合。

怎麼辦呢?

卷積神經網路簡介

圖1-6 一層卷積層和softmax組成的一個分類器

1.5CNN解決過擬合問題的策略

1.5.1設定較大的stride

我們可以設定較大的卷積核stride,這樣,每個卷積核輸出的縮圖就會變小一些,進而減少softmax的輸入特徵數量。

1.5.2池化層

為了進一步縮小縮圖,我們可以採用這樣一個策略,就是池化。我們可以對縮圖中的畫素點,進行一個下采樣。假設縮圖的矩陣是:

卷積神經網路簡介

我們設定一個大小為3*3的取樣視窗,然後讓這個視窗在矩陣A上滑動,滑動的步長是1。每滑動到一個位置,我們就基於視窗內的元素,計算出一個可以代表這個視窗內的元素的值。

比方說,取樣視窗如圖。我們可以使用視窗內元素的均值(或者最小值、最大值等等,可以都試試),來代表這些元素:

卷積神經網路簡介

卷積神經網路簡介

圖1-7 池化取樣視窗示意圖

然後我們可以滑動視窗,得到另外3個取樣結果:

卷積神經網路簡介

這樣,矩陣A就被縮小了一圈,成為一個新的矩陣:

卷積神經網路簡介

假如A是一個很大的矩陣,池化操作可以顯著的縮小矩陣的大小。對CNN來說,較小的矩陣,就代表著較少的引數,過擬合的可能性就較低。

1.6影象填充

在1。3中,我們讓卷積核掃描影象的時候,有一個問題,那就是邊緣的畫素點、尤其是4角的畫素點被掃描到的次數較低,這使得卷積核提取到的資訊中,來自影象邊緣的有點少。

另外,有時候我們希望卷積核的輸出矩陣和原始影象的大小一樣。

怎麼辦呢?我們可以修改一下卷積核的感受野滑動的規則。

我們給原始影象周圍加1圈畫素點,都是黃色,如圖1-8。這個操作叫做填充。這樣,我們得到了一個8*8的新影象。由於我們填充時使用的是背景色,不影響影象中的數字。

卷積神經網路簡介

圖1-8 填充後的影象

填充後的影象的畫素矩陣是:

卷積神經網路簡介

這樣,我們用感受野大小為3*3的卷積核掃描fig_pad後,就會得到一個6*6的矩陣,和原始影象fig一樣大。

1.7完整的CNN

我們把1。5所介紹的策略加到1。4中的CNN+softmax分類器上,就得到了一個效果更好的分類器,如圖。

卷積神經網路簡介

圖1-9 CNN和softmax結合而成的一個分類器

這裡,從padding開始,到池化層,合起來就是CNN的基本結構。我們可以在這個基礎上進行魔改,得到LeNet之類的網路結構。

這裡我們只使用了一層CNN,就是算上softmax也才兩層人工神經元,看起來沒什麼深度。為什麼CNN被稱作深度學習演算法呢?

2深度神經網路

CNN實際上是一個特徵提取器,它會從影象中提取若干縮圖。有人覺得這些縮圖還是不夠抽象,就用2層甚至更多層的卷積層堆疊起來(當然,為了減少過擬合,每個卷積層後面一般都會加一個池化層),得到更加抽象的特徵。

那麼,CNN內部的節點之間是如何連線的呢?

卷積層和它後面的池化層的連線方式比較簡單,是一對一的。

我們主要看卷積層和它前面那個池化層的連線方式。由於前面那個池化層和前面的那個卷積層是一對一連線的,我們實際上需要考慮的是兩個卷積層之間的連線方式。

2.1全連線

我們假設layer1有N1個卷積核,接收原始影象,經過卷積操作和池化操作,輸出了N1個縮圖;layer2有N2個卷積核,接收layer1的輸出。Layer2的每一個卷積核,都要對layer1輸出的N1個縮圖進行卷積操作,分別得到N1個更小的縮圖。也就是說,layer2層會輸出一共N2*N1個更小的縮圖。這樣會導致引數隨著層數的增加迅速上升,我們的小電腦有點經受不起,因此這裡不採用這個方案。

2.2一對一

另外一種方式是layer1的第1個卷積核對應layer2的第1個卷積核;layer1的第2個卷積核對應layer2的第2個卷積核;。。。。也就是前後兩層CNN有著相同數量的卷積核,後一層的一個卷積核只接收前面一層的一個特定的卷積核的輸出。

一對一連線的方式,優點是連線數量少。但是會導致一種特徵只能沿著一條路徑一直走到盡頭。反過來說,卷積核只能接收上一層輸出中的一部分資訊,資訊損失是比較大的。

2.3LeNet的連線方式

我們採用LeCun在LeNet中的方案,layer2層的神經元只接收其中K個卷積核的輸出。假設layer1層有卷積核(no_1_1, no_1_2,no_1_3,no_1_4),而layer2層有卷積核(no_2_1, no_2_2, 。。, no_2_Q)。如K=4,那麼就是全連線了;如果K<4,比如k=3那麼layer2層的神經元對應的來自layer1的卷積核可以這樣分組

卷積神經網路簡介

圖2-1 CNN中卷積層與前面一層的連線策略

非全連線的方案,是前面兩種方案的折中形式,可以大幅減小兩層神經元之間的連線數,從而降低訓練時的計算量,但是又不會損失太多資訊。

至此,我們就介紹了CNN的基本構成以及連線方式。接下來,我們設計一個具體的分類器。

3.2網路結構設計

(1)各層神經元的個數

假設我們的分類器中,第1層卷積核有3個卷積核,第2層卷積核有2個,softmax層有10個神經元。

(2)卷積核的設定

卷積核的視野域統一為3*3,卷積步長為2,使用背景色來填充(見1。6節)。

(3)池化層的設定

池化層layer2的取樣視窗大小是22,步長是2,填充方式也是使用背景色來填充。layer4的取樣視窗大小是1*1,步長是1。

(4)卷積核與池化層的連線方式

見2。3節。

(5)池化層與softmax層的連線方式

全連線,也就是把池化層輸出的足有小圖片拉直,然後拼接成一個長向量,輸入到softmax層。

這樣,我們就設計了一個基於CNN提取特徵,用softmax分類的分類器。這個分類器裡有5層神經元layer1,layer2,layer3,layer4,layer5(其中layer1層和layer3是卷積核,layer3和layer4是池化層,layer5是softmax層)

那麼,CNN的卷積核的權重是如何得到的呢?

3CNN的訓練

通常來說,我們訓練CNN的方式,就是用有標籤資料去訓練如圖1-9這樣的分類器,從而得到CNN的引數。我們會使用反向傳播演算法來求CNN的引數。

3.1前向過程

,每一層的輸入和輸出我們都用x和y來表示,下角標表示向量是哪一層的。那麼,各層的輸入和輸出情況就是:

卷積神經網路簡介

卷積神經網路簡介

注意,這裡的矩陣元素符號,有一個比較長的下角標,5位的含義是:(1)卷積核所在的層數;(2)本層神經元的序號;(3)這個卷積核輸出的圖片的序號;(4)這個卷積核掃描得到的小圖片的行序號;(5)這個卷積核掃描得到的小圖片的列序號。

卷積核後面的池化層,接收y1,輸出是:

卷積神經網路簡介

第2個卷積核層接收y2,輸出是:

卷積神經網路簡介

第2個池化層的輸出是:

卷積神經網路簡介

Softmax層的輸出:

卷積神經網路簡介

3.2反向傳播過程

卷積神經網路的反向傳播過程和BP神經網路的基本一致。

假設真實標籤是

卷積神經網路簡介

,其中

卷積神經網路簡介

表示向量label的第i個元素的取值,在這個任務中就是圖片中數字取值為i的機率。

分類器的最後一層是softmax,最適合的損失函式是交叉熵:

卷積神經網路簡介

softmax層的各個神經元輸出的誤差是:

卷積神經網路簡介

那麼前面的池化層layer4的每一個畫素點對應的誤差就是,與這個畫素點相連的softmax神經元的誤差的加權和(權重就是連線權重)。

池化層layer4輸出的小圖片的畫素點與softmax神經元連線權重的梯度,就是神經元的輸出誤差與,畫素點取值的乘機。

layer3輸出的小圖片上的畫素點,誤差為對應的池化層layer4輸出的畫素點誤差。前面我們說過,mean pooling就是對取樣視窗內畫素點求均值。layer3的輸出誤差,就是對layer4輸出誤差進行一個反向的操作。

4結束語

我們可以看到,深度學習是機器學習演算法中,比較複雜的一類。深度學習為了克服模型擬合能力極強帶來的過擬合,使用了很多策略,導致理解和實現演算法的細節比較困難。學習這類演算法的時候,不要太過著急。

開源的學習資料中,由於預設學習深度學習的人已經有了一定的機器學習基礎,對演算法中的符號和推導介紹較少。學習CNN之前,我們最好把BP神經網路搞明白,這樣我們在理解卷積核以及CNN的訓練的時候會更輕鬆一些。

本文介紹的CNN非常簡單,實際生產中,我們使用的網路會更復雜一些。

注意:

本文為李鵬宇(知乎個人主頁

https://www。

zhihu。com/people/py-li-

34

)原創作品,受到著作權相關法規的保護。如需引用、轉載,請註明來源資訊:(1)作者名,即“李鵬宇”;(2)原始網頁連結,即當前頁面地址。如有疑問,可發郵件至我的郵箱:lipengyuer@126。com。