1. 程式人生 > >卷積神經網路記錄(一)基礎知識整理

卷積神經網路記錄(一)基礎知識整理

卷積神經網路記錄

最近一段時間在學習卷積神經網路的知識,看了很多部落格和資料之後,決定自己寫一篇記錄一下學習地知識,鞏固一下所學。

1.卷積神經網路與全連線神經網路的異同

首先來看卷積神經網路之前的網路的異同,兩種神經網路結構對比圖如下:

在這裡插入圖片描述

在結構上,兩種網路看起來不同,實際上還是很相似的。兩者都是通過一層一層的節點組織起來的,在訓練過程上也是基本一致。兩種神經網路的的區別就在於相鄰兩層的不同節點之間的連線方式,對於全連線網路(FC),位於相鄰兩層上的任意兩個節點都是連線的,而卷積神經網路(CNN)的相鄰兩層之間,只有部分節點相連。

那麼,為什麼會有CNN網路呢? 顯然,對於FC,輸入資料的所有資訊都會得到有效的利用,因為通過全連線的方式,每一點資訊都會對訓練過程做出“ 貢獻 ”

, 這是它的優點,但是,當處理影象資料的時候,這就反而成了累贅, 之前使用 FC 處理MNIST資料集,第一層上有 784 個節點,因為我們的影象是 28 * 28 , 僅僅是這樣的小圖片,需要進行更新的引數已經很多了,顯然,對於更大的圖片,這樣的過程是吃不消的。因此,CNN 應運而生,之後會介紹到 CNN 通過權值共享等等方法,有效地解決了這個問題。

2.卷積神經網路的重要概念

卷積是什麼

不管是什麼演算法,當牽扯到數學層面的時候,都不太好理解 ( ̄m ̄),但是理解之後都會更清楚整個過程。
如果去查卷積的概念,可能會出現這樣的定義:
卷積(convolution) 是通過兩個函式 ffg

g 生成第三個函式的一種數學運算元,表徵函式ffgg 經過翻轉和平移的重疊部分的面積。數學定義如下:
h(x)=f(x)g(x)=f(t)g(xt)d(t) h(x) =f(x)\cdot g(x)=\int f(t)\cdot g(x-t)d_{(t)}
不好理解,事實上,在卷積網路上使用的離散卷積,也就是不連續的,它是一種運算方式,也就是按照卷積核,將輸入對應位置的資料進行加權和運算,接下來結合卷積核的概念,就會很好理解了。如果想要進一步理解卷積,可以在知乎上查詢這一問題:
如何理解CNN中的卷積
其實不知有這一篇文章,另外還有很多問題下的回答都做了解釋,這裡就不一一列舉了。

卷積核的概念

接上面,卷積核是整個網路的核心,訓練CNN的過程就是不斷更新卷積核引數直到最優的過程。

卷積核的定義:對於輸入影象中的一部分割槽域,進行加權平均的處理,其中這個過程的權重,由一個函式定義,這個函式就是卷積核。(這個地方,在有些資料可能會將卷積核解釋為權重矩陣,當然概念其實不是很重要,直接將卷積核理解為一種運算方式就可以了)
下面看圖解,這樣會更直觀的理解這個計算過程:

在這裡插入圖片描述

左邊的 Image 是輸入的資料,右邊是通過卷積核操作之後的結果,定義中,進行處理的小區域就是顏色比較淺的 3*3 的區域, 可以看到這些資料被處理成了右側輸出中的一個小格子。

在這個卷積核中,我們定義:
w=[111111111] w = \begin{bmatrix} 1 & 1 &1 \\ 1 & 1 & 1\\ 1 & 1 & 1 \end{bmatrix}

b=0 b = 0

我們用這個 ww 的元素分別乘以待處理的區域的每一個元素值,也就是進行內積操作,然後加上bias,取均值:
f(x)=1×1+1×1+1×1+1×0+1×1+1×1+1×0+1×0+1×1=6 f(x) = 1\times1+1\times1+1\times1+1\times0+1\times1+1\times1+1\times0+1\times0+1\times1 = 6
上面的式子忽略了 加上 bias 的過程,因為定義bias等於0嘛,實際中不要忘記加上。然後我們把這個 6 儲存在輸出的第一個節點上,這樣,原來九個節點的資訊可以說是被 **“ 壓縮”**到了一個點的資訊中,那麼輸出結果的其他 8個 格子呢?其實是同樣的方式計算,只是選擇的區域不同而已:

在這裡插入圖片描述

這就相當於,給定了3 * 3 的區域,計算完一個之後,向另一個方向進行 “滑動”,這裡滑動的步長是1,這個步長稱為 “Stride”,也是很重要的一個引數,對輸入資料操作完成之後,我們就得到了右邊的輸出結果,這個結果也是一張圖對吧,我們稱之為這個卷積層的 特徵圖(Feature Map)

如果感覺還是不清楚,這裡還有兩張GIF圖,更直觀:

在這裡插入圖片描述

在這裡插入圖片描述

