深度卷積神經?絡(AlexNet)
神經?絡可以直接基于圖像的原始像素進?分類。這種稱為端到端(end-to?end)的?法節(jié)省了很多中間步驟。然而,在很??段時間?更流?的是研究者通過勤勞與智慧
所設計并?成的??特征。這類圖像分類研究的主要流程是:
1. 獲取圖像數(shù)據集;
2. 使?已有的特征提取函數(shù)?成圖像的特征惭婿;
3. 使?機器學習模型對圖像的特征分類。
當時認為的機器學習部分僅限最后這?步视搏。如果那時候跟機器學習研究者交談审孽,他們會認為機器學習既重要?優(yōu)美。優(yōu)雅的定理證明了許多分類器的性質浑娜。機器學習領域?機勃勃佑力、嚴謹而且極其有?。然而筋遭,如果跟計算機視覺研究者交談打颤,則是另外?幅景象暴拄。他們會告訴你圖像識別?“不可告?”的現(xiàn)實是:計算機視覺流程中真正重要的是數(shù)據和特征。也就是說编饺,使?較?凈的數(shù)據集和較有效的特征甚??機器學習模型的選擇對圖像分類結果的影響更?乖篷。
學習特征表?
既然特征如此重要,它該如何表?呢透且?
我們已經提到撕蔼,在相當?的時間?,特征都是基于各式各樣??設計的函數(shù)從數(shù)據中提取的秽誊。事實上鲸沮,不少研究者通過提出新的特征提取函數(shù)不斷改進圖像分類結果。這?度為計算機視覺的發(fā)展做出了重要貢獻锅论。
然而讼溺,另?些研究者則持異議。他們認為特征本?也應該由學習得來最易。他們還相信怒坯,為了表征?夠復雜的輸?,特征本?應該分級表?藻懒。持這?想法的研究者相信剔猿,多層神經?絡可能可以學得數(shù)據的多級表征,并逐級表?越來越抽象的概念或模式束析。以圖像分類為例艳馒,并回憶“?維卷積層” ?節(jié)中物體邊緣檢測的例?憎亚。在多層神經?絡中员寇,圖像的第?級的表?可以是在特定的位置和?度是否出現(xiàn)邊緣;而第?級的表?說不定能夠將這些邊緣組合出有趣的模式第美,如花紋蝶锋;在第三級的表?中,也許上?級的花紋能進?步匯合成對應物體特定部位的模式什往。這樣逐級表?下去扳缕,最終,模型能夠較容易根據最后?級的表?完成分類任務别威。需要強調的是躯舔,輸?的逐級表?由多層模型中的參數(shù)決定,而這些參數(shù)都是學出來的省古。
缺失要素?:數(shù)據
包含許多特征的深度模型需要?量的有標簽的數(shù)據才能表現(xiàn)得?其他經典?法更好粥庄。限于早期計算機有限的存儲和90年代有限的研究預算,?部分研究只基于小的公開數(shù)據集豺妓。例如惜互,不少研究論?基于加州?學歐?分校(UCI)提供的若?個公開數(shù)據集布讹,其中許多數(shù)據集只有?百??千張圖像。這?狀況在2010年前后興起的?數(shù)據浪潮中得到改善训堆。特別是描验,2009年誕?的ImageNet數(shù)據集包含了1,000?類物體,每類有多達數(shù)千張不同的圖像坑鱼。這?規(guī)模是當時其他公開數(shù)據集?法與之相提并論的膘流。ImageNet數(shù)據集同時推動計算機視覺和機器學習研究進?新的階段,使此前的傳統(tǒng)?法不再有優(yōu)勢鲁沥。
缺失要素?:硬件
深度學習對計算資源要求很?睡扬。早期的硬件計算能?有限,這使訓練較復雜的神經?絡變得很困難黍析。然而卖怜,通?GPU的到來改變了這?格局。很久以來阐枣,GPU都是為圖像處理和計算機游戲設計的马靠,尤其是針對?吞吐量的矩陣和向量乘法從而服務于基本的圖形變換。值得慶幸的是蔼两,這其中的數(shù)學表達與深度?絡中的卷積層的表達類似甩鳄。通?GPU這個概念在2001年開始興起,涌現(xiàn)出諸如OpenCL和CUDA之類的編程框架额划。
AlexNet
2012年妙啃,AlexNet橫空出世。這個模型的名字來源于論?第?作者的姓名Alex Krizhevsky [1]俊戳。 AlexNet使?了8層卷積神經?絡揖赴,并以很?的優(yōu)勢贏得了ImageNet 2012圖像識別挑戰(zhàn)賽。它?次證明了學習到的特征可以超越??設計的特征抑胎,從而?舉打破計算機視覺研究的前狀燥滑。
AlexNet與LeNet的設計理念?常相似,但也有顯著的區(qū)別阿逃。
第?铭拧,與相對較小的LeNet相?,AlexNet包含8層變換恃锉,其中有5層卷積和2層全連接隱藏層搀菩,以及1個全連接輸出層。下?我們來詳細描述這些層的設計破托。AlexNet第?層中的卷積窗口形狀是11× 11肪跋。因為ImageNet中絕?多數(shù)圖像的?和寬均?MNIST圖像的?和寬?10倍以上,ImageNet圖像的物體占?更多的像素炼团,所以需要更?的卷積窗口來捕獲物體澎嚣。第?層中的卷積窗口形狀減小到5 × 5疏尿,之后全采?3 × 3。此外易桃,第?褥琐、第?和第五個卷積層之后都使?了窗口形狀為3 × 3、步幅為2的最?池化層晤郑。而且敌呈,AlexNet使?的卷積通道數(shù)也?于LeNet中的卷積通道數(shù)數(shù)?倍。緊接著最后?個卷積層的是兩個輸出個數(shù)為4096的全連接層造寝。這兩個巨?的全連接層帶來將近1GB的模型參數(shù)磕洪。由于早期顯存的限制,最早的AlexNet使?雙數(shù)據流的設計使?個GPU只需要處理?半模型诫龙。幸運的是析显,顯存在過去?年得到了??的發(fā)展,因此通常我們不再需要這樣的特別設計了签赃。
第?谷异,AlexNet將sigmoid激活函數(shù)改成了更加簡單的ReLU激活函數(shù)。???锦聊,ReLU激活函數(shù)的計算更簡單歹嘹,例如它并沒有sigmoid激活函數(shù)中的求冪運算。另???孔庭,ReLU激活函數(shù)在不同的參數(shù)初始化?法下使模型更容易訓練尺上。這是由于當sigmoid激活函數(shù)輸出極接近0或1時,這些區(qū)域的梯度?乎為0圆到,從而造成反向傳播?法繼續(xù)更新部分模型參數(shù)怎抛;而ReLU激活函數(shù)在正區(qū)間的梯度恒為1。因此构资,若模型參數(shù)初始化不當抽诉,sigmoid函數(shù)可能在正區(qū)間得到?乎為0的梯度,從而令模型?法得到有效訓練吐绵。
第三,AlexNet通過丟棄法(參?“丟棄法”?節(jié))來控制全連接層的模型復雜度河绽。而LeNet并沒有使?丟棄法己单。
第四,AlexNet引?了?量的圖像增?耙饰,如翻轉纹笼、裁剪和顏?變化,從而進?步擴?數(shù)據集來緩解過擬合苟跪。我們將在后?的“圖像增?”?節(jié)詳細介紹這種?法廷痘。
下?我們實現(xiàn)稍微簡化過的AlexNet
import d2lzh as d2l
from mxnet import gluon, init, nd
from mxnet.gluon import data as gdata, nn
import os
import sys
net = nn.Sequential()
# 使?較?的11 x 11窗?來捕獲物體蔓涧。同時使?步幅4來較?幅度減?輸出?和寬。這?使?的輸出通
# 道數(shù)?LeNet中的也要?很多
net.add(nn.Conv2D(96, kernel_size=11, strides=4, activation='relu'),
nn.MaxPool2D(pool_size=3, strides=2),
# 減?卷積窗?笋额,使?填充為2來使得輸?與輸出的?和寬?致元暴,且增?輸出通道數(shù)
nn.Conv2D(256, kernel_size=5, padding=2, activation='relu'),
nn.MaxPool2D(pool_size=3, strides=2),
# 連續(xù)3個卷積層,且使?更?的卷積窗?兄猩。除了最后的卷積層外茉盏,進?步增?了輸出通道數(shù)。
# 前兩個卷積層后不使?池化層來減?輸?的?和寬
nn.Conv2D(384, kernel_size=3, padding=1, activation='relu'),
nn.Conv2D(384, kernel_size=3, padding=1, activation='relu'),
nn.Conv2D(256, kernel_size=3, padding=1, activation='relu'),
nn.MaxPool2D(pool_size=3, strides=2),
# 這?全連接層的輸出個數(shù)?LeNet中的?數(shù)倍枢冤。使?丟棄層來緩解過擬合
nn.Dense(4096, activation="relu"), nn.Dropout(0.5),
nn.Dense(4096, activation="relu"), nn.Dropout(0.5),
# 輸出層鸠姨。由于這?使?Fashion-MNIST,所以?類別數(shù)為10淹真,??論?中的1000
nn.Dense(10))
X = nd.random.uniform(shape=(1, 1, 224, 224))
net.initialize()
for layer in net:
X = layer(X)
print(layer.name, 'output shape:\t', X.shape)
conv0 output shape:
(1, 96, 54, 54)
pool0 output shape:
(1, 96, 26, 26)
conv1 output shape:
(1, 256, 26, 26)
pool1 output shape:
(1, 256, 12, 12)
conv2 output shape:
(1, 384, 12, 12)
conv3 output shape:
(1, 384, 12, 12)
conv4 output shape:
(1, 256, 12, 12)
pool2 output shape:
(1, 256, 5, 5)
dense0 output shape:
(1, 4096)
dropout0 output shape: (1, 4096)
dense1 output shape:
(1, 4096)
dropout1 output shape: (1, 4096)
dense2 output shape:
(1, 10)