1.卷積神經(jīng)網(wǎng)絡(luò)詳解
import torch
2.卷積神經(jīng)網(wǎng)絡(luò)簡介
卷積神經(jīng)網(wǎng)絡(luò)由一個(gè)或多個(gè)卷積層和頂端的全連通層(也可以使用1x1的卷積層作為最終的輸出)組成一種前饋神經(jīng)網(wǎng)絡(luò)第岖。一般的認(rèn)為,卷積神經(jīng)網(wǎng)絡(luò)是由Yann LeCun大神在1989年提出的LeNet中首先被使用枷颊,但是由于當(dāng)時(shí)的計(jì)算能力不夠鳞贷,并沒有得到廣泛的應(yīng)用窿冯,到了1998年Yann LeCun及其合作者構(gòu)建了更加完備的卷積神經(jīng)網(wǎng)絡(luò)LeNet-5并在手寫數(shù)字的識別問題中取得成功多望,LeNet-5的成功使卷積神經(jīng)網(wǎng)絡(luò)的應(yīng)用得到關(guān)注。LeNet-5沿用了LeCun (1989) 的學(xué)習(xí)策略并在原有設(shè)計(jì)中加入了池化層對輸入特征進(jìn)行篩選 爆安。LeNet-5基本上定義了現(xiàn)代卷積神經(jīng)網(wǎng)絡(luò)的基本結(jié)構(gòu)叛复,其構(gòu)筑中交替出現(xiàn)的卷積層-池化層被認(rèn)為有效提取了輸入圖像的平移不變特征,使得對于特征的提取前進(jìn)了一大步扔仓,所以我們一般的認(rèn)為褐奥,Yann LeCun是卷積神經(jīng)網(wǎng)絡(luò)的創(chuàng)始人。
2006年后翘簇,隨著深度學(xué)習(xí)理論的完善撬码,尤其是計(jì)算能力的提升和參數(shù)微調(diào)(fine-tuning)等技術(shù)的出現(xiàn),卷積神經(jīng)網(wǎng)絡(luò)開始快速發(fā)展版保,在結(jié)構(gòu)上不斷加深呜笑,各類學(xué)習(xí)和優(yōu)化理論得到引入夫否,2012年的AlexNet、2014年的VGGNet叫胁、GoogLeNet 和2015年的ResNet,使得卷積神經(jīng)網(wǎng)絡(luò)幾乎成為了深度學(xué)習(xí)中圖像處理方面的標(biāo)配慷吊。
2.1 為什么要用卷積神經(jīng)網(wǎng)絡(luò)
對于計(jì)算機(jī)視覺來說,每一個(gè)圖像是由一個(gè)個(gè)像素點(diǎn)構(gòu)成曹抬,每個(gè)像素點(diǎn)有三個(gè)通道,分別代表RGB三種顏色(不計(jì)算透明度)急鳄,我們以手寫識別的數(shù)據(jù)你MNIST舉例谤民,每個(gè)圖像的是一個(gè)長寬均為28,channel為1的單色圖像疾宏,如果使用全連接的網(wǎng)絡(luò)結(jié)構(gòu)张足,即,網(wǎng)絡(luò)中的神經(jīng)與相鄰層上的每個(gè)神經(jīng)元均連接坎藐,那就意味著我們的網(wǎng)絡(luò)有28 * 28 =784個(gè)神經(jīng)元(RGB3色的話還要*3)为牍,hidden層如果使用了15個(gè)神經(jīng)元,需要的參數(shù)個(gè)數(shù)(w和b)就有:28 * 28 * 15 * 10 + 15 + 10=117625個(gè)岩馍,這個(gè)數(shù)量級到現(xiàn)在為止也是一個(gè)很恐怖的數(shù)量級碉咆,一次反向傳播計(jì)算量都是巨大的,這還展示一個(gè)單色的28像素大小的圖片蛀恩,如果我們使用更大的像素疫铜,計(jì)算量可想而知。
2.2 結(jié)構(gòu)組成
上面說到傳統(tǒng)的網(wǎng)絡(luò)需要大量的參數(shù)双谆,但是這些參數(shù)是否重復(fù)了呢壳咕,例如,我們識別一個(gè)人顽馋,只要看到他的眼睛谓厘,鼻子,嘴寸谜,還有臉基本上就知道這個(gè)人是誰了竟稳,只是用這些局部的特征就能做做判斷了,并不需要所有的特征程帕。
另外一點(diǎn)就是我們上面說的可以有效提取了輸入圖像的平移不變特征住练,就好像我們看到了這是個(gè)眼睛,這個(gè)眼鏡在左邊還是在右邊他都是眼睛愁拭,這就是平移不變性讲逛。
我們通過卷積的計(jì)算操作來提取圖像局部的特征,每一層都會(huì)計(jì)算出一些局部特征岭埠,這些局部特征再匯總到下一層盏混,這樣一層一層的傳遞下去蔚鸥,特征由小變大,最后在通過這些局部的特征對圖片進(jìn)行處理许赃,這樣大大提高了計(jì)算效率止喷,也提高了準(zhǔn)確度。
2.2.1 卷積層
2.2.1.1 卷積計(jì)算
在介紹卷積層之前要先介紹一下卷積的計(jì)算混聊,這里使用[知乎]我們會(huì)定義一個(gè)權(quán)重矩陣弹谁,也就是我們說的W(一般對于卷積來說,稱作卷積的核kernel也有有人稱做過濾器filter)句喜,這個(gè)權(quán)重矩陣的大小一般為3 * 3
或者5 * 5
预愤,但是在LeNet里面還用到了比較大的7 * 7
,現(xiàn)在已經(jīng)很少見了咳胃,因?yàn)楦鶕?jù)經(jīng)驗(yàn)的驗(yàn)證植康,3和5是最佳的大小。
我們以圖上所示的方式展懈,我們在輸入矩陣上使用我們的權(quán)重矩陣進(jìn)行滑動(dòng)销睁,每滑動(dòng)一步,將所覆蓋的值與矩陣對應(yīng)的值相乘存崖,并將結(jié)果求和并作為輸出矩陣的一項(xiàng)冻记,依次類推直到全部計(jì)算完成。
上圖所示来惧,我們輸入是一個(gè) 5 * 5
的矩陣檩赢,通過使用一次3 * 3
的卷積核計(jì)算得到的計(jì)算結(jié)果是一個(gè)3 * 3
的新矩陣。
那么新矩陣的大小是如何計(jì)算的呢违寞?
2.2.1.2 卷積核大小 f
剛才已經(jīng)說到了一個(gè)重要的參數(shù)贞瞒,就是核的大小,我們這里用f來表示
2.2.1.3 邊界填充 (p)adding
我們看到上圖趁曼,經(jīng)過計(jì)算后矩陣的大小改變了军浆,如果要使矩陣大小不改變呢,我們可以先對矩陣做一個(gè)填充挡闰,將矩陣的周圍全部再包圍一層乒融,這個(gè)矩陣就變成了7*7
,上下左右各加1,相當(dāng)于 5+1+1=7
這時(shí)摄悯,計(jì)算的結(jié)果還是 5 * 5
的矩陣赞季,保證了大小不變,這里的p=1
2.2.1.4 步長 (s)tride
從動(dòng)圖上我們能夠看到奢驯,每次滑動(dòng)只是滑動(dòng)了一個(gè)距離申钩,如果每次滑動(dòng)兩個(gè)距離呢?那就需要使用步長這個(gè)參數(shù)瘪阁。
2.2.1.5 計(jì)算公式
n為我們輸入的矩陣的大小撒遣, 向下取整
這個(gè)公式非常重要一定要記住
2.2.1.6 卷積層
在每一個(gè)卷積層中我們都會(huì)設(shè)置多個(gè)核邮偎,每個(gè)核代表著不同的特征,這些特征就是我們需要傳遞到下一層的輸出义黎,而我們訓(xùn)練的過程就是訓(xùn)練這些不同的核禾进。
2.2.2 激活函數(shù)
由于卷積的操作也是線性的,所以也需要進(jìn)行激活廉涕,一般情況下泻云,都會(huì)使用relu。
2.2.3 池化層(pooling)
池化層是CNN的重要組成部分狐蜕,通過減少卷積層之間的連接壶愤,降低運(yùn)算復(fù)雜程度,池化層的操作很簡單馏鹤,就想相當(dāng)于是合并,我們輸入一個(gè)過濾器的大小娇哆,與卷積的操作一樣湃累,也是一步一步滑動(dòng),但是過濾器覆蓋的區(qū)域進(jìn)行合并碍讨,只保留一個(gè)值治力。
合并的方式也有很多種,例如我們常用的兩種取最大值maxpooling勃黍,取平均值avgpooling
池化層的輸出大小公式也與卷積層一樣宵统,由于沒有進(jìn)行填充,所以p=0覆获,可以簡化為
2.2.4 dropout層
dropout是2014年 Hinton 提出防止過擬合而采用的trick马澈,增強(qiáng)了模型的泛化能力
Dropout(隨機(jī)失活)是指在深度學(xué)習(xí)網(wǎng)絡(luò)的訓(xùn)練過程中,按照一定的概率將一部分神經(jīng)網(wǎng)絡(luò)單元暫時(shí)從網(wǎng)絡(luò)中丟棄弄息,相當(dāng)于從原始的網(wǎng)絡(luò)中找到一個(gè)更瘦的網(wǎng)絡(luò)痊班,說的通俗一點(diǎn),就是隨機(jī)將一部分網(wǎng)絡(luò)的傳播掐斷摹量,聽起來好像不靠譜涤伐,但是通過實(shí)際測試效果非常好。
有興趣的可以去看一下原文Dropout: A Simple Way to Prevent Neural Networks from Overfitting這里就不詳細(xì)介紹了缨称。
2.2.5 全連接層
全鏈接層一般是作為最后的輸出層使用凝果,卷積的作用是提取圖像的特征,最后的全連接層就是要通過這些特征來進(jìn)行計(jì)算睦尽,輸出我們所要的結(jié)果了器净,無論是分類,還是回歸当凡。
我們的特征都是使用矩陣表示的掌动,所以再傳入全連接層之前還需要對特征進(jìn)行壓扁四啰,將他這些特征變成一維的向量,如果要進(jìn)行分類的話粗恢,就是用sofmax作為輸出柑晒,如果要是回歸的話就直接使用linear即可。
以上就是卷積神經(jīng)網(wǎng)絡(luò)幾個(gè)主要的組成部分眷射,下面我們介紹一些經(jīng)典的網(wǎng)絡(luò)模型
2.3 經(jīng)典模型
2.3.1 LeNet - 5
1998匙赞, Yann LeCun 的 LeNet5 官網(wǎng)
卷積神經(jīng)網(wǎng)路的開山之作,麻雀雖小妖碉,但五臟俱全涌庭,卷積層、pooling層欧宜、全連接層坐榆,這些都是現(xiàn)代CNN網(wǎng)絡(luò)的基本組件
- 用卷積提取空間特征;
- 由空間平均得到子樣本冗茸;
- 用 tanh 或 sigmoid 得到非線性席镀;
- 用 multi-layer neural network(MLP)作為最終分類器;
-
層層之間用稀疏的連接矩陣夏漱,以避免大的計(jì)算成本豪诲。
2
輸入:圖像Size為3232。這要比mnist數(shù)據(jù)庫中最大的字母(2828)還大挂绰。這樣做的目的是希望潛在的明顯特征屎篱,如筆畫斷續(xù)、角點(diǎn)能夠出現(xiàn)在最高層特征監(jiān)測子感受野的中心葵蒂。
輸出:10個(gè)類別交播,分別為0-9數(shù)字的概率
- C1層是一個(gè)卷積層,有6個(gè)卷積核(提取6種局部特征)践付,核大小為5 * 5
- S2層是pooling層堪侯,下采樣(區(qū)域:2 * 2 )降低網(wǎng)絡(luò)訓(xùn)練參數(shù)及模型的過擬合程度。
- C3層是第二個(gè)卷積層荔仁,使用16個(gè)卷積核伍宦,核大小:5 * 5 提取特征
- S4層也是一個(gè)pooling層,區(qū)域:2*2
- C5層是最后一個(gè)卷積層乏梁,卷積核大小:5 * 5 卷積核種類:120
- 最后使用全連接層次洼,將C5的120個(gè)特征進(jìn)行分類,最后輸出0-9的概率
一下代碼來自官方教程
import torch.nn as nn
class LeNet5(nn.Module):
def __init__(self):
super(LeNet5, self).__init__()
# 1 input image channel, 6 output channels, 5x5 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120) # 這里論文上寫的是conv,官方教程用了線性層
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # all dimensions except the batch dimension
num_features = 1
for s in size:
num_features *= s
return num_features
net = LeNet5()
print(net)
2.3.2 AlexNet
2012遇骑,Alex Krizhevsky
可以算作LeNet的一個(gè)更深和更廣的版本卖毁,可以用來學(xué)習(xí)更復(fù)雜的對象 論文
- 用rectified linear units(ReLU)得到非線性;
- 使用 dropout 技巧在訓(xùn)練期間有選擇性地忽略單個(gè)神經(jīng)元,來減緩模型的過擬合亥啦;
- 重疊最大池炭剪,避免平均池的平均效果;
-
使用 GPU NVIDIA GTX 580 可以減少訓(xùn)練時(shí)間翔脱,這比用CPU處理快了 10 倍奴拦,所以可以被用于更大的數(shù)據(jù)集和圖像上。
4
雖然 AlexNet只有8層届吁,但是它有60M以上的參數(shù)總量错妖,Alexnet有一個(gè)特殊的計(jì)算層,LRN層疚沐,做的事是對當(dāng)前層的輸出結(jié)果做平滑處理暂氯,這里就不做詳細(xì)介紹了,
Alexnet的每一階段(含一次卷積主要計(jì)算的算作一層)可以分為8層:
con - relu - pooling - LRN :
要注意的是input層是227*227亮蛔,而不是paper里面的224痴施,這里可以算一下,主要是227可以整除后面的conv1計(jì)算究流,224不整除辣吃。如果一定要用224可以通過自動(dòng)補(bǔ)邊實(shí)現(xiàn),不過在input就補(bǔ)邊感覺沒有意義梯嗽,補(bǔ)得也是0,這就是我們上面說的公式的重要性沽损。conv - relu - pool - LRN :
group=2灯节,這個(gè)屬性強(qiáng)行把前面結(jié)果的feature map分開,卷積部分分成兩部分做conv - relu
conv-relu
conv - relu - pool
fc - relu - dropout :
dropout層绵估,在alexnet中是說在訓(xùn)練的以1/2概率使得隱藏層的某些neuron的輸出為0炎疆,這樣就丟到了一半節(jié)點(diǎn)的輸出,BP的時(shí)候也不更新這些節(jié)點(diǎn)国裳,防止過擬合形入。fc - relu - dropout
fc - softmax
在Pytorch的vision包中是包含Alexnet的官方實(shí)現(xiàn)的,我們直接使用官方版本看下網(wǎng)絡(luò)
import torchvision
model = torchvision.models.alexnet(pretrained=False) #我們不下載預(yù)訓(xùn)練權(quán)重
print(model)
2.3.3 VGG
2015缝左,牛津的 VGG亿遂。論文
- 每個(gè)卷積層中使用更小的 3×3 filters,并將它們組合成卷積序列
- 多個(gè)3×3卷積序列可以模擬更大的接收場的效果
- 每次的圖像像素縮小一倍渺杉,卷積核的數(shù)量增加一倍
VGG有很多個(gè)版本蛇数,也算是比較穩(wěn)定和經(jīng)典的model。它的特點(diǎn)也是連續(xù)conv多計(jì)算量巨大是越,這里我們以VGG16為例..圖片來源
VGG清一色用小卷積核耳舅,結(jié)合作者和自己的觀點(diǎn)哀墓,這里整理出小卷積核比用大卷積核的優(yōu)勢:
根據(jù)作者的觀點(diǎn),input8 -> 3層conv3x3后次屠,output=2掀宋,等同于1層conv7x7的結(jié)果; input=8 -> 2層conv3x3后盔性,output=2霞丧,等同于2層conv5x5的結(jié)果
卷積層的參數(shù)減少。相比5x5纯出、7x7和11x11的大卷積核蚯妇,3x3明顯地減少了參數(shù)量
通過卷積和池化層后,圖像的分辨率降低為原來的一半暂筝,但是圖像的特征增加一倍箩言,這是一個(gè)十分規(guī)整的操作: 分辨率由輸入的224->112->56->28->14->7, 特征從原始的RGB3個(gè)通道-> 64 ->128 -> 256 -> 512
這為后面的網(wǎng)絡(luò)提供了一個(gè)標(biāo)準(zhǔn),我們依舊使用Pytorch官方實(shí)現(xiàn)版本來查看
import torchvision
model = torchvision.models.vgg16(pretrained=False) #我們不下載預(yù)訓(xùn)練權(quán)重
print(model)
GoogLeNet (Inception)
2014,Google Christian Szegedy 論文
- 使用1×1卷積塊(NiN)來減少特征數(shù)量焕襟,這通常被稱為“瓶頸”陨收,可以減少深層神經(jīng)網(wǎng)絡(luò)的計(jì)算負(fù)擔(dān)。
- 每個(gè)池化層之前鸵赖,增加 feature maps务漩,增加每一層的寬度來增多特征的組合性
googlenet最大的特點(diǎn)就是包含若干個(gè)inception模塊,所以有時(shí)候也稱作 inception net
googlenet雖然層數(shù)要比VGG多很多它褪,但是由于inception的設(shè)計(jì)饵骨,計(jì)算速度方面要快很多。
不要被這個(gè)圖嚇到茫打,其實(shí)原理很簡單
Inception架構(gòu)的主要思想是找出如何讓已有的稠密組件接近與覆蓋卷積視覺網(wǎng)絡(luò)中的最佳局部稀疏結(jié)構(gòu)【哟ィ現(xiàn)在需要找出最優(yōu)的局部構(gòu)造,并且重復(fù) 幾次老赤。之前的一篇文獻(xiàn)提出一個(gè)層與層的結(jié)構(gòu)轮洋,在最后一層進(jìn)行相關(guān)性統(tǒng)計(jì),將高相關(guān)性的聚集到一起抬旺。這些聚類構(gòu)成下一層的單元弊予,且與上一層單元連接。假設(shè)前 面層的每個(gè)單元對應(yīng)于輸入圖像的某些區(qū)域开财,這些單元被分為濾波器組汉柒。在接近輸入層的低層中,相關(guān)單元集中在某些局部區(qū)域责鳍,最終得到在單個(gè)區(qū)域中的大量聚類竭翠,在最后一層通過1x1的卷積覆蓋。
上面的話聽起來很生硬薇搁,其實(shí)解釋起來很簡單:每一模塊我們都是用若干個(gè)不同的特征提取方式斋扰,例如 3x3卷積,5x5卷積,1x1的卷積传货,pooling等屎鳍,都計(jì)算一下,最后再把這些結(jié)果通過Filter Concat來進(jìn)行連接问裕,找到這里面作用最大的逮壁。而網(wǎng)絡(luò)里面包含了許多這樣的模塊,這樣不用我們?nèi)藶槿ヅ袛嗄膫€(gè)特征提取方式好粮宛,網(wǎng)絡(luò)會(huì)自己解決(是不是有點(diǎn)像AUTO ML)窥淆,在Pytorch中實(shí)現(xiàn)了InceptionA-E,還有InceptionAUX 模塊巍杈。
# inception_v3需要scipy忧饭,所以沒有安裝的話pip install scipy 一下
import torchvision
model = torchvision.models.inception_v3(pretrained=False) #我們不下載預(yù)訓(xùn)練權(quán)重
print(model)
ResNet
2015,Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun 論文
Kaiming He 何凱明(音譯)這個(gè)大神大家一定要記住筷畦,現(xiàn)在很多論文都有他參與(mask rcnn, focal loss)词裤,Jian Sun孫劍老師就不用說了,現(xiàn)在曠世科技的首席科學(xué)家
剛才的googlenet已經(jīng)很深了鳖宾,ResNet可以做到更深吼砂,通過殘差計(jì)算,可以訓(xùn)練超過1000層的網(wǎng)絡(luò)鼎文,俗稱跳連接
退化問題
網(wǎng)絡(luò)層數(shù)增加渔肩,但是在訓(xùn)練集上的準(zhǔn)確率卻飽和甚至下降了。這個(gè)不能解釋為overfitting拇惋,因?yàn)閛verfit應(yīng)該表現(xiàn)為在訓(xùn)練集上表現(xiàn)更好才對周偎。這個(gè)就是網(wǎng)絡(luò)退化的問題,退化問題說明了深度網(wǎng)絡(luò)不能很簡單地被很好地優(yōu)化
殘差網(wǎng)絡(luò)的解決辦法
深層網(wǎng)絡(luò)的后面那些層是恒等映射蚤假,那么模型就退化為一個(gè)淺層網(wǎng)絡(luò)栏饮。那現(xiàn)在要解決的就是學(xué)習(xí)恒等映射函數(shù)了吧兔。讓一些層去擬合一個(gè)潛在的恒等映射函數(shù)H(x) = x磷仰,比較困難。如果把網(wǎng)絡(luò)設(shè)計(jì)為H(x) = F(x) + x境蔼。我們可以轉(zhuǎn)換為學(xué)習(xí)一個(gè)殘差函數(shù)F(x) = H(x) - x. 只要F(x)=0灶平,就構(gòu)成了一個(gè)恒等映射H(x) = x. 而且,擬合殘差肯定更加容易箍土。
以上又很不好理解逢享,繼續(xù)解釋下,先看圖:
我們在激活函數(shù)前將上一層(或幾層)的輸出與本層計(jì)算的輸出相加吴藻,將求和的結(jié)果輸入到激活函數(shù)中做為本層的輸出瞒爬,引入殘差后的映射對輸出的變化更敏感,其實(shí)就是看本層相對前幾層是否有大的變化,相當(dāng)于是一個(gè)差分放大器的作用侧但。圖中的曲線就是殘差中的shoutcut矢空,他將前一層的結(jié)果直接連接到了本層,也就是俗稱的跳連接禀横。
我們以經(jīng)典的resnet18來看一下網(wǎng)絡(luò)結(jié)構(gòu) 圖片來源
import torchvision
model = torchvision.models.resnet18(pretrained=False) #我們不下載預(yù)訓(xùn)練權(quán)重
print(model)
那么我們該如何選擇網(wǎng)絡(luò)呢屁药?
來源
以上表格可以清楚的看到準(zhǔn)確率和計(jì)算量之間的對比。我的建議是柏锄,小型圖片分類任務(wù)酿箭,resnet18基本上已經(jīng)可以了,如果真對準(zhǔn)確度要求比較高趾娃,再選其他更好的網(wǎng)絡(luò)架構(gòu)缭嫡。