日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Lesson 16.6Lesson 16.6 复现经典架构:LeNet5 复现经典架构 (2):AlexNet

發(fā)布時間:2025/4/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Lesson 16.6Lesson 16.6 复现经典架构:LeNet5 复现经典架构 (2):AlexNet 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

4 復(fù)現(xiàn)經(jīng)典網(wǎng)絡(luò):LeNet5與AlexNet

4.1 現(xiàn)代CNN的奠基者:LeNet5

使用卷積層和池化層能夠創(chuàng)造的最簡單的網(wǎng)絡(luò)是什么樣呢?或許就是下面這樣的架構(gòu):
首先,圖像從左側(cè)輸入,從右側(cè)輸出,數(shù)據(jù)傳輸方向與DNN一致。整個網(wǎng)絡(luò)由2個卷積層、2個平均池化層和2個全連接層組成,雖然沒有標(biāo)注出來,但每個卷積層和全連接層后都使用激活函數(shù)tanh或sigmoid。

這個架構(gòu)就是著名的LeNet5架構(gòu),它在1998年被LeCun等人在論文《Gradient-Based Learning Applied to Document Recognition》中正式提出,它被認(rèn)為是現(xiàn)代卷積神經(jīng)網(wǎng)絡(luò)的奠基者。在LeNet5被提出后,幾乎所有的卷積網(wǎng)絡(luò)都會連用卷積層、池化層與全連接層(也就是線性層)。現(xiàn)在,這已經(jīng)成為一種非常經(jīng)典的架構(gòu):卷積層作為輸入層,緊跟激活函數(shù),池化層緊跟在一個或數(shù)個卷積+激活的結(jié)構(gòu)之后。在卷積池化交替進(jìn)行數(shù)次之后,轉(zhuǎn)向線性層+激活函數(shù),并使用線性層結(jié)尾,輸出預(yù)測結(jié)果。由于輸入數(shù)據(jù)結(jié)構(gòu)的設(shè)置,以上架構(gòu)圖中的網(wǎng)絡(luò)可能與論文中有一些細(xì)節(jié)上的區(qū)別(論文見下載資料),在其他教材中,你或許會見到添加了更多卷積層、或添加了更多池化層的相似架構(gòu),這些都是根據(jù)LeNet的核心思想“卷積+池化+線性”來搭建的LeNet5的變體。

在上面的架構(gòu)中,每層的結(jié)構(gòu)和參數(shù)都標(biāo)識得非常清楚,在PyTorch中實現(xiàn)其架構(gòu)的代碼如下:

import torch from torch import nn from torch.nn import functional as F data = torch.ones(size=(10,1,32,32)) class Model(nn.Module):def __init__(self):super().__init__()self.conv1 = nn.Conv2d(1,6,5)self.pool1 = nn.AvgPool2d(kernel_size=2,stride=2)self.conv2 = nn.Conv2d(6,16,5)self.pool2 = nn.AvgPool2d(kernel_size=2,stride=2)self.fc1 = nn.Linear(16*5*5,120) #這里的上層輸入是圖像中的全部像素self.fc2 = nn.Linear(120,84)def forward(self,x):x = F.tanh(self.conv1(x))x = self.pool1(x)x = F.tanh(self.conv2(x))x = self.pool2(x)x = x.view(-1,16*5*5) #需要將數(shù)據(jù)的特征部分“拉平”才能夠進(jìn)入FC層x = F.tanh(self.fc1(x))output = F.softmax(self.fc2(x),dim=1) net = Model() net(data) #卷積網(wǎng)絡(luò)的一大特點是:改變輸入數(shù)據(jù)的尺寸,整個網(wǎng)絡(luò)就會開始花式報錯 #你可以試試將數(shù)據(jù)32*32的結(jié)構(gòu)修改至28*28 #安裝torchinfo庫,查看網(wǎng)絡(luò)結(jié)構(gòu) !pip install torchinfo from torchinfo import summary net = Model() summary(net, input_size=(10, 1, 32, 32)) #========================================================================================== #Layer (type:depth-idx) Output Shape Param # #========================================================================================== #model -- -- #├─Conv2d: 1-1 [10, 6, 28, 28] 156 #├─AvgPool2d: 1-2 [10, 6, 14, 14] -- #├─Conv2d: 1-3 [10, 16, 10, 10] 2,416 #├─AvgPool2d: 1-4 [10, 16, 5, 5] -- #├─Linear: 1-5 [10, 120] 48,120 #├─Linear: 1-6 [10, 84] 10,164 #========================================================================================== #Total params: 60,856 #Trainable params: 60,856 #Non-trainable params: 0 #Total mult-adds (M): 4.22 #========================================================================================== #Input size (MB): 0.04 #Forward/backward pass size (MB): 0.52 #Params size (MB): 0.24 #Estimated Total Size (MB): 0.81 #==========================================================================================

