本節參考:《深度學習之PyTorch物體檢測實戰》
《DIVE INTO DEEP LEARNING》
VGG塊
VGG提出了可以通過重複使用簡單的基礎塊來構建深度模型的思路
VGG塊的組成規律是:連續使用數個相同的填充爲1、窗口形狀爲的卷積層後接上一個步幅爲2、窗口形狀爲的最大池化層。卷積層保持輸入的高和寬不變,而池化層則對其減半。每經過一個VGG塊(除了最後一個),都會使通道數翻倍而寬高減半,而由於每個卷積層的窗口大小一樣,所以每層的模型參數尺寸和計算複雜度與輸入高、輸入寬、輸入通道數和輸出通道數的乘積成正比。VGG這種高和寬減半以及通道翻倍的設計使多數卷積層都有相同的模型參數尺寸和計算複雜度。
()(簡單計算一下第一個卷積層進行一次前向傳播需要進行大約8千萬次乘法運算)
多個的卷積核進行堆疊,相比更大的卷積核,在獲得相同感受野的情況下,所需參數量更少。同時因爲擁有更多的激活函數,表達能力也更強。
def vgg_block(num_convs, in_channels, out_channels):
blk = []
for _ in range(num_convs):
blk.append(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1))
blk.append(nn.ReLU(inplace=True))
in_channels = out_channels
blk.append(nn.MaxPool2d(2, 2))
return blk
VGG網絡
下面以VGG16爲例進行實現:
# 以ImageNet的3*224*224圖像爲例
class VGG(nn.Module):
def __init__(self, num_classes=1000):
super(VGG, self).__init__()
layers = []
conv_num = [2, 2, 3, 3, 3]
in_channels = [3, 64, 128, 256, 512, 512]
for i in range(5):
layers += vgg_block(conv_num[i], in_channels[i], in_channels[i + 1])
self.features = nn.Sequential(*layers)
self.classifier = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(True),
nn.Dropout(),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x