25 使用塊的網(wǎng)絡(luò) VGG【動手學(xué)深度學(xué)習(xí)v2】

AlexNet缺點:結(jié)構(gòu)不規(guī)則,不規(guī)范,不清晰。
若要向更大規(guī)模的網(wǎng)絡(luò)發(fā)展,必須用更規(guī)范的方式去構(gòu)建網(wǎng)絡(luò)。

VGG思想:通過堆疊卷積塊構(gòu)建網(wǎng)絡(luò)
使用卷積核更小、層數(shù)更深的網(wǎng)絡(luò)效果優(yōu)于卷積核更大、層數(shù)較淺的網(wǎng)絡(luò)



通過不同的超參數(shù)設(shè)定,可以構(gòu)建出形態(tài)各異的VGG網(wǎng)絡(luò)


代碼實現(xiàn):
該函數(shù)有三個參數(shù),分別對應(yīng)于卷積層的數(shù)量num_convs
、輸入通道的數(shù)量in_channels
?和輸出通道的數(shù)量out_channels
.
import torch from torch import nn from d2l import torch as d2l def vgg_block(num_convs, in_channels, out_channels): layers = [] for _ in range(num_convs): layers.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1)) layers.append(nn.ReLU()) in_channels = out_channels layers.append(nn.MaxPool2d(kernel_size=2,stride=2)) return nn.Sequential(*layers)
與AlexNet、LeNet一樣,VGG網(wǎng)絡(luò)可以分為兩部分:第一部分主要由卷積層和匯聚層組成,第二部分由全連接層組成。
超參數(shù)變量conv_arch
。該變量指定了每個VGG塊里卷積層個數(shù)和輸出通道數(shù)。全連接模塊則與AlexNet中的相同。
原始VGG網(wǎng)絡(luò)有5個卷積塊,其中前兩個塊各有一個卷積層,后三個塊各包含兩個卷積層。 第一個模塊有64個輸出通道,每個后續(xù)模塊將輸出通道數(shù)量翻倍,直到該數(shù)字達(dá)到512。由于該網(wǎng)絡(luò)使用8個卷積層和3個全連接層,因此它通常被稱為VGG-11。
conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
下面的代碼實現(xiàn)了VGG-11??梢酝ㄟ^在conv_arch
上執(zhí)行for循環(huán)來簡單實現(xiàn)。
def vgg(conv_arch): conv_blks = [] in_channels = 1 # 卷積層部分 for (num_convs, out_channels) in conv_arch: conv_blks.append(vgg_block(num_convs, in_channels, out_channels)) in_channels = out_channels return nn.Sequential( *conv_blks, nn.Flatten(), # 全連接層部分 nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5), nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5), nn.Linear(4096, 10)) net = vgg(conv_arch)
構(gòu)建一個高度和寬度為224的單通道數(shù)據(jù)樣本,以觀察每個層輸出的形狀。
X = torch.randn(size=(1, 1, 224, 224)) for blk in net: X = blk(X) print(blk.__class__.__name__,'output shape:\t',X.shape)
Sequential output shape: torch.Size([1, 64, 112, 112]) Sequential output shape: torch.Size([1, 128, 56, 56]) Sequential output shape: torch.Size([1, 256, 28, 28]) Sequential output shape: torch.Size([1, 512, 14, 14]) Sequential output shape: torch.Size([1, 512, 7, 7]) Flatten output shape: torch.Size([1, 25088]) Linear output shape: torch.Size([1, 4096]) ReLU output shape: torch.Size([1, 4096]) Dropout output shape: torch.Size([1, 4096]) Linear output shape: torch.Size([1, 4096]) ReLU output shape: torch.Size([1, 4096]) Dropout output shape: torch.Size([1, 4096]) Linear output shape: torch.Size([1, 10])
由于VGG-11比AlexNet計算量更大,因此我們構(gòu)建了一個通道數(shù)較少的網(wǎng)絡(luò),足夠用于訓(xùn)練Fashion-MNIST數(shù)據(jù)集。
ratio = 4 small_conv_arch = [(pair[0], pair[1] // ratio) for pair in conv_arch] net = vgg(small_conv_arch)
除了使用略高的學(xué)習(xí)率外,模型訓(xùn)練過程與?7.1節(jié)中的AlexNet類似。
lr, num_epochs, batch_size = 0.05, 10, 128 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
loss 0.220, train acc 0.918, test acc 0.900 2578.4 examples/sec on cuda:0