這是我們在之前的課程中學(xué)到的寫法,這種寫法適合層數(shù)較少、層次簡單的神經(jīng)網(wǎng)絡(luò),但這個網(wǎng)絡(luò)和我們之前寫的只有線性層的網(wǎng)絡(luò)比起來還是略有些復(fù)雜了。在這段代碼中你可以清晰地看見卷積層、池化層以及全連接層是如何鏈接在一起共同作用的。我們將“層”放在init中定義,而將“函數(shù)”放在forward中定義,令init中的結(jié)構(gòu)與forward中的結(jié)構(gòu)一一對應(yīng),并使用forward函數(shù)執(zhí)行向前傳播流程。

從今天的眼光來看,LeNet5無疑是很簡單并且有些弱小的卷積網(wǎng)絡(luò),然而,當(dāng)加入學(xué)習(xí)率衰減等優(yōu)化方法并訓(xùn)練恰當(dāng)時,單一的LeNet5模型可以在Fashion-MNIST數(shù)據(jù)集上獲得超過91%的訓(xùn)練準(zhǔn)確率(可參考kaggle kernel:https://www.kaggle.com/jaeboklee/pytorch-fashion-mnist-lenet5-ensemble)。

這個效果已經(jīng)比只有線性層的網(wǎng)絡(luò)提升了約5%的成績。雖然簡單,LeNet5卻切實展示了卷積神經(jīng)網(wǎng)絡(luò)的實力。

4.2 從淺層到深度:AlexNet

在二十一世紀(jì)的前十年,LeNet5作為現(xiàn)代卷積網(wǎng)絡(luò)的奠基者并沒有引起太大的水花,大多數(shù)人并不相信機(jī)器提取的特征能夠比人親自提取的特征更強(qiáng)大,事實上,LeNet5也確實無法在復(fù)雜任務(wù)上戰(zhàn)勝傳統(tǒng)計算機(jī)視覺方法。卷積網(wǎng)絡(luò)在被提出的幾十年內(nèi)一直在蟄伏,直到2012年,AlexNet橫空出世,真正第一次證明了,當(dāng)數(shù)據(jù)量達(dá)標(biāo)、訓(xùn)練得當(dāng)時,卷積神經(jīng)網(wǎng)絡(luò)提取的特征效果遠(yuǎn)遠(yuǎn)勝過人類提取的特征。


AlexNet誕生于有“視覺界奧林匹克”之稱的大規(guī)模視覺識別挑戰(zhàn)比賽ILSVRC(ImageNet Large Scale Visual Recognition Challenge)。ILSVRC使用ImageNet數(shù)據(jù)集,共有一千四百多萬幅圖像,共2萬多個類別,圖像的尺寸有224×224,227×227,256×256,299×299等不同類型。在ILSVRC中,參賽隊伍需要使用大約包含一百萬張圖片的訓(xùn)練集來訓(xùn)練模型,并識別出測試集中的一千個類別,再按“錯誤率”從低到高進(jìn)行排名(具體錯誤率是如何計算的,將在我們使用ImageNet進(jìn)行訓(xùn)練的時候來說明)。在AlexNet出現(xiàn)之前,最好成績一直由手工提取特征+支持向量機(jī)的算法獲得,最低錯誤率為25.8%。2012年,AlexNet進(jìn)入ILSVRC競賽,一下將錯誤率降低到了15.3%。在過去的ImageNet競賽中,哪怕有一個百分點的提升都是非常不錯的成績,而深度學(xué)習(xí)首次入場就取得了10個百分點的提升,這給整個圖像領(lǐng)域帶來了巨大的震撼,從那之后圖像領(lǐng)域的前沿研究就全面向深度學(xué)習(xí)傾斜了。AlexNet無疑是真正讓“深度視覺”出圈的架構(gòu),其架構(gòu)如下所示:


AlexNet總共有11層,其中有5個卷積層、3個池化層、2個全連接隱藏層,1個全連接輸出層,實際上,在全連接層的前后AlexNet使用了Dropout層,但在大部分架構(gòu)上都不會把DP表現(xiàn)出來。

在有的文獻(xiàn)上,你可能看到人們稱AlexNet為8層(不計算池化層)。實際上,在學(xué)術(shù)界,我們對于神經(jīng)網(wǎng)絡(luò)的“層”的計數(shù)方法沒有明確的定義,有的文獻(xiàn)會將所有卷積中的元素都算做“層”,例如、池化、BN、Dropout等都是層,而有的文獻(xiàn)認(rèn)為,只有帶有訓(xùn)練參數(shù)的才能夠被稱為“層”,其他對數(shù)據(jù)進(jìn)行處理的、不帶訓(xùn)練參數(shù)的功能(如池化、激活函數(shù)、Dropout等)都屬于參數(shù)層的附屬。大部分文獻(xiàn)中的架構(gòu)圖只會寫出卷積、池化以及全連接層是如何排列,即便文獻(xiàn)中提到使用了Dropout或BN等計算方式,可能也不一定會明確這些計算在整體網(wǎng)絡(luò)架構(gòu)的哪一部分。在PyTorch中進(jìn)行計算時,就連激活函數(shù)也可以是單獨(dú)的層。因此,人們對于一個神經(jīng)網(wǎng)絡(luò)究竟有幾層是沒有明確定義的。在學(xué)習(xí)架構(gòu)時,不用去糾結(jié)整體的層數(shù),而要從層與層之間的組合入手。例如,AlexNet的架構(gòu)若用文字來表現(xiàn),則可以打包成4個組合:

輸入→(卷積+池化)→(卷積+池化)→(卷積x3+池化)→(線性x3)→輸出

相對的,LeNet5的架構(gòu)可以打包成3個組合:

輸入→(卷積+池化)→(卷積+池化)→(線性x2)→輸出

雖然省略了不少細(xì)節(jié),但是這樣的組合比架構(gòu)圖更容易記憶,可以快速幫助你判斷眼前的代碼究竟依賴于怎樣的經(jīng)典架構(gòu)來建立。

和只有6層(包括池化層)的LeNet5比起來,AlexNet主要做出了如下改變:

1、相比之下,卷積核更小、網(wǎng)絡(luò)更深、通道數(shù)更多,這代表人們已經(jīng)認(rèn)識到了圖像數(shù)據(jù)天生適合于多次提取特征,“深度”才是卷積網(wǎng)絡(luò)的未來。LeNet5是基于MNIST數(shù)據(jù)集創(chuàng)造,MNIST數(shù)據(jù)集中的圖片尺寸大約只有30*30的大小,LeNet5采用了5x5的卷積核,圖像尺寸/核尺寸大約在6:1。而基于ImageNet數(shù)據(jù)集訓(xùn)練的AlexNet最大的卷積核只有11x11,且在第二個卷積層就改用5x5,剩下的層中都使用3x3的卷積核,圖像尺寸/核尺寸至少也超過20:1。小卷積核讓網(wǎng)絡(luò)更深,但也讓特征圖的尺寸變得很小,為了讓信息盡可能地被捕獲,AlexNet也使用了更多的通道。小卷積核、多通道、更深的網(wǎng)絡(luò),這些都成為了卷積神經(jīng)網(wǎng)絡(luò)后續(xù)發(fā)展的指導(dǎo)方向。
2、使用了ReLU激活函數(shù),擺脫Sigmoid與Tanh的各種問題。
3、使用了Dropout層來控制模型復(fù)雜度,控制過擬合。
4、引入了大量傳統(tǒng)或新興的圖像增強(qiáng)技術(shù)來擴(kuò)大數(shù)據(jù)集,進(jìn)一步緩解過擬合。
5、使用GPU對網(wǎng)絡(luò)進(jìn)行訓(xùn)練,使得“適當(dāng)?shù)挠?xùn)練“(proper training)成為可能。

