訂閱
糾錯
加入自媒體

如何用Python從頭開始構(gòu)建VGG Net?

介紹

VGG-Network 是 K. Simonyan 和 A. Zisserman 在論文“Very Deep Convolutional Networks for Large-Scale Image Recognition”[1] 中提出的卷積神經(jīng)網(wǎng)絡(luò)模型。該架構(gòu)在 ImageNet 中實現(xiàn)了 92.7% 的 top-5 測試準(zhǔn)確率,該網(wǎng)絡(luò)擁有超過 1400 萬張屬于 1000 個類別的圖像。它是深度學(xué)習(xí)領(lǐng)域著名的架構(gòu)之一。將第1層和第2層的大內(nèi)核大小的過濾器分別替換為11和5,顯示了對 AlexNet 架構(gòu)的改進(jìn),多個3×3內(nèi)核大小的過濾器相繼出現(xiàn)。它接受了數(shù)周的訓(xùn)練,并使用了 NVIDIA Titan Black GPU。

VGG16 架構(gòu)卷積神經(jīng)網(wǎng)絡(luò)的輸入是一個固定大小的 224 × 224 RGB 圖像。它所做的唯一預(yù)處理是從每個像素中減去在訓(xùn)練數(shù)據(jù)集上計算的平均 RGB 值。然后圖像通過一堆卷積 (Conv.) 層運行,其中的過濾器的感受野非常小,為 3 × 3,這是捕捉左/右、上/下概念的最小尺寸,和中心部分。在其中一種配置中,它還利用了1 × 1卷積濾波器,可以觀察到輸入通道的線性變換之后是非線性的。卷積步幅固定為1像素; 卷積層輸入的空間填充使卷積后的空間分辨率保持不變,即3 × 3個卷積層的填充為1像素。然后空間池化由五個最大池化層執(zhí)行,其中 16 個最大池層跟在一些 Conv 層之后,但不是所有的 Conv  層。這個最大池化是在一個 2 × 2 像素的窗口上執(zhí)行的,步長為 2。

資料來源:neurohive.io

該架構(gòu)包含一堆卷積層,這些層在不同的架構(gòu)中具有不同的深度,然后是三個全連接 (FC) 層:前兩個 FC 各有 4096 個通道,第三個 FC 執(zhí)行 1000 路分類,因此包含 1000 個通道,每個類一個通道。最后一層是 soft-max 層。全連接層的配置在所有網(wǎng)絡(luò)中都是相似的。所有隱藏層都配備了整流 (ReLU) 非線性。此外,這里的一個網(wǎng)絡(luò)包含局部響應(yīng)歸一化 (LRN),這種歸一化不會提高訓(xùn)練數(shù)據(jù)集的性能,但使用它會導(dǎo)致內(nèi)存消耗和計算時間增加。架構(gòu)總結(jié):模型的輸入是固定大小的 224×224224×224 RGB 圖像預(yù)處理是從每個像素中減去訓(xùn)練集 RGB 值的平均值卷積層 17– 步幅固定為 1 像素– 3×33×3 的填充為 1 像素空間池化層– 按照慣例,這一層不計入網(wǎng)絡(luò)的深度– 空間池化是使用最大池化層完成的– 窗口大小為 2×22×2– 步幅固定為 2– Convnets 使用了 5 個最大池化層全連接層:第一:4096 (ReLU)第二:4096(ReLU)第三:1000(Softmax)架構(gòu)配置下圖包含 VGG 網(wǎng)絡(luò)的卷積神經(jīng)網(wǎng)絡(luò)配置以下:VGG-11VGG-11 (LRN)VGG-13VGG-16 (Conv1)VGG-16VGG-19

來源:“用于大規(guī)模圖像識別的深度卷積網(wǎng)絡(luò)”

上面提到的卷積神經(jīng)網(wǎng)絡(luò)配置每列一個。在下文中,網(wǎng)絡(luò)以其名稱 (A-E) 表示。所有配置都遵循傳統(tǒng)設(shè)計,僅在深度上有所不同:從網(wǎng)絡(luò)A中的11個權(quán)重層(8個轉(zhuǎn)換和3個FC層)到網(wǎng)絡(luò)E中的19個權(quán)重層(16個轉(zhuǎn)換和3個FC層)。每個卷積層的寬度很小,通道數(shù)很小,從第一層的64開始,然后在每個最大池化層之后繼續(xù)增加2倍,直到達(dá)到512。每個配置的參數(shù)數(shù)量如下所述。雖然它有很大的深度,但網(wǎng)絡(luò)中的權(quán)值的數(shù)目并不大于較淺的網(wǎng)絡(luò)中的權(quán)值的數(shù)目,而該網(wǎng)絡(luò)具有較大的卷積層寬度和感受野

來源:“用于大規(guī)模圖像識別的非常深的卷積網(wǎng)絡(luò)”

