【BackBone】VGGNet复现 代码解析

Backbone 专栏收录该内容
2 篇文章 0 订阅

Backbone 是对图像进行特征提取,这一部分是整个CV任务的根基,后续的下游任务都是基于提取出来的图像特征去工作。 因此Backbone是基石,也是开始CV学习的第一步~
感兴趣的小伙伴可以关注我的专栏:

专栏:【Paper】Backbone

代码:https://github.com/ViatorSun/Backbone

intro:ICLR 2015
论文中文翻译:https://www.cnblogs.com/moeyu/p/14244065.html
arXiv:Very Deep Convolutional Networks for Large-Scale Image Recognition

本文代码见最后


在这里插入图片描述

1、VGG 网络框架

VGG是Oxford的Visual Geometry Group的组提出的。该网络是在ILSVRC 2014上的相关工作,主要工作是证明了 增加网络的深度能够在一定程度上影响网络最终的性能。VGG有两种结构,分别是VGG16和VGG19,两者并没有本质上的区别,只是网络深度不一样。VGG 相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)。

对于相同的感受野(与输出有关的输入图片的局部大小),

  • 堆积的小卷积核具有更少的参数;
  • 层数的增加引入了更多的非线性激活函数,使得模型可以学习更复杂的数据;
  • VGG中 采用 3个3x3卷积核来代替7x7卷积核,使用2个3x3卷积核来代替5*5卷积核;

VGG优点

  • VGGNet的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2);
  • 几个小滤波器(3x3)卷积层的组合比一个大滤波器(5x5或7x7)卷积层好;
  • 验证了通过不断加深网络结构可以提升性能;

VGG缺点

  • VGG耗费更多计算资源,并且使用了更多的参数(这里不是3x3卷积的锅),导致更多的内存占用(140M)。
  • 其中绝大多数的参数都是来自于第一个全连接层。VGG可是有3个全连接层啊!

在这里插入图片描述

一些小伙伴可能不太会数VGG的深度是如何定义的,在此VGG的深度是由卷积层 和 全联接层组合而成的,对于Maxpooling、soft-max等层不计算在内,计算在内的只包含 weight的层。



复现架构

在这里插入图片描述

代码框架

小伙伴的理解的时候可以根据序号 1-5进行分析,debug的时候会更加清楚 代码的框架设计。

最后,将网络模型架构打印出来与paper进行比对

    model = vgg16()
    print(model)

在这里插入图片描述


3、代码实现

#  !/usr/bin/env  python
#  -*- coding:utf-8 -*-
# @Time   :  2021.4
# @Author :  绿色羽毛
# @Email  :  lvseyumao@foxmail.com
# @Blog   :  https://blog.csdn.net/ViatorSun
# @Note   :  VGG网络


import torch
import torch.nn as nn
from   torch.autograd import Variable



try:
    from torch.hub import load_state_dict_from_url
except ImportError:
    from torch.utils.model_zoo import load_url as load_state_dict_from_url




__all__ = [ 'VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn', 'vgg19_bn', 'vgg19' ]



# 预训练vgg模型参数
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'    }


# VGG 网络框架参数   M 表示 MaxPool层
cfgs = { 'A': [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],                                             # VGG11
         'B': [64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],                                    # VGG13
         'D': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],                     # VGG16
         'E': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M']  }    # VGG19


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.Linear(512 * 7 * 7, 4096),
                                          nn.ReLU(True),
                                          nn.Dropout(),
                                          nn.Linear(4096, 4096),
                                          nn.ReLU(True),
                                          nn.Dropout(),
                                          nn.Linear(4096, 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 layer in self.modules():
            if isinstance(layer, nn.Conv2d):
                nn.init.kaiming_normal_(layer.weight, mode='fan_out', nonlinearity='relu')
                if layer.bias is not None:
                    nn.init.constant_(layer.bias, 0)
            elif isinstance(layer, nn.BatchNorm2d):
                nn.init.constant_(layer.weight, 1)
                nn.init.constant_(layer.bias, 0)
            elif isinstance(layer, nn.Linear):
                nn.init.normal_(layer.weight, 0, 0.01)
                nn.init.constant_(layer.bias, 0)


# 根据 cfg参数 构造对应的CNN层
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)

# 生成 VGG模型
def _vgg(arch, cfg, batch_norm, pretrained, progress, **kwargs):
    '''
    :param arch:       模型名字
    :param cfg:        构造模型参数
    :param batch_norm: 归一化层
    :param pretrained: 加载预训练参数
    :param progress:   加载进展
    :param kwargs:     参数
    :return:
    '''
    if pretrained:
        kwargs['init_weights'] = False
    model = VGG(make_layers(cfgs[cfg], batch_norm=batch_norm), **kwargs)
    if pretrained:
        state_dict = load_state_dict_from_url( model_urls[arch] , progress=progress )
        model.load_state_dict(state_dict)
    return model


def vgg11(pretrained=False, progress=True, **kwargs):
    """VGG 11-layer model (configuration "A")
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg11', 'A', False, pretrained, progress, **kwargs)

def vgg11_bn(pretrained=False, progress=True, **kwargs):
    """VGG 11-layer model (configuration "A") with batch normalization
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg11_bn', 'A', True, pretrained, progress, **kwargs)

def vgg13(pretrained=False, progress=True, **kwargs):
    """VGG 13-layer model (configuration "B")
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg13', 'B', False, pretrained, progress, **kwargs)

def vgg13_bn(pretrained=False, progress=True, **kwargs):
    """VGG 13-layer model (configuration "B") with batch normalization
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg13_bn', 'B', True, pretrained, progress, **kwargs)

def vgg16(pretrained=False, progress=True, **kwargs):
    """VGG 16-layer model (configuration "D")
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg16', 'D', False, pretrained, progress, **kwargs)

def vgg16_bn(pretrained=False, progress=True, **kwargs):
    """VGG 16-layer model (configuration "D") with batch normalization
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg16_bn', 'D', True, pretrained, progress, **kwargs)

def vgg19(pretrained=False, progress=True, **kwargs):
    """VGG 19-layer model (configuration "E")
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg19', 'E', False, pretrained, progress, **kwargs)

def vgg19_bn(pretrained=False, progress=True, **kwargs):
    """VGG 19-layer model (configuration 'E') with batch normalization
    Args:
        pretrained (bool): If True, returns a model pre-trained on ImageNet
        progress (bool): If True, displays a progress bar of the download to stderr
    """
    return _vgg('vgg19_bn', 'E', True, pretrained, progress, **kwargs)



def test():
    model = vgg16()
    print(model)
    img = torch.rand(2,3,224,224)
    img = Variable(img)
    output = model(img)
    print(output.size())




if __name__ == '__main__':
    test()

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值