深入理解VGG16模型与代码实现

一、VGG16简介

      VGG16(Visual Geometry Group 16)是一种深度卷积神经网络模型,由牛津大学的研究团队Visual Geometry Group开发。它是2014年的ImageNet图像识别挑战中的参赛模型之一,并在该挑战中取得了非常出色的结果。

      VGG16模型的设计思想是通过堆叠多个较小的卷积层和池化层来构建深层网络,以增强模型的表达能力。具体来说,VGG16模型由16个卷积层和3个全连接层组成。其中,卷积层主要用于提取输入图像的特征,而全连接层则用于将提取到的特征映射到类别概率上。

      VGG16的卷积部分采用了较小的3x3卷积核和步长为1的卷积操作,这种设计方式使得网络可以更深,从而提升了特征的表达能力。在每两个卷积层之间,VGG16还使用了2x2的最大池化层,以减小特征图的尺寸并保留最显著的特征。在最后的卷积层之后,VGG16采用了三个全连接层,每个全连接层都有4096个隐藏单元,最后一个全连接层输出模型的预测结果。

      VGG16的一个重要特点是它的模型结构相对简单且易于理解,没有使用复杂的技巧或模块。这种简单性使得VGG16成为深度学习中的经典模型之一,被广泛应用于计算机视觉领域的各种任务,如图像分类、目标检测和图像生成等。

      然而,由于VGG16的结构较为庞大,参数量较多,导致模型的训练和推理过程较为耗时。为了解决这个问题,后续的研究工作提出了一些改进版本的VGG模型,如VGG19和VGGNet等,它们在VGG16的基础上进行了一些调整和优化,以提高模型的性能和效率。

二、VGG16模型结构

输入(224*224)图像
conv3-64
conv3-64
maxpool
conv3-128
conv3-128
maxpool
conv3-256
conv3-256
conv3-256
maxpool
conv3-512
conv3-512
conv3-512
maxpool
conv3-512
conv3-512
conv3-512
maxpool
FC-4096
FC-4096
FC-1000
soft-max

 

 针对VGG16进行具体分析发现,VGG16共包含:

13个卷积层(Convolutional Layer),分别用conv3-XXX表示 (XXX为输出通道数,3代表kernel_size)
3个全连接层(Fully connected Layer),分别用FC-XXXX表示(XXX为输出神经元个数)
5个池化层(Pool layer),分别用maxpool表示

三、计算过程 

结合模型来看,更容易理解。

 三、详细解释

1.卷积 (conv2d)

pytorch官网的介绍Conv2d — PyTorch master documentation

参数参数类型说明
in_channelsint输入图像通道数
out_channelsint卷积产生的通道数
kernel_size(int or tuple)卷积核尺寸,可以设为1个int型数或者一个(int, int)型的元组。例如(2,3)是高2宽3卷积核
stride(int or tuple, optional)卷积步长,默认为1。可以设为1个int型数或者一个(int, int)型的元组。
padding(int or tuple, optional)填充操作,控制padding_mode的数目
padding_mode(string, optional)padding模式,默认为Zero-padding 。
dilation(int or tuple, optional)扩张操作:控制kernel点(卷积核点)的间距,默认值:1。
groups(int, optional)group参数的作用是控制分组卷积,默认不分组,为1组。
bias(bool, optional)为真,则在输出中添加一个可学习的偏差。默认:True。

其实就是一个卷积核对图片上的一块区域进行乘积的过程,计算图如下

 

再看下面这条

输入计算过程输出
【224*224*3】conv2d(in_channels=3,out_channels=64,kernel_size=3,stride=1,padding=1)【224*224*64】

 输入:224(宽度)*224(高度)*3(图片通道数,因为是RGB,所以是3)

计算过程:conv2d(in_channels=3,out_channels=64,kernel_size=3,stride=1,padding=1),参数设置原因如下

参数说明
in_channels=3原始图片RGB通道数为3
out_channels=64根据conv3-64,可知第一层输出通道数64
kernel_size=3根据conv3-64,可知第一层kernel_size为3
stride=1默认值
padding=1原论文中padding=same 即为1,也可根据等会的公式推出

  输出:224(宽度)*224(高度)*64(根据conv3-64,得知输出后的通道数64)

卷积后的计算公式
输出特征图的宽度=(输入特征图的宽度-卷积核尺寸+2*填充)÷步长+1

输出特征图的高度=(输入特征图的高度-卷积核尺寸+2*填充)÷步长+1

验证:

224=(224-3+2*1)÷1+1=224

224=(224-3+2*1)÷1+1=224

所以得出卷积后的特征图为宽为224,高为224,通道数为64

 2.最大池化(maxpool)

pytorch官网的介绍MaxPool2d — PyTorch master documentation

参数参数类型说明
kernel_size (Union[intTuple[intint]]表示做最大池化的窗口大小,可以是单个值,也可以是tuple元组
stride(Union[intTuple[intint]]步长

 其实就是一个卷积核对图片上的一块区域进行取最大值的过程,计算图如下

 

 

再看下面这条

输入计算过程输出
【224*224*64】MaxPool2d(kernel_size=2,stride=2)【112*112*64】

输入:224(宽度)*224(高度)*64(根据上一层的输出【224*224*64】作为这一层的输入,可知通道数为64)

计算过程:MaxPool2d(kernel_size=2,stride=2),参数设置原因如下

参数说明
kernel_size作者定义的
stride默认与kernel_size一致,即为2

  输出:112(宽度)*112(高度)*64(MaxPooling操作只对特征图的空间维度进行操作,而不会改变特征图的通道数。)

池化后的计算公式
输出特征图的宽度=(输入特征图的宽度-池化核宽度)÷步长+1

输出特征图的高度=(输入特征图的高度-池化核高度)÷步长+1

验证:

112=(224-2)÷2+1

112=(224-2)÷2+1

所以得出池化后的特征图为宽为112,高为112,通道数为64

 3.总结

每一层的输出通道数要与下一层的输入通道数要一致,特别是在yolo以及一些轻量级网络的配置中。

四、参数量计算

 五、搭建模型

import torch
import torch.nn as nn


# 定义 VGG16 模型
class VGG16(nn.Module):
    def __init__(self, num_classes=1000):
        super(VGG16, self).__init__()
        self.features = nn.Sequential(
            # 第一段卷积层
            nn.Conv2d(3, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            # 第二段卷积层
            nn.Conv2d(64, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            # 第三段卷积层
            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            # 第四段卷积层
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),

            # 第五段卷积层
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes)
        )

    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x


# 创建 VGG16 模型实例
model = VGG16()

# 打印模型结构
print(model)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值