除此之外,在原論文中,作者Alex Krizhevsky還提出了其他創(chuàng)新,例如,他們使用了overlap pooling的技術(shù)——一般的池化層在進(jìn)行掃描的時候,都是步幅 >= 核尺寸,而在AlexNet中,池化層中的步幅是小于核尺寸的,這就讓池化過程中的掃描區(qū)域出現(xiàn)重疊(overlap),根據(jù)論文所示,這個技術(shù)可以緩解過擬合。從以上這些點,很容易看出為什么AlexNet對于卷積神經(jīng)網(wǎng)絡(luò)而言如此地重要,它幾乎從算法、算力、數(shù)據(jù)、架構(gòu)技巧等各個方面影響了現(xiàn)代卷積神經(jīng)網(wǎng)絡(luò)地發(fā)展。AlexNet之后,ImageNet競賽上就很少看到傳統(tǒng)視覺算法的身影了。當(dāng)然,競賽環(huán)境與工業(yè)環(huán)境有極大的區(qū)別,在實際落地的過程中,深度學(xué)習(xí)還受到各種限制,因此傳統(tǒng)方法依然很關(guān)鍵。

現(xiàn)在,讓我們在PyTorch中來復(fù)現(xiàn)AlexNet的架構(gòu):

import torch from torch import nn from torch.nn import functional as Fdata = torch.ones(size=(10,3,227,227)) #假設(shè)圖像的尺寸為227x227class Model(nn.Module):def __init__(self):super().__init__() #大卷積核、較大的步長、較多的通道self.conv1 = nn.Conv2d(3,96,kernel_size=11, stride=4) self.pool1 = nn.MaxPool2d(kernel_size=3,stride=2)#卷積核、步長恢復(fù)正常大小,進(jìn)一步擴(kuò)大通道self.conv2 = nn.Conv2d(96,256,kernel_size=5, padding=2) self.pool2 = nn.MaxPool2d(kernel_size=3,stride=2)#連續(xù)的卷積層,瘋狂提取特征self.conv3 = nn.Conv2d(256,384,kernel_size=3,padding=1) self.conv4 = nn.Conv2d(384,384,kernel_size=3,padding=1)self.conv5 = nn.Conv2d(384,256,kernel_size=3,padding=1)self.pool3 = nn.MaxPool2d(kernel_size=3,stride=2)#全連接層self.fc1 = nn.Linear(256*6*6,4096) #這里的上層輸入是圖像中的全部像素self.fc2 = nn.Linear(4096,4096)self.fc3 = nn.Linear(4096,1000) #輸出ImageNet的一千個類別def forward(self,x):x = F.relu(self.conv1(x))x = self.pool1(x)x = F.relu(self.conv2(x))x = self.pool2(x)x = F.relu(self.conv3(x))x = F.relu(self.conv4(x))x = F.relu(self.conv5(x))x = self.pool3(x)x = x.view(-1,256*6*6) #需要將數(shù)據(jù)的特征部分“拉平”才能夠進(jìn)入FC層x = F.relu(F.dropout(self.fc1(x),0.5)) #dropout:隨機(jī)讓50%的權(quán)重為0x = F.relu(F.dropout(self.fc2(x),0.5)) output = F.softmax(self.fc3(x),dim=1) net = Model() net(data)from torchinfo import summary summary(net,input_size=((10,3,227,227))) # ========================================================================================== # Layer (type:depth-idx) Output Shape Param # # ========================================================================================== # model -- -- # ├─Conv2d: 1-1 [10, 96, 55, 55] 34,944 # ├─MaxPool2d: 1-2 [10, 96, 27, 27] -- # ├─Conv2d: 1-3 [10, 256, 27, 27] 614,656 # ├─MaxPool2d: 1-4 [10, 256, 13, 13] -- # ├─Conv2d: 1-5 [10, 348, 13, 13] 802,140 # ├─Conv2d: 1-6 [10, 348, 13, 13] 1,090,284 # ├─Conv2d: 1-7 [10, 256, 13, 13] 802,048 # ├─MaxPool2d: 1-8 [10, 256, 6, 6] -- # ├─Linear: 1-9 [10, 4096] 37,752,832 # ├─Linear: 1-10 [10, 4096] 16,781,312 # ├─Linear: 1-11 [10, 1000] 4,097,000 # ========================================================================================== # Total params: 61,975,216 # Trainable params: 61,975,216 # Non-trainable params: 0 # Total mult-adds (G): 10.68 # ========================================================================================== # Input size (MB): 6.18 # Forward/backward pass size (MB): 51.77 # Params size (MB): 247.90 # Estimated Total Size (MB): 305.85 # ==========================================================================================

