CNN研究的歷史
私以為,神經(jīng)網(wǎng)絡(luò)這一大類的算法,是仿生學(xué)與數(shù)學(xué)結(jié)合的一次突破,不管是最原始的神經(jīng)網(wǎng)絡(luò)還是現(xiàn)在非常常見各種變種,都是在參考人類大腦的某一工作原理的工作方式,并將其轉(zhuǎn)化為數(shù)學(xué)模型的表達.
舉個最簡單的栗子,本文提到的卷積神經(jīng)網(wǎng)絡(luò)CNN, 里面有一個非常重要的概念叫做感受野,其來源是1968年的一篇研究貓與猴子視覺皮層的論文,生物學(xué)家將視覺皮層中對視野的小區(qū)域單獨反應(yīng)的神經(jīng)元稱為感受野,相鄰細胞具有相似和重疊的感受野.
受這個概念的啟發(fā),在然后是1980年,神經(jīng)感知機(neocognitron)的提出,標(biāo)志了第一個初始的卷積神經(jīng)網(wǎng)絡(luò)的誕生,后續(xù)的二十多年,又經(jīng)過多位研究人員的改進.在2005年有學(xué)者完成了GPU上的CNN實現(xiàn).再往后,隨著CPU與GPU算力的提升,更深層次的神經(jīng)網(wǎng)絡(luò)訓(xùn)練變成現(xiàn)實.
2012年是神經(jīng)網(wǎng)絡(luò)研究突飛猛進的一年,隨著AlexNet在ImageNet競賽中奪魁,并驚人的把錯誤率記錄從26%降低到15%,CNN研究正式起飛了.當(dāng)然,最初是lecun大佬用lenet識別手寫數(shù)字,大佬今年也因為這些計算機視覺上的研究獲圖靈獎了.
未來某一天如果在人類神經(jīng)系統(tǒng)的工作原理上有了真正的突破性進展, 那隨之而來的應(yīng)該也會是深度學(xué)習(xí)領(lǐng)域的一次重大進步, 或許到那個時候才是強人工智能的時代.
CNN的基本原理
前面我們提到過感受野,研究表明大腦中的一些個體神經(jīng)元細胞只有在某個方位的邊緣存在的情況下才會響應(yīng). 對應(yīng)到視覺來說.人在識別物體時靠的是檢測物體的一些邊緣.
比如說,在白紙上畫個最簡單的人臉,人眼怎么知道這是個人臉?有兩個圈代表眼鏡,有一個圈代表鼻子,還有一個橢圓代表嘴,當(dāng)然還有一個外部輪廓,就是大臉.

現(xiàn)在我們知道了圖像識別的關(guān)鍵在于找某些特定的邊緣,那么有什么辦法可以使圖像的邊緣更為突出,比如說下面這兩張圖.


怎么做到的?就是卷積.
什么是卷積
它的物理意義大概可以理解為:系統(tǒng)某一時刻的輸出是由多個輸入共同作用(疊加)的結(jié)果。[1]
我最初接觸的卷積,是大學(xué)時信號與系統(tǒng)課程里的卷積公式以及概率論里根據(jù)聯(lián)合概率密度函數(shù)求分布的公式,也就是:

圖像對于計算機而言,其實是一個二維的數(shù)組,那么如何針對這個數(shù)組做卷積?下面這個圖可以很直觀地描述這個過程.

至于為何可以這樣做,包含大量信號處理的知識,可以參考[1]文中的內(nèi)容.
這張圖包含了CNN最基本的原理與網(wǎng)絡(luò)特點.
CNN的基本組成
CNN作為神經(jīng)網(wǎng)絡(luò)的一種,也同樣由輸入輸出隱藏層三種組成,其中隱藏層包含卷積層,池化層,全連接層,激勵層.下面逐一介紹各層.
輸入層
這個可以略過把.卷積層
卷積層是CNN的核心,這一層的處理方式上文已經(jīng)提到過了,不再贅述.卷積層的主要作用,在于提取更高層次特征,也就是我們之前提到過的加強邊緣.不得不感嘆一下,特征工程真的是很多機器學(xué)習(xí)任務(wù)中非常核心的步驟,而對于某些可以通用的特征提取方法,干脆就像CNN一樣融入到模型的描述里.
在前饋過程中,通過濾波器對輸入圖像進行卷積,產(chǎn)生濾波器的二維激活圖.
關(guān)于卷積層的結(jié)構(gòu),可以參考一個斯坦福的課程動態(tài)演示圖.在這-
池化層
池化層又稱為下采樣層,作用是在保持盡可能多的信息的前提下減少數(shù)據(jù)量,效果相當(dāng)于resize得到一張較為模糊的圖片.最常見的max_pooling的做法是每四個鄰域內(nèi)的像素點取一個最大值.如下圖
max_pooling示意
原本想在這里說一下tensorflow里的conv1d,conv2d的, 礙于還得講解nhwc與nchw的區(qū)別等等問題,暫時先略過.
此外,在tf里有幾個很重要的參數(shù)
卷積層參數(shù)
其中stride表示步長,也就是每一步在各維度上前進的長度.padding為表示輸入輸出的大小是否一致,same表示一致,valid表示不同.
tf里有個坑, 曾經(jīng)困擾了我一段時間,以下面代碼為例
# 定義一個矩陣a,表示需要被卷積的矩陣。
a = np.array(np.arange(1, 1 + 12).reshape([1, 6, 2]), dtype=np.float32)
# 卷積核,此處卷積核的數(shù)目為1
kernel = np.array(np.arange(1, 1 + 4), dtype=np.float32).reshape([2, 2, 1])
# 進行conv1d卷積
conv1d = tf.nn.conv1d(a, kernel, 1, 'VALID')
# 得到運行結(jié)果如下
----kernel----
[[[ 1.]
[ 2.]]
[[ 3.]
[ 4.]]]
-------a------
[[[ 1. 2.]
[ 3. 4.]
[ 5. 6.]
[ 7. 8.]
[ 9. 10.]
[ 11. 12.]]]
----conv------
[[[ 30.]
[ 50.]
[ 70.]
[ 90.]
[ 110.]]]
這里的輸入的tensor與卷積核的維度其實是不一致的,簡單地想象一下,這兩個應(yīng)該沒法做卷積運算,那背后的問題出在哪里?最初以為是nhwc的問題,特意去研究了Intel的文檔,仍然沒有找到結(jié)果.最終實在沒有辦法,查源代碼,于是發(fā)現(xiàn)了在源碼的方法注釋里有這樣一段.

仔細看一下,才能發(fā)現(xiàn),其實input與filter的維度順序是不一樣的,才會出現(xiàn)之前的問題.
這里不太清楚源碼的作者這樣做的出發(fā)點是什么,有大佬能指出就最好了.
- 全連接層
全連接層是對卷積與池化層輸出進行綜合處理的層, 網(wǎng)絡(luò)結(jié)構(gòu)與普通的神經(jīng)網(wǎng)絡(luò)隱藏層一致. - 激勵層
對池化層的輸出使用激活函數(shù),因此在池化層后需要跟一層激勵,進行非線性映射,通常使用relu(因為收斂速度快,梯度計算也簡單).這一層的首選當(dāng)然是relu,次選是leaky relu或max out, 不要使用sigmoid. - 輸出層
略過,一般接個softmax
CNN的特點
CNN的三個特點其實也來自于兩種特殊的網(wǎng)絡(luò)結(jié)構(gòu):卷積層,池化層.
- 局部感知
這里的其實說的是上文中提到的感受野的概念,因為圖像中,像素點與遠處像素點的關(guān)系并不大,所以局部感知能獲取到一定的局部特征. - 權(quán)值共享
池化層的計算,如果針對每個區(qū)域需要單獨計算感受野的權(quán)值,那么需要計算的參數(shù)數(shù)量可能是天文數(shù)字.所以,主要是基于計算復(fù)雜度的考慮,就有了權(quán)值共享這一設(shè)計. - 多卷積核
一種卷積核代表的是一種特征,為獲得更多不同的特征集合,卷積層會有多個卷積核,生成不同的特征,這也是為什么卷積后的圖片的高,每一個圖片代表不同的特征。
CNN的架構(gòu)演化
CNN的架構(gòu)演化從1990s的Lenet開始,到21世紀初的沉寂,再到alexnet煥發(fā)第二春,開始大紅大紫,主要得益于這些年來算力的提升.不得不提的就是lecun,以及NVIDIA的黃仁勛刀神,前者首創(chuàng)了使用cnn進行圖像分類并在GPU上實現(xiàn),后者極大地推動了顯卡算力的提升. 也就是因為顯卡的運算能力的提升,越來越多的深度CNN模型才能夠運行起來.下面順著每一年的ImageNet比賽簡單提幾個比較重要的模型.
-
lenet與alexnet
lenet是lecun提出的首次使用CNN進行手寫識別的網(wǎng)絡(luò)結(jié)構(gòu),并且奠定了后序CNN的基本結(jié)構(gòu),就是卷積池化全連接,
lenet結(jié)構(gòu)
現(xiàn)在常用的lenet會在池化層后接一個激勵層.
-
alexnet與ZF-net
Alexnet在2012年的ImageNet比賽中以超出第二名10.9%的優(yōu)勢奪冠,從此深度學(xué)習(xí)開始正式興起.
alexnet結(jié)構(gòu)
相對于lenet,主要的改進在于
- 更深的網(wǎng)絡(luò)
- 在池化層后使用relu激活
- dropout
- Local Responce Normalization:局部響應(yīng)歸一
zfnet是2013年的ImageNet冠軍,結(jié)構(gòu)與Alexnet基本一致,主要的工作在于....調(diào)參.
- VGG-Nets
該網(wǎng)絡(luò)是2014年定位任務(wù)的冠軍,其實也是在AlexNet的基礎(chǔ)上做的改進,因為前一年已經(jīng)有人調(diào)參改了,所以這一年...他們把網(wǎng)絡(luò)結(jié)構(gòu)加深了, 研究人員真是雞賊.當(dāng)然為了訓(xùn)練在當(dāng)時看來非常深度的網(wǎng)絡(luò),他們也在這里提出了預(yù)訓(xùn)練的方法,也就是先訓(xùn)練一部分的網(wǎng)絡(luò),等這部分穩(wěn)定之后再訓(xùn)練后面的網(wǎng)絡(luò).
至于2014年分類任務(wù)的冠軍,則是GoogleNet, 該網(wǎng)絡(luò)在加深層數(shù)的同時也做了層的創(chuàng)新,引入Inception結(jié)構(gòu)代替了單純的卷積+激活的傳統(tǒng)操作,并且后面的全連接層全部替換為簡單的全局平均pooling.
- ResNet
這個網(wǎng)絡(luò)是2015年由何愷明推出的,層數(shù)已經(jīng)由GoogleNet的22層,提升到100多層, 還在網(wǎng)絡(luò)結(jié)構(gòu)上做了很大的創(chuàng)新,引入了殘差單元來解決退化問題. - DenseNet
自Resnet提出以后,ResNet的變種網(wǎng)絡(luò)層出不窮,都各有其特點,網(wǎng)絡(luò)性能也有一定的提升。本文介紹的最后一個網(wǎng)絡(luò)是CVPR 2017最佳論文DenseNet,論文中提出的DenseNet(Dense Convolutional Network)主要還是和ResNet及Inception網(wǎng)絡(luò)做對比,思想上有借鑒,但卻是全新的結(jié)構(gòu),網(wǎng)絡(luò)結(jié)構(gòu)并不復(fù)雜,卻非常有效,在CIFAR指標(biāo)上全面超越ResNet
可以看出,隨著網(wǎng)絡(luò)層數(shù)的增長,近年來的網(wǎng)絡(luò)結(jié)構(gòu)的優(yōu)化也主要針對于梯度消失等問題進行改進.
在NLP中的應(yīng)用
NLP任務(wù)的輸入并非像素點,但是經(jīng)過詞嵌入之后,詞可以變成固定維度的向量,句子則可以變成矩陣,這個矩陣也就可以看成一個圖像,作為CNN的輸入.私以為從特征提取上來說,圖像分類與文本分類也有相似之處,圖像分類著重于提取組合的邊緣特征, 而文本分類任務(wù)中,詞的組合也具有非常重要的意義,所以使用CNN進行處理文本分類任務(wù)也具有可行性.
近年來比較有名的論文如下(摘自知乎):

我個人接觸比較多的是這一篇, 平時工作中使用的也是基于該論文的改進.后序再補充論文的閱讀筆記.
參考文獻
[1]蔣竺波.CNN 入門講解:什么是卷積(Convolution)[EB/OL].https://zhuanlan.zhihu.com/p/30994790,2018-04-20.
[2]Madcola.CNN網(wǎng)絡(luò)架構(gòu)演進:從LeNet到DenseNet[EB/OL].https://www.cnblogs.com/skyfsm/p/8451834.html,2018-02-17.
[3]jeyzhang.卷積神經(jīng)網(wǎng)絡(luò)(CNN)在句子建模上的應(yīng)用[EB/OL].http://www.jeyzhang.com/cnn-apply-on-modelling-sentence.html,2016-03-11.



