基于CNN的FashionMNIST数据集识别4——VGG-16模型

模型背景

VGG-16 是牛津大学 ‌Visual Geometry Group (VGG)‌ 在 2014 年提出的经典卷积神经网络模型,发表于论文《Very Deep Convolutional Networks for Large-Scale Image Recognition》。它在 ImageNet 图像分类任务中取得了突破性成绩,核心贡献是证明了 ‌网络深度‌ 对模型性能的重要性(当然太深了也不好)。

源码

import torch
from torch import nn
from torchsummary import summary

class VGG16(nn.Module):
    def __init__(self):
        """VGG16网络结构(适配单通道输入)"""
        super().__init__()
        
        # 特征提取部分 假设输入图像是224x224
        self.block1 = nn.Sequential(  # [224x224]
            nn.Conv2d(1, 64, kernel_size=3, padding=1),  # 保持224x224
            nn.ReLU(),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2)  # 输出[112x112]
        )
        
        self.block2 = nn.Sequential(
            nn.Conv2d(64, 128, kernel_size=3, padding=1),  # 保持112x112
            nn.ReLU(),
            nn.Conv2d(128, 128, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)  # 输出[56x56]
        )
        
        self.block3 = nn.Sequential(
            nn.Conv2d(128, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)  # 输出[28x28]
        )
        
        self.block4 = nn.Sequential(
            nn.Conv2d(256, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)  # 输出[14x14]
        )
        
        self.block5 = nn.Sequential(
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.Conv2d(512, 512, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)  # 输出[7x7]
        )
        
        # 分类部分
        self.block6 = nn.Sequential(
            nn.Flatten(),
            nn.Linear(7*7*512, 256),  # 输入维度25088
            nn.ReLU(),
            nn.Linear(256, 128),
            nn.ReLU(),
            nn.Linear(128, 10)  # 假设是10分类任务
        )
        
        # 参数初始化
        self._initialize_weights()
        
    def _initialize_weights(self):
        """网络参数初始化"""
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, nonlinearity='relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight, 0, 0.01)
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
                    
    def forward(self, x):
        """前向传播"""
        x = self.block1(x)
        x = self.block2(x)
        x = self.block3(x)
        x = self.block4(x)
        x = self.block5(x)
        x = self.block6(x)
        return x

if __name__ == "__main__":
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = VGG16().to(device)
    # 测试网络结构(输入应为单通道224x224图像)
    print(summary(model, (1, 224, 224)))

设计思路

  • 统一的小卷积核
    全部使用 ‌3×3 卷积核‌替代大尺寸卷积核(如 5×5、7×7),优势在于:

    • 减少参数量(2个3×3卷积 ≈ 1个5×5卷积的感知野,但参数少 28%)
    • 增加非线性(每个卷积后接 ReLU)
  • 深度堆叠结构
    通过堆叠多个小卷积核构建深层网络(16-19 层),提升了特征提取能力。

  • 简洁的架构模式
    每阶段包含 1~4 个卷积层 + 1 个最大池化层,结构高度统一。

为了方便计算,每个分块最后都有一个池化层,并且池化层的步长和内核大小都是2,套用前面的公式,池化后的图像宽度(高度)是:

OUT = (IN + 2*0 - 2)/2 +1 = IN/2

每经过一块,图像的面积都缩小到以前的1/2 * 1/2 = 1/4,方便全连接层的计算。

另外,在卷积层的计算也很讨巧,卷积层的内核是3*3,填充为1,步长是1。经过卷积后,图像的宽度(高度)是:

OUT = (IN +2*1 - 3)/1 +1 = IN

也就是说卷积层并不会改变图像的尺寸,只会增加图像的通道数,简化了计算。

特点

可以看到,由于层数比较多,哪怕减少了全连接层的神经元数量,参数量也达到了两千万。参数量过大会带来两个核心问题:

  • 计算量大,训练起来慢
  • 训练出的模型容易过拟合,在验证集上表现明显劣于训练集

针对过拟合现象,有以下解决方式:

  • 用全局平均池化(GAP)替代全连接层
  • 添加 Dropout 层防止过拟合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值