與LeNet5實現(xiàn)時候的情況一致,由于輸入數(shù)據(jù)的結(jié)構(gòu)可能與原論文有區(qū)別,我們的網(wǎng)絡(luò)架構(gòu)中的小細(xì)節(jié)可能與原論文有些許不同。從代碼量來看,其實AlexNet并沒有比LeNet5復(fù)雜太多,當(dāng)結(jié)構(gòu)清晰時,我們甚至認(rèn)為AlexNet有些簡單。但在AlexNet出世之前,學(xué)術(shù)界普遍認(rèn)為深度網(wǎng)絡(luò)是不可能訓(xùn)練的,而今天我們都了解,只要有足夠的算力和數(shù)據(jù),即便是幾億參數(shù)的巨量網(wǎng)絡(luò)也是可以訓(xùn)練的。AlexNet所帶來的觀念上的轉(zhuǎn)變才是真正推動卷積神經(jīng)網(wǎng)絡(luò)向前發(fā)展的核心。

只要有架構(gòu)圖,復(fù)現(xiàn)經(jīng)典架構(gòu)其實并不是一件難事(照著敲代碼,一點也不難),但我們不太可能完全記住經(jīng)典架構(gòu)中的每個細(xì)節(jié)。在復(fù)現(xiàn)架構(gòu)時,我們應(yīng)該注意哪些方面呢?

