本节参考:《深度学习之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