訓(xùn)練損失函數(shù)是多項邏輯回歸學(xué)習(xí)算法是基于動量反向傳播的小批量隨機梯度下降 (SGD)批量大小為 256動量是 0.9正則化L2 權(quán)重衰減(懲罰乘數(shù)為 0.0005)前兩個全連接層的 Dropout 設(shè)置為 0.5學(xué)習(xí)率初始:0.01當(dāng)驗證集精度停止提高時,它會降低到 10。盡管與 Alexnet 相比,它具有更多的參數(shù)和深度,但由于 CNN 的損失函數(shù)收斂所需的時期更少小卷積核和大深度的更多正則化。某些層的預(yù)初始化。訓(xùn)練圖像大小S 是同位素重縮放圖像的最小邊設(shè)置S的兩種方法Fix S,稱為單尺度訓(xùn)練這里 S = 256 和 S = 384Vary S,稱為多尺度訓(xùn)練S 來自 [Smin, Smax] 其中 Smin = 256, Smax = 512– 然后 224×224224×224圖像是從每次 SGD 迭代重新縮放的圖像中隨機裁剪的。

主要特征VGG16 共有 16 層,具有一定的權(quán)重。僅使用卷積和池化層。始終使用 3 x 3 內(nèi)核進(jìn)行卷積。202×2 大小的最大池。1.38 億個參數(shù)。在ImageNet 數(shù)據(jù)上訓(xùn)練。它的準(zhǔn)確率為 92.7%。另一個版本是 VGG 19,共有 19 個帶權(quán)重的層。這是一個非常好的深度學(xué)習(xí)架構(gòu),用于對任何特定任務(wù)進(jìn)行基準(zhǔn)測試。VGG 的預(yù)訓(xùn)練網(wǎng)絡(luò)是開源的,因此它可以開箱即用地用于各種類型的應(yīng)用程序。讓我們實現(xiàn) VGG 網(wǎng)絡(luò)首先讓我們?yōu)?VGG 網(wǎng)絡(luò)的每個版本創(chuàng)建過濾器映射。參考上面的配置圖片了解過濾器的數(shù)量。即為鍵名為 VGG11、VGG13、VGG16、VGG19 的版本創(chuàng)建一個字典,并分別根據(jù)每個版本中的過濾器數(shù)量創(chuàng)建一個列表。這里列表中的“M”稱為 Maxpool 操作。import torch
import torch.nn as nn
VGG_types = {
"VGG11": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
"VGG13": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
"VGG16": [64,64,"M",128,128,"M",256,256,256,"M",512,512,512,"M",512,512,512,"M",],
"VGG19": [64,64,"M",128,128,"M",256,256,256,256,"M",512,512,512,512,
         "M",512,512,512,512,"M",],}
創(chuàng)建一個全局變量來說明架構(gòu)的版本。然后創(chuàng)建一個名為 VGG_net 的類,輸入為 in_channels 和 num_classes,它接受輸入,如圖像通道數(shù)和輸出類數(shù)。初始化 Sequential 層,即在序列中,Linear layer->ReLU->Dropout。然后創(chuàng)建一個名為 create_conv_layers 的函數(shù),它將 VGGnet 架構(gòu)配置作為輸入,即我們上面為不同版本創(chuàng)建的列表。當(dāng)它遇到上面列表中的字母“M”時,它執(zhí)行 MaxPool2d 操作。VGGType = "VGG16"
class VGGnet(nn.Module):
   def __init__(self, in_channels=3, num_classes=1000):
       super(VGGnet, self).__init__()
       self.in_channels = in_channels
       self.conv_layers = self.create_conv_layers(VGG_types[VGGType])
self.fcs = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096),
nn.ReLU(),
nn.Dropout(p=0.5),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.conv_layers(x)
x = x.reshape(x.shape[0], -1)
x = self.fcs(x)
return x
def create_conv_layers(self, architecture):
layers = []
in_channels = self.in_channels
for x in architecture:
if type(x) == int:
out_channels = x
layers += [
nn.Conv2d(
in_channels=in_channels,
out_channels=out_channels,
kernel_size=(3, 3),
stride=(1, 1),
padding=(1, 1),
),
nn.BatchNorm2d(x),
nn.ReLU(),
]
in_channels = x
elif x == "M":
layers += [nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 2))]
return nn.Sequential(*layers)
完成后,編寫一個小的測試代碼來檢查我們的實現(xiàn)是否運行良好。在下面的測試代碼中,給出的類數(shù)是 500。if __name__ == "__main__":
   device = "cuda" if torch.cuda.is_available() else "cpu"
   model = VGGnet(in_channels=3, num_classes=500).to(device)
   # print(model)
   x = torch.randn(1, 3, 224, 224).to(device)
   print(model(x).shape)
輸出應(yīng)該是這樣的:

如果你想查看網(wǎng)絡(luò)架構(gòu),你可以取消對上述代碼中的*print(model)*語句的注釋。也可以通過更改變量 VGGType 中的 VGG 版本來嘗試使用不同的版本。

image.png

聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標(biāo)題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號