對於整個計算的過程來說,我們可以看到,原來 5*5 的輸入影象處理之後變成了 3*3 的特徵圖,所以可以說,卷積進行的是特徵提取的過程。

這就是卷積核的運作方式,如果用函式式來表示這個過程:
f(x)=wx+b f(x) = wx+b
很眼熟對吧,就像之前的神經元進行的線性變換一樣。這個使用卷積核處理的在實際的卷積網路中,一般對於這個函式的輸出,還要使用激勵函式進行去線性化,在CNN中,最常用的啟用函式是 ReLU函式。

3.卷積神經網路的結構

瞭解了CNN中最重要的卷積核的概念,接著來看CNN的結構:

在這裡插入圖片描述

這裡最後有一個softmax處理的過程,這是一個分類模型的結構,CNN結構有很多劃分,雖然看著不同,但實際上都是大同小異,這張圖片比較清楚地展示了CNN 地結構,CNN 網路一般來說,包括這五個部分:

  • 輸入層 INPUT
  • 卷積層 CONV
  • 啟用函式層 RELU
  • 池化層 POOL
  • 全連線層 FC

不過注意不要簡單地理解所有的卷積網路都是隻有五層,對於大部分卷積網路,都會交替地用到中間地四層結構,也就是呈現出一種 卷積層-啟用函式層-池化層-卷積層=啟用函式層-池化層…地交替結構,當然,對於一些新出現地卷積網路,連池化層都省去了,以上五層結構只是一般會出現的層次。

輸入層

整個網路的輸入,一般是一張圖象地畫素矩陣,在上面的圖中,可以看到輸入是一個立體的結構,這是因為一般的影象都會有一個深度的概念,就像我們一般見到的RGB的彩色影象,就是 a*b*c的形式,其中前兩維指定的是影象的長和寬,第三維則是深度,彩色RGB的深度是3,而之前我們見到的MNIST中的黑白影象的深度是 1.

卷積層

這一層的主要部分就是進行卷積操作,前面已經介紹了卷積核的概念,卷積層實際上就是實現了這個卷積核的計算過程,在這一層中,可能會見到以下的幾種關鍵詞:

  • 濾波器 Filter,我的理解就是實現前面定義的卷積核的神經元。

  • 步長 Stride:前面提到了對於一個區域,在進行計算完成之後要進行滑動,滑動的時候的的移動距離也就是這個Stride了

  • 填充 Padding: 考慮上面卷積地計算過程,對於影象靠近中間部分的畫素,我們可以看出,會被 “重疊” 地計算很多次,相比之下,邊緣地畫素呢?只被計算了一次,這有點太不公平了啊。怎麼讓它也能享受到 多次計算呢?就是在邊緣填充一些值這樣就好了嘛:

在這裡插入圖片描述

注意這裡的填充值都是0,顯然Padding的值不是我們需要的,所以不讓他們的值影響網路,所以要使用0. 除了保持邊界資訊,其實還有一個用處:補齊輸入資料的差異,也很好理解對吧,如果size不一樣,那麼在小地圖片周圍進行填充就可以了。

  • 深度 Depth:這裡的深度不是指影象,而是指某一層中神經元(濾波器)的個數,這個怎麼理解呢?不妨繼續看看卷積層處理之後的結果,我們看結構圖中,此時輸出的不是一張特徵圖,而是幾張特徵圖組成的一個立體,一個Filter可以將輸入影象處理成一張Feature Map,這裡說明一下,不同的 Filter 重點處理的特徵是不同的,就好像 “各司其職”, 比方說輸入一張貓的影象,有的 Filter 對耳朵敏感,有的則是對眼睛敏感,我們想要得到不同的這些特徵圖,所以設定了多個 Filter ,這樣每個 Filter 處理得到一張 Feature Map ,那麼多個 Filter 就會得到多個Feature Map, 將這些Feature Map 疊在一起就是輸出的立體了,所以可以看到,Filter 與 Feature Map的數量是一樣的,這個數量,就是 深度。

除了這些引數之外,我們還要考慮一個問題,其實答案也非常明顯,為什麼要進行卷積層的處理? 將若干個資料點處理為一個數據,也就是 “特徵提取” 的過程了。關於這個特徵提取的過程理解,可以關注這個問題,下面的解答很清楚:

激勵函式層

也可以把這個單獨寫成一層吧,實際中,使用啟用函式處理往往是與之前的卷積層繫結在一起的,這個作用其實也就是是啟用函式的作用了,進行去線性化嘛,在卷積網路中,一般使用的激勵函式是 ReLu 函式,注意大多數情況下都不會使用 Sigmoid函式處理。

池化層

池化層(Pooling Layer)雖然名字怪怪的,實際上相比之前的卷積層更好計算,它作用在 Feature Map 上,相當於對輸入矩陣的尺寸進一步濃縮,也就是進一步提取特徵:

在這裡插入圖片描述

