基礎(chǔ)篇
吳教授的CNN課堂:基礎(chǔ)篇 | 卷積和池化
第二周是關(guān)于卷積網(wǎng)絡(luò)(CNN)進階部分,學到挺多新東西。因為之前了解過CNN基礎(chǔ)后,就大多在用RNN進行自然語言處理方面的研究,很多CNN的最新進展雖有耳聞,但是并不清楚。
特別是各個論文模型又喜歡取一些奇怪的名字(比如昨天讀的兩篇論文,一個叫NTT,一個叫TMD),如果沒讀過論文,不了解一些緣由,真是傻傻分不清。
之前看視覺問答時,預(yù)處理圖片部分需選擇訓練好的網(wǎng)絡(luò),結(jié)果一看,一大堆什么VGG、Res、Incept這些看不懂的名詞,而且后面還加著16、19、101等數(shù)字和V1、V2、V3這樣的版本數(shù)。結(jié)果只能兩眼一抹黑,參考別人的論文,瞎選了一個。
閑話不多說,開始吧。
那些曾經(jīng)輝煌過的Net
在提到之后的ResNet和Inception Net前,最好先回顧一下CNN里面成功架構(gòu)的發(fā)展,這樣就可以把握住一條清晰的發(fā)展脈絡(luò),之后講解進階網(wǎng)絡(luò)的時候也能很快理解。
首先是爺爺級的LeNet-5,因為這大概是20年前提出來的了。是當時尚且青澀,而現(xiàn)在已是深度學習四大天王里的LeCun提出的,LeNet也是取自他名字前半截,5表示只有五層,當時用于處理MNIST這樣的手寫數(shù)字識別。
在基礎(chǔ)課里面吳教授也有親手把整個架構(gòu)畫出來,所以并不是很復(fù)雜。分別卷積和池化兩次后,然后直接輸入全連接網(wǎng)絡(luò)就可以了。
LeNet后,因為人工智能寒冬,所以很長時間并沒有太大發(fā)展。
直到13年的時候,后起之秀Alex Krizhevsky (相信不少人也看過他的博客,聽過他有名的Stanford cs231) 提出了AlexNet,在ImageNet比賽上取得了很大的成功,向大家展示了深度學習的力量,從此掀起一次浪潮。
AlexNet和LeNet差別并不是很大,主要不同有以下三點。
- 卷積層過濾器大小的一些變化,網(wǎng)絡(luò)層數(shù)也多了些;
- 使用了ReLU激活函數(shù);
- 在當時用了兩個GPU來訓練;
在AlexNet展示了深度學習在圖像處理上的成功后,大家也就開始不斷在其之上完善圖像處理的CNN構(gòu)架。而VGG就是第一個非常簡潔又系統(tǒng)化,提出了一套怎么使用更深的網(wǎng)絡(luò)來訓練的網(wǎng)絡(luò)架構(gòu)。
VGG的創(chuàng)舉之點在于,比起之前那些網(wǎng)絡(luò)其中參數(shù)的混雜,它很有計劃和條理地布置了架構(gòu)中各個層的結(jié)構(gòu)。比如說可以列舉出一下幾點:
- 卷積層一定用3x3的過濾器,填充用"same",步長選擇1;
- 池化層一定用2x2的窗口大小,步長選擇2;
- 還有就是把整個網(wǎng)絡(luò)分成幾個大的部分,每部分都是卷積加池化,并且每部分過濾器的個數(shù)也有規(guī)律的增加,像這樣
64 -> 128 -> 256 -> 512 -> 512
。
VGG是當時參賽組(Visual Geometry Group)的名稱。一般現(xiàn)在大家用到的都是VGG-16或者VGG-19,16和19也正如所想,分別是對應(yīng)的VGG版本中的層數(shù)。
看上去16和19層好像也很多了,但和之后ResNet這樣的動不動就101,152層的巨無霸相比,還是小巫見大巫。
那為什么不也增加VGG的層數(shù)呢?
這里要提到深層神經(jīng)網(wǎng)絡(luò)訓練中的一個大問題了,那就是當層數(shù)過大時,會產(chǎn)生所謂的梯度爆炸(Exploding Gradients)和梯度消失(Vanishing Gradients)現(xiàn)象。
打個比方,如果每次的梯度相乘的系數(shù)都是小于1的數(shù),假如說0.6, 那么19 層算下來,0.6的19次方就已經(jīng)是0.00061了,更別提上百層了。這樣傳播到最底層的時候,能夠學習到的參數(shù)就很小了,這就是梯度消失。
反過來,梯度爆炸的情況,如果系數(shù)大于1,多次累乘后就會得到一個很大的數(shù),也會造成不好的結(jié)果。有點像是復(fù)利的概念,也就是那個和國王打賭要一棋盤稻子的故事。
梯度爆炸還好解決,可以用梯度修剪(Gradient Clipping)修剪一下就好了。而梯度消失就有點難解決了。
因為這樣的問題,所以雖然理論上普通的深處網(wǎng)絡(luò)是越深學的越好,但是實際上卻事與愿違。下圖橫軸是網(wǎng)絡(luò)層數(shù),豎軸是訓練誤差(越小越好)。理論上隨著層數(shù)增加,誤差就減小,但是實際是過了某個點之后,誤差反而會增大。
那么ResNet是怎么訓練到上百層的呢,難道它就不怕上面的問題嗎?
它用一個很簡單的方法解決了上面的問題。
殘差網(wǎng)絡(luò) (ResNet)
有很多很棒的論文,沒讀之前,看名字覺得很厲害的。但結(jié)果一看論文,才發(fā)現(xiàn)方法非常之簡潔,特別是有一些利用數(shù)學知識推導(dǎo)出的簡單解決方法,讓人不得不一邊拍手稱贊,一邊感嘆自己數(shù)學渣。
ResNet也是這樣子的,看名字很酷炫,但是打開論文一看,才發(fā)現(xiàn)原來是這樣啊。
ResNet的最主要就是Shortcut(捷徑)這個概念。來看看這到底是什么吧,首先假設(shè)我們從一個神經(jīng)網(wǎng)絡(luò)中取出兩層,當做是一個塊(block),先不管中間是MLP或者是CNN。
而shortcut就如下圖一樣,從第一層的輸入直接建立一條捷徑到第二層的輸出,激活函數(shù)前。
也就是說第二層激活后的輸出可以會發(fā)生這樣的變化。
由
變成
這樣子處理之后,我們得到的這一小塊就叫做Residual Block(殘差塊),而把這些塊堆疊起來就是我們的殘差網(wǎng)絡(luò)了。很簡單吧,像下面這樣,一個34層的殘差網(wǎng)絡(luò)。
這樣子我們就得到殘差網(wǎng)絡(luò),那么實際上訓練會怎么樣呢。
正是我們想要的模型,也非常符合理論。
最后再提一下殘差網(wǎng)絡(luò)背后的原理,為什么這樣簡單改一下就能夠有這么好的表現(xiàn)呢。
原因是捷徑的建立,使得每一個殘差塊可以很容易地學習到恒等函數(shù),也就是f(x)=x。也就是說加入殘差塊之后,再差也能學會恒等函數(shù),保留信息,把之前的結(jié)果直接這樣傳下去,所以也就不用擔心之前提到的梯度消失問題了。
Inception網(wǎng)絡(luò)
1x1卷積
介紹Inception網(wǎng)絡(luò)前,先介紹一下其中一個很重要的概念1x1卷積。
初看1x1卷積的概念會覺得很奇怪,這樣子每次對一個像素進行卷積有什么用,我們本來不就是想檢測局部的特征嗎。但是如果理解了通道概念的話,就能很好理解了。
因為,如果說普通的大窗口卷積更注重一個通道內(nèi)各個特征的互動的話,那么1x1卷積就是只在通道與通道進行卷積運算,加強了通道之間的互動。
這就是第一點,加強了通道與通道之間的交流。用這個就可以只對通道進行一些操作,如用1x1卷積增加通道數(shù),減少通道數(shù),也可以不增不減,但是對之前的通道進行整理。
1x1卷積網(wǎng)絡(luò)還有一個好處,那就是通過合理運用可以減少整體網(wǎng)絡(luò)的運算量。
還是來舉例子吧,假設(shè)有以下一個卷積過程。
那么上面這個過程所需要的運算量大約一億兩千萬次。
而如果我們巧妙地利用1x1卷積來對通道進行合理處理的話,像下面這樣。
運算量會變得只有大概一千二百萬左右,一下子就縮小了十倍。
什么是Inception網(wǎng)絡(luò)
有了上面的知識以后,一切就簡單多了。Inception網(wǎng)絡(luò)的核心概念是,既然在選擇CNN架構(gòu)的時候要為了過濾器的窗口大小考慮半天,那么何不把各個尺寸都用上去,最后再把結(jié)果接起來就好了呢。
于是就有了下面這樣的Inception模塊。有用1x1、3x3、5x5各個尺寸的卷積,而且還用到之前講到的利用1x1卷積減少運算量的技巧。
最后至于整個Inception網(wǎng)絡(luò),就像之前殘差網(wǎng)絡(luò)一樣,把Inception模塊堆疊起來就好了。
當然論文中還有一些次要細節(jié),這里就不多說了。
而且自最初的論文之后,Inception網(wǎng)絡(luò)也有很多改進,加入了很多技巧,比如之前的殘差網(wǎng)絡(luò)中的技巧。所以現(xiàn)在網(wǎng)上的Inception網(wǎng)絡(luò),后面會有V1、V2、V3之類后綴,表示的就是各個版本。
深一點,再深一點(不要想歪)
最后,作為余談,說說為什么Inception網(wǎng)絡(luò)要叫做Inception網(wǎng)絡(luò)。
因為在這篇正經(jīng)的學術(shù)論文里面,作者引用了一個鏈接,點開后會出現(xiàn)這張圖片。