VggNet网络结构详解

VggNet网络结构详解

#图像识别网络结构详解

一、概述

VGG在2014年由牛津大学著名研究组VGG (Visual Geometry Group) 提出,斩获该年ImageNet竞赛中 Localization Task (定位任务) 第一名 和 Classification Task (分类任务) 第二名。

二、网络详解

VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)。对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核是优于采用大的卷积核,因为多层非线性层可以增加网络深度来保证学习更复杂的模式,而且代价还比较小(参数更少)。
简单来说,在VGG中,使用了3个3x3卷积核来代替7x7卷积核,使用了2个3x3卷积核来代替5*5卷积核,这样做的主要目的是在保证具有相同感知野的条件下,提升了网络的深度,在一定程度上提升了神经网络的效果。比如,3个步长为1的3x3卷积核的一层层叠加作用可看成一个大小为7的感受野(其实就表示3个3x3连续卷积相当于一个7x7卷积),其参数总量为 3x(9xC^2) ,如果直接使用7x7卷积核,其参数总量为 49x(C^2) ,这里 C指的是输入和输出的通道数。很明显,27x(C^2)小于 49x(C^2),即减少了参数;而且3x3卷积核有利于更好地保持图像性质。下表1为各个网络配置,表2为VGG-19网络各层详细情况,图1为VGG-16结构图
表1:各个网络的配置
VggNet网络结构详解_第1张图片
表2:VGG-19网络各层详细
VggNet网络结构详解_第2张图片
图1 VGG-16网络结构图
VggNet网络结构详解_第3张图片

三、VGGNet改进点总结

1 使用更小的33卷积核,和更深的网络。两个33卷积核的堆叠相对于55卷积核的视野,三个33卷积核的堆叠相当于77卷积核的视野。这样一方面可以减少参数(3个堆叠的33结构只有77结构参数数量的(333)/(77)=55%);另一方面拥有更多的非线性变换,增加了CNN对特征的学习能力。
2 在VGGNet的卷积结构中,引入1*1的卷积核,在不影响输入输出维度的情况下,引入非线性变换,增加网络的表达能力,降低计算量。
3 训练时,先训练级别简单(层数较浅)的VGGNet的A级网络,然后使用A级网络的权重来初始化后面的复杂模型,加快训练的收敛速度。
4 采用了Multi-Scale的方法来训练和预测。可以增加训练的数据量,防止模型过拟合,提升预测准确率。
注:Single-Scale: 是指把一张图片送到CNN;
Multi-Scale:一般会送到CNN十张图片:比如高宽是256Χ256的图片,Multi-Scale会在它的四个角以及中心进行裁剪 ,将其裁剪为10张 224Χ 224 的图片,然后再进行翻转,总共十张图片,最后全部送到 CNN。

四、VGGNet存在问题

唯一的不足是,在进行反向传播时,中间的卷积层可能会导致占用更多的内存。

五、VGG代码

代码如下(示例):

import torch.nn as nn
import torch

__all__ = [
    'VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn',
    'vgg19_bn', 'vgg19',
]
model_urls = {
     
    'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth',
    'vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth',
    'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth',
    'vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth',
    'vgg11_bn': 'https://download.pytorch.org/models/vgg11_bn-6002323d.pth',
    'vgg13_bn': 'https://download.pytorch.org/models/vgg13_bn-abd245e5.pth',
    'vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth',
    'vgg19_bn': 'https://download.pytorch.org/models/vgg19_bn-c79401a0.pth',
}

1.定义分类网络结构

代码如下(示例):

class VGG(nn.Module):
    # 定义初始化函数
    def __init__(self, features, num_classes=1000, init_weights=True):
        super(VGG, self).__init__()
        self.features = features
        self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
        self.classifier = nn.Sequential(
            nn.Dropout(0.4),
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU6(True),
            nn.Dropout(0.4),
            nn.Linear(4096, 2048),
            nn.ReLU6(True),
            nn.Dropout(0.4),
            nn.Linear(2048, num_classes),

        )

        if init_weights:
            self._initialize_weights()
     
    # 定义前向传播函数
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)

        return x
    
    # 定义初始化权重函数
    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                nn.init.constant_(m.bias, 0)

2 .定义提取特征网络结构函数

代码如下(示例):

def make_layers(cfg:list, 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)
cfg = {
     
    'A0': [64, 'M', 128, 'M', 256, 256, 'M'],
    'A1': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M'],
    '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'],
}

3 . 定义实例化给定的配置模型函数

代码如下(示例):

def vgg7(**kwargs):
    model = VGG(make_layers(cfg['A0']), **kwargs)
    return model

def vgg7_bn(**kwargs):
    model = VGG(make_layers(cfg['A0'], batch_norm=True), **kwargs)
    return model


def vgg9(**kwargs):
    model = VGG(make_layers(cfg['A1']), **kwargs)
    return model


def vgg9_bn(**kwargs):
    model = VGG(make_layers(cfg['A1'], batch_norm=True), **kwargs)
    return model


def vgg11(**kwargs):
    model = VGG(make_layers(cfg['A']), **kwargs)
    return model


def vgg11_bn(**kwargs):
    model = VGG(make_layers(cfg['A'], batch_norm=True), **kwargs)
    return model


def vgg13(**kwargs):
    model = VGG(make_layers(cfg['B']), **kwargs)
    return model


def vgg13_bn(**kwargs):
    model = VGG(make_layers(cfg['B'], batch_norm=True), **kwargs)
    return model


def vgg16(**kwargs):
    model = VGG(make_layers(cfg['D']), **kwargs)
    return model


def vgg16_bn(**kwargs):
    model = VGG(make_layers(cfg['D'], batch_norm=True), **kwargs)
    return model


def vgg19(**kwargs):
    model = VGG(make_layers(cfg['E']), **kwargs)
    return model


def vgg19_bn(**kwargs):
    model = VGG(make_layers(cfg['E'], batch_norm=True), **kwargs)
    return model

if __name__ == '__main__':
    # 'VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', 'vgg19_bn', 'vgg19'
    # Example
    net13 = vgg13_bn()
    print(net13)

六 总结

1.在本文中主要介绍了VggNet网络结构以及各层的使用情况。
2.总结了VggNet网络结构的优缺点 。
3.提供了示例代码。
本人水平有限,文章有写的不对的地方欢迎各位指出!!!

你可能感兴趣的:(图像识别分类网络,人工智能,神经网络,深度学习,python,pytorch)