計算類似卷積,通過一個類似Filter的結構進行不斷地移動(Stride就等於Filter地長度)只是過程簡單多了。對於這個區域地計算,不再是使用加權和地形式,而是採用簡單的最大值、平均值的方式,使用最大值的稱為最大池化層(max pooling), 使用平均值的稱為平均池化層(mean pooling),這是一個最大池化計算的例子:

在這裡插入圖片描述

就像在圖中 取定 2*2 的區域 ,那麼第一個區域的結果就是:
max(1,1,5,6)=6 max(1, 1,5, 6) = 6
其餘的以此類推。

與卷積層一樣,我們為什麼使用池化層呢?,一般來說,池化層有以下幾個功能:

  1. 對 Feature Map 又進行一次特徵提取,這也是減小資料量的操作
  2. 獲取更抽象的特徵,防止過擬合,提高泛化性
  3. 經過這個處理,對輸入的微小變化有更大的容忍,也就是說如果資料有一些噪音,那麼經過這個特徵提取的過程,就一定程度上減小了噪音的影響。

最後一點要注意的是,池化層並非是卷積網路所必需的。一些新的CNN網路設計時候並沒有使用池化層。

全連線層

在一開始的結構圖中可以看出, CNN網路還有一個特點 : 可能有多輪 卷積層 和池化層的處理,這時候,模型已經將影象輸入處理成了資訊含量更高的特徵,為了實現分類的任務(一般是分類,當然也會有其他的任務),需要使用全連線層來完成分類任務。

4.幾個問題

劃分了整個結構,卷積網路的計算流程也就梳理了一遍,接下來記錄一些我在學習中遇到的一些問題吧,前面只是形式化的一些內容,這裡才是乾貨:

如何計算輸出的 Feature Map 的 shape?

設:

  • 輸入資料的長寬分別是 、h_in、w_in
  • Filter 的寬度是 f
  • Padding 是 pp
  • 輸出資料的長寬分別是 houtwouth_out、 w_out
  • 步長 stride 是 ss

那麼輸出的特徵圖的長度可以表示為(寬度的計算方式也是一樣的):
hout=hinf+2ps+1 h_out = \frac{h_in-f+2p}{s}+1
在證明上,直接根據變化前後邊長的等量關係建立方程求解即可。

相較於全連線網路,為什麼卷積網路可以更好地處理影象資料?

全連線網路的特點就是所有的輸入資訊都會對之後的訓練都影響,但是對於影象資料,這樣是沒有意義的,比如對於一張圖片,資料呈現的區域特點,比如一張貓的影象,耳朵附近的資料點彼此會有關聯,但是尾巴處的資訊對耳朵就幾乎沒有影響了,基於這個,卷積網路有兩個很重要的概念:

  • 區域性感受野
  • 權值共享
    在上面提到過這兩個概念,對於區域性感受野,或者說是感受野,是借鑑的生物學上的概念,在這裡其實就是指卷積核作用的那個區域,圖解:
    在這裡插入圖片描述

對於後層的結果,就比如桃紅色的那個格子,它的感受野就是黃色的那一片,也就是壓縮前的那一塊區域。區域性感受野的特點其實就是我所說的一張圖片距離很遠的點關聯很小,所以我們就相當於從 全連線方式 省下了一部分引數,只進行區域性運算,所以引數就少了嘛。
對於“權值共享”, 實際上就是對於一張影象,計算的方式一樣,也就是特徵提取的方式一樣,這個過程就是 我們拿著卷積核的那個框框 ,不斷在原輸入影象上滑動的過程 ,所有框框內部的資料計算方式一樣,這就是 “引數共享”,這樣就大大減少了引數值,畢竟權重都是一樣的嘛。
當然在使用中,有時候引數還是太多,收斂還是太慢,這時候還有其他的方式,比如dropout等等,隨機 “殺死”一些神經元,計算就更快了。
這麼看來,卷積計算“提取特徵”就像是一個篩子,從原影象上一點一點地移動,把符合條件地區域“篩出來”。

參考資料

在學習的過程中,收藏了一些資料,畢竟我的這次記錄,也都是來源於此,在這列出來:

卷積神經網路CNN的總結 :比較全面地總結了整個CNN地基礎知識
卷積神經網路地理解:介紹了一些CNN中的問題
如何通俗解釋卷積:知乎大佬們對卷積的理解
如何通俗易懂地解釋卷積也是對卷積地解釋,這裡重點說了離散卷積地概念,可以看一看

參考的視訊資料是經典的斯坦福機器學習公開課視訊和唐宇迪的機器學習視訊。

參考的書籍資料:
我在學習TensorFlow,所以很多參考地資料都是來源於TensorFlow中的卷積網路介紹,
《TensorFlow實戰:Google深度學習框架》
《白話深度學習與TensorFlow》
這裡還要重點推薦一本書:
《解析卷積神經網路——深度學習實踐手冊》
這本書可能沒有實體書,作者是魏秀參,這本書從淺入深,很全面的介紹了CNN,後面還有很多實用中使用的技巧,這本書脫離了某種框架,著重是在原理上介紹,寫的很好,我還在學習中,推薦給大家。網上應該會有很多資源。

以上~