pytorch Vgg16笔记

原本想直接跳过VGG,直接到PSEnet,但面试遇到很多使用VGG16的,于是静下心看看VGG网络到底是什么样的。
1 卷积核
又叫滤波器filter,在pytorch 卷积神经网络笔记,我已经写出了卷积计算的公式,但是卷积核的大小是多少呢?先看看卷积神经网络VGG16这么简单,为什么没人能说清? ,这里说卷积核一般用3*3.可是为什么呢?为什么倾向于使用3*3 小卷积核堆叠代替大卷积核
在实践中深度学习(05)–典型CNN结构(VGG13,16,19,3x3的卷积核在VGG16中应用的很好,后来才被ResNet等其他网络模型借鉴过去。

  • 像素八邻域信息
    数字图像处理入门(二)-邻域、连通性
    这里面又有三个概念4邻域、D领域、8领域、4连通、8连通,分别为下图所示:
    12345
    那么为什么3*3是最小的能够捕获像素八邻域信息的尺寸呢?
    为什么现在大家喜欢用3*3小卷积?
  • 感受野(Receptive Field)
    卷积神经网络中感受野的详细介绍,实际就是特征图feature map上的一个点对应输入图上的一个区域。
    两层3x3的卷积核卷积操作之后的感受野是5x5,P=0,S=1
    三层3x3卷积核操作之后的感受野是7x7,P=0,S=1
    feature map长宽计算公式,其中W为宽度,H为高度,P为填充大小,K为卷积核大小,S为步长
    W n + 1 = ( W n + 2 P K ) / S + 1 W_{n+1}=(W_n+2*P-K)/S+1
    H n + 1 = ( H n + 2 P K ) / S + 1 H_{n+1}=(H_n+2*P-K)/S+1
    根据这个公式就不难明白,两次卷积后,成为1个像素点,那么第一卷积后的feature map的维度必须是3x3,所以反推感受野是5x5.反推公式如下,从最后一层的感受野往前推
    R F i = ( R F i + 1 1 ) S + K ( 1 1 ) 1 + 3 = 3 ( 3 1 ) 1 + 3 = 5 RF_i=(RF_{i+1}-1)*S+K\Longrightarrow (1-1)*1+3=3\Longrightarrow (3-1)*1+3=5
    注意池化后的特征图大小为
    W n + 1 = ( W n F ) / S + 1 W_{n+1}=(W_n-F)/S+1
    H n + 1 = ( H n F ) / S + 1 H_{n+1}=(H_n-F)/S+1
    2 VGG网络
    vgg论文
    利用PyTorch实现VGG16,VGG系列(Pytorch实现),对比这两篇文章,打印网络,发现两者有差异,其中一个在全连接曾做了dropout,而另一个没有做。有一篇文章写的较为优雅,这里做一下笔记分析一下:
    2.1 nn.Sequential
    这里在全链接层Fully Connected Layer使用了nn.Sequential,我们知道FC曾主要做分类的,这里建立一个顺序执行的模型,pytorch系列7 -----nn.Sequential讲解,在这个容器中可以通过索引来获取,当然也可以取别名,参照pytorch教程之nn.Sequential类详解——使用Sequential类来自定义顺序连接模型
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),
        )
  # 下面是打印出来的顺序模型,前面的数字就是模型中层
  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=1000, bias=True)
  )

2.2 make_layers
在卷积层、池化层、RN层中在vgg的各个网络模型中有差异,于是将其中的参数提取出来,想用的时候只需要切换参数构建模型就很方便了。

cfg = {
    'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M'],
}
def make_layers(cfg, batch_norm=False):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = v
    return nn.Sequential(*layers)
def vgg13_bn(**kwargs):
    model = VGG(make_layers(cfg['B'], batch_norm=True), **kwargs)
    return model
发布了317 篇原创文章 · 获赞 168 · 访问量 46万+

猜你喜欢

转载自blog.csdn.net/warrah/article/details/102822575