1、首先,代碼可以不自己寫,但一定要通
2、了解此架構(gòu)的核心思想,以及在此思想下其結(jié)構(gòu)大概如何排布。對于比較簡單的網(wǎng)絡(luò)(比如AlexNet),可以記住具體的層的結(jié)構(gòu)(包括參數(shù)大概的大小),但對于復(fù)雜網(wǎng)絡(luò),可以不用難為自己,理解思想為主,看見代碼能認(rèn)出是該網(wǎng)絡(luò),并且看見代碼之后能夠理解每層具體在做什么,做的事情如何與該網(wǎng)絡(luò)的核心思想一致。
3、了解此架構(gòu)被提出的背景,即可了解它的突破與局限
4、發(fā)現(xiàn)架構(gòu)與自己熟悉的不一致,先多谷歌下不同的架構(gòu)圖,或許你看到的只是別人基于經(jīng)典架構(gòu)修改的變體。實在糾結(jié),再回看提出框架的具體論文。

到這里,相信大家對卷積層和池化層的應(yīng)用已經(jīng)有了基本的了解。作為進(jìn)階內(nèi)容,大家可以試著擺脫課件中的代碼,自己對著架構(gòu)圖復(fù)現(xiàn)網(wǎng)絡(luò)架構(gòu),你甚至可以試著計算一下各層特征圖的大小,將此架構(gòu)改寫為更簡潔的形式,并利用這些架構(gòu)在經(jīng)典數(shù)據(jù)集上進(jìn)行各種嘗試。

總結(jié)

以上是生活随笔為你收集整理的Lesson 16.6Lesson 16.6 复现经典架构:LeNet5 复现经典架构 (2):AlexNet的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。