1. 什么是CNN
卷積神經網絡(Convolutional Neural Networks, CNN)是一類包含卷積計算且具有深度結構的前饋神經網絡(Feedforward Neural Networks),是深度學習(deep learning)的代表算法之一。
我們先來看卷積神經網絡各個層級結構圖:
上圖中CNN要做的事情是:給定一張圖片,是車還是馬未知,是什么車也未知,現在需要模型判斷這張圖片里具體是一個什么東西,總之輸出一個結果:如果是車 那是什么車。
- 最左邊是數據輸入層(input layer),對數據做一些處理,比如去均值(把輸入數據各個維度都中心化為0,避免數據過多偏差,影響訓練效果)、歸一化(把所有的數據都歸一到同樣的范圍)、PCA/白化等等。CNN只對訓練集做“去均值”這一步。
- CONV:卷積計算層(conv layer),線性乘積求和。
- RELU:激勵層(activation layer),下文有提到:ReLU是激活函數的一種。
- POOL:池化層(pooling layer),簡言之,即取區域平均或最大。
- FC:全連接層(FC layer)。
這幾個部分中,卷積計算層是CNN的核心。
1.1 輸入層
在做輸入的時候,需要把圖片處理成同樣大小的圖片才能夠進行處理。
常見的處理數據的方式有:
-
去均值(常用)
- AlexNet:訓練集中100萬張圖片,對每個像素點求均值,得到均值圖像,當訓練時用原圖減去均值圖像。
- VGG:對所有輸入在三個顏色通道R/G/B上取均值,只會得到3個值,當訓練時減去對應的顏色通道均值。(此種方法效率高)
TIPS:在訓練集和測試集上減去訓練集的均值。
-
歸一化
幅度歸一化到同樣的范圍。
-
PCA/白化(很少用)
- 用PCA降維
- 白化是對數據每個特征軸上的幅度歸一化。
1.2 卷積計算層(conv)
對圖像(不同的數據窗口數據)和濾波矩陣(一組固定的權重:因為每個神經元的多個權重固定,所以又可以看做一個恒定的濾波器filter)做內積(逐個元素相乘再求和)的操作就是所謂的『卷積』操作,也是卷積神經網絡的名字來源。
濾波器filter是什么呢!請看下圖。圖中左邊部分是原始輸入數據,圖中中間部分是濾波器filter,圖中右邊是輸出的新的二維數據。
不同的濾波器filter會得到不同的輸出數據,比如顏色深淺、輪廓。相當于提取圖像的不同特征,模型就能夠學習到多種特征。用不同的濾波器filter,提取想要的關于圖像的特定信息:顏色深淺或輪廓。如下圖所示。
在CNN中,濾波器filter(帶著一組固定權重的神經元)對局部輸入數據進行卷積計算。每計算完一個數據窗口內的局部數據后,數據窗口不斷平移滑動,直到計算完所有數據。這個過程中,有這么幾個參數:
- 深度depth:神經元個數,決定輸出的depth厚度。同時代表濾波器個數。
- 步長stride:決定滑動多少步可以到邊緣。
- 填充值zero-padding:在外圍邊緣補充若干圈0,方便從初始位置以步長為單位可以剛好滑倒末尾位置,通俗地講就是為了總長能被步長整除。
-
參數共享機制
假設每個神經元連接數據窗的權重是固定對的。固定每個神經元連接權重,可以看做模板,每個神經元只關注一個特性(模板),這使得需要估算的權重個數減少:一層中從1億到3.5萬。
一組固定的權重和不同窗口內數據做內積:卷積
作用在于捕捉某一種模式,具體表現為很大的值。
卷積操作的本質特性包括稀疏交互和參數共享。
1.3 激勵層
把卷積層輸出結果做非線性映射。
激活函數有:
[圖片上傳失敗...(image-47fc39-1565506634323)]
- sigmoid:在兩端斜率接近于0,梯度消失。
- ReLu:修正線性單元,有可能出現斜率為0,但概率很小,因為mini-batch是一批樣本損失求導之和。
TIPS:
- CNN慎用sigmoid!慎用sigmoid!慎用sigmoid!
- 首先試RELU,因為快,但要小心點。
- 如果RELU失效,請用 Leaky ReLU或者Maxout。
- 某些情況下tanh倒是有不錯的結果,但是很少。
1.4 池化層
也叫下采樣層,就算通過了卷積層,緯度還是很高 ,需要進行池化層操作。
- 夾在連續的卷積層中間。
- 壓縮數據和參數的量,降低維度。
- 減小過擬合。
- 具有特征不變性。
方式有:Max pooling、average pooling
Max pooling
取出每個部分的最大值作為輸出,例如上圖左上角的4個黃色方塊取最大值為3作為輸出,以此類推。
average pooling
每個部分進行計算得到平均值作為輸出,例如上圖左上角的4個黃色方塊取得平均值2作為輸出,以此類推。
1.5 全連接層
全連接層的每一個結點都與上一層的所有結點相連,用來把前邊提取到的特征綜合起來。由于其全連接的特性,一般全連接層的參數也是最多的。
- 兩層之間所有神經元都有權重連接
- 通常全連接層在卷積神經網絡尾部
1.6 層次結構小結
CNN層次結構 | 作用 |
---|---|
輸入層 | 卷積網絡的原始輸入,可以是原始或預處理后的像素矩陣 |
卷積層 | 參數共享、局部連接,利用平移不變性從全局特征圖提取局部特征 |
激活層 | 將卷積層的輸出結果進行非線性映射 |
池化層 | 進一步篩選特征,可以有效減少后續網絡層次所需的參數量 |
全連接層 | 用于把該層之前提取到的特征綜合起來。 |
1.7 CNN優缺點
優點:
- 共享卷積核,優化計算量。
- 無需手動選取特征,訓練好權重,即得特征。
- 深層次的網絡抽取圖像信息豐富,表達效果好。
- 保持了層級網絡結構。
- 不同層次有不同形式與功能。
缺點:
- 需要調參,需要大樣本量,GPU等硬件依賴。
- 物理含義不明確。
與NLP/Speech共性:
都存在局部與整體的關系,由低層次的特征經過組合,組成高層次的特征,并且得到不同特征之間的空間相關性。
2. 典型CNN發展歷程
- LeNet,這是最早用于數字識別的CNN
- AlexNet, 2012 ILSVRC比賽遠超第2名的CNN,比LeNet更深,用多層小卷積層疊加替換單大卷積層。
- ZF Net, 2013 ILSVRC比賽冠軍
- GoogLeNet, 2014 ILSVRC比賽冠軍
- VGGNet, 2014 ILSVRC比賽中的模型,圖像識別略差于GoogLeNet,但是在很多圖像轉化學習問題(比如objectdetection)上效果很好
- ResNet(深度殘差網絡(Deep Residual Network,ResNet)), 2015ILSVRC比賽冠軍,結構修正(殘差學習)以適應深層次CNN訓練。
- DenseNet, CVPR2017 best paper,把ResNet的add變成concat
3. 圖像相關任務
3.1 圖像識別與定位
-
classification:C個類別識別
- input:Image
- Output:類別標簽
- Evaluation metric:準確率
-
Localization定位)
Input:Image
Output:物體邊界框(x,y,w,h)
-
Evaluation metric:交并準則(IOU) > 0.5 圖中陰影部分所占面積
image
3.1.1 思路1:識別+定位過程
識別可以看作多分類問題(用softmax),用別人訓練好的CNN模型做fine-tune
-
定位的目標是(x,y,w,h)是連續值,當回歸問題解決(mse)
在1的CNN尾部展開(例如把最后一層拿開),接上一個(x,y,w,h)的神經網絡,成為classification+regression的模型。
更細致的識別可以提前規定好有k個組成部分,做成k個部分的回歸,
例如:框出兩只眼睛和兩條腿,4元祖*4=16(個連續值)
Regression部分用歐氏距離損失,使用SGD訓練。
3.1.2 思路2:圖窗+識別
- 類似剛才的classification+regression思路
- 咱們取不同大小的“框”
- 讓框出現在不同的位置
- 判定得分
- 按照得分的高低對“結果框”做抽樣和合并
3.2 物體檢測(object detection)
3.2.1 過程
當圖像有很多物體怎么辦的?難度可是一下暴增啊。
那任務就變成了:多物體識別+定位多個物體,那把這個任務看做分類問題?
看成分類問題有何不妥?
- 你需要找很多位置, 給很多個不同大小的框
- 你還需要對框內的圖像分類
- 當然, 如果你的GPU很強大, 恩, 那加油做吧…
邊緣策略:想辦法先找到可能包含內容的圖框(候選框),然后進行分類問題的識別。
方法:根據RGB值做區域融合。fast-CNN,共享圖窗,從而加速候選框的形成。
-
R-CNN => fast-CNN => faster-RCNN 速度對比
image
3.2.2 R-CNN
R-CNN的簡要步驟如下:
- 輸入測試圖像。
- 利用選擇性搜索Selective Search算法在圖像中從下到上提取2000個左右的可能包含物體的候選區域Region Proposal。
- 因為取出的區域大小各自不同,所以需要將每個Region Proposal縮放(warp)成統一的227x227的大小并輸入到CNN,將CNN的fc7層的輸出作為特征。
- 將每個Region Proposal提取到的CNN特征輸入到SVM進行分類。
3.2.3 SPP-Net
SPP:Spatial Pyramid Pooling(空間金字塔池化),SPP-Net是出自2015年發表在IEEE上的論文。
眾所周知,CNN一般都含有卷積部分和全連接部分,其中,卷積層不需要固定尺寸的圖像,而全連接層是需要固定大小的輸入。所以當全連接層面對各種尺寸的輸入數據時,就需要對輸入數據進行crop(crop就是從一個大圖扣出網絡輸入大小的patch,比如227×227),或warp(把一個邊界框bounding box(紅框)的內容resize成227×227)等一系列操作以統一圖片的尺寸大小,比如224224(ImageNet)、3232(LenNet)、96*96等。
所以才如你在上文中看到的,在R-CNN中,“因為取出的區域大小各自不同,所以需要將每個Region Proposal縮放(warp)成統一的227x227的大小并輸入到CNN”。
但warp/crop這種預處理,導致的問題要么被拉伸變形、要么物體不全,限制了識別精確度。沒太明白?說句人話就是,一張16:9比例的圖片你硬是要Resize成1:1的圖片,你說圖片失真不?
SPP Net的作者Kaiming He等人逆向思考,既然由于全連接FC層的存在,普通的CNN需要通過固定輸入圖片的大小來使得全連接層的輸入固定。那借鑒卷積層可以適應任何尺寸,為何不能在卷積層的最后加入某種結構,使得后面全連接層得到的輸入變成固定的呢?
這個“化腐朽為神奇”的結構就是spatial pyramid pooling layer。
它的特點有兩個:
-
結合空間金字塔方法實現CNNs的多尺度輸入。
SPP Net的第一個貢獻就是在最后一個卷積層后,接入了金字塔池化層,保證傳到下一層全連接層的輸入固定。
換句話說,在普通的CNN機構中,輸入圖像的尺寸往往是固定的(比如224*224像素),輸出則是一個固定維數的向量。SPP Net在普通的CNN結構中加入了ROI池化層(ROI Pooling),使得網絡的輸入圖像可以是任意尺寸的,輸出則不變,同樣是一個固定維數的向量。
簡言之,CNN原本只能固定輸入、固定輸出,CNN加上SSP之后,便能任意輸入、固定輸出。神奇吧?
-
只對原圖提取一次卷積特征
在R-CNN中,每個候選框先resize到統一大小,然后分別作為CNN的輸入,這樣是很低效的。
而SPP Net根據這個缺點做了優化:只對原圖進行一次卷積計算,便得到整張圖的卷積特征feature map,然后找到每個候選框在feature map上的映射patch,將此patch作為每個候選框的卷積特征輸入到SPP layer和之后的層,完成特征提取工作。
如此這般,R-CNN要對每個區域計算卷積,而SPPNet只需要計算一次卷積,從而節省了大量的計算時間,比R-CNN有一百倍左右的提速。
3.2.4 Fast R-CNN
SPP Net真是個好方法,R-CNN的進階版Fast R-CNN就是在R-CNN的基礎上采納了SPP Net方法,對R-CNN作了改進,使得性能進一步提高。
R-CNN有一些相當大的缺點(把這些缺點都改掉了,就成了Fast R-CNN)。
大缺點:由于每一個候選框都要獨自經過CNN,這使得花費的時間非常多。
解決:共享卷積層,現在不是每一個候選框都當做輸入進入CNN了,而是輸入一張完整的圖片,在第五個卷積層再得到每個候選框的特征。
原來的方法:許多候選框(比如兩千個)-->CNN-->得到每個候選框的特征-->分類+回歸
現在的方法:一張完整圖片-->CNN-->得到每張候選框的特征-->分類+回歸
所以容易看見,Fast R-CNN相對于R-CNN的提速原因就在于:不過不像R-CNN把每個候選區域給深度網絡提特征,而是整張圖提一次特征,再把候選框映射到conv5上,而SPP只需要計算一次特征,剩下的只需要在conv5層上操作就可以了。
算法步驟:
- 在圖像中確定約1000-2000個候選框 (使用選擇性搜索)。
- 對整張圖片輸進CNN,得到feature map。
- 找到每個候選框在feature map上的映射patch,將此patch作為每個候選框的卷積特征輸入到SPP layer和之后的層。
- 對候選框中提取出的特征,使用分類器判別是否屬于一個特定類。
- 對于屬于某一類別的候選框,用回歸器進一步調整其位置。
3.2.5 Faster R-CNN
Fast R-CNN存在的問題:存在瓶頸:選擇性搜索,找出所有的候選框,這個也非常耗時。那我們能不能找出一個更加高效的方法來求出這些候選框呢?
解決:加入一個提取邊緣的神經網絡,也就說找到候選框的工作也交給神經網絡來做了。
所以,rgbd在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同時引入anchor box應對目標形狀的變化問題(anchor就是位置和大小固定的box,可以理解成事先設置好的固定的proposal)。這就是Faster R-CNN。
算法步驟:
- 對整張圖片輸進CNN,得到feature map。
- 卷積特征輸入到RPN,得到候選框的特征信息。
- 對候選框中提取出的特征,使用分類器判別是否屬于一個特定類。
- 對于屬于某一類別的候選框,用回歸器進一步調整其位置。
3.2.6 YOLO
Faster R-CNN的方法目前是主流的目標檢測方法,但是速度上并不能滿足實時的要求。YOLO一類的方法慢慢顯現出其重要性,這類方法使用了回歸的思想,利用整張圖作為網絡的輸入,直接在圖像的多個位置上回歸出這個位置的目標邊框,以及目標所屬的類別。
我們直接看上面YOLO的目標檢測的流程圖:
- 給個一個輸入圖像,首先將圖像劃分成7*7的網格。
- 對于每個網格,我們都預測2個邊框(包括每個邊框是目標的置信度以及每個邊框區域在多個類別上的概率)。
- 根據上一步可以預測出772個目標窗口,然后根據閾值去除可能性比較低的目標窗口,最后NMS去除冗余窗口即可。
小結:YOLO將目標檢測任務轉換成一個回歸問題,大大加快了檢測的速度,使得YOLO可以每秒處理45張圖像。而且由于每個網絡預測目標窗口時使用的是全圖信息,使得false positive比例大幅降低(充分的上下文信息)。
但是YOLO也存在問題:沒有了Region Proposal機制,只使用7*7的網格回歸會使得目標不能非常精準的定位,這也導致了YOLO的檢測精度并不是很高。
3.2.7 SSD
SSD: Single Shot MultiBox Detector。上面分析了YOLO存在的問題,使用整圖特征在7*7的粗糙網格內回歸對目標的定位并不是很精準。那是不是可以結合region proposal的思想實現精準一些的定位?SSD結合YOLO的回歸思想以及Faster R-CNN的anchor機制做到了這點。
上圖是SSD的一個框架圖,首先SSD獲取目標位置和類別的方法跟YOLO一樣,都是使用回歸,但是YOLO預測某個位置使用的是全圖的特征,SSD預測某個位置使用的是這個位置周圍的特征(感覺更合理一些)。
那么如何建立某個位置和其特征的對應關系呢?可能你已經想到了,使用Faster R-CNN的anchor機制。如SSD的框架圖所示,假如某一層特征圖(圖b)大小是8*8,那么就使用3*3的滑窗提取每個位置的特征,然后這個特征回歸得到目標的坐標信息和類別信息(圖c)。
不同于Faster R-CNN,這個anchor是在多個feature map上,這樣可以利用多層的特征并且自然的達到多尺度(不同層的feature map 3*3滑窗感受野不同)。
小結:SSD結合了YOLO中的回歸思想和Faster R-CNN中的anchor機制,使用全圖各個位置的多尺度區域特征進行回歸,既保持了YOLO速度快的特性,也保證了窗口預測的跟Faster R-CNN一樣比較精準。SSD在VOC2007上mAP可以達到72.1%,速度在GPU上達到58幀每秒。
3.3 語義(圖像)分割
識別圖上pixel的類別,用全卷積網絡。
4. 代碼實現CNN
5. 參考文獻
作者:@mantchs
GitHub:https://github.com/NLP-LOVE/ML-NLP
歡迎大家加入討論!共同完善此項目!群號:【541954936】點擊進入