资讯动态

FA_CNN卷积神经网络八---VGG16 网络模型PyTorch

发布时间:2026/10/22 2:17:35 来源:尧图企业网站定制
FAFormulas and AlgorithmCNNConvolutional Neural Network1. 引言在深度学习图像分类任务中迁移学习是一种非常高效的做法。我们通常不会从零开始训练一个大型卷积神经网络如 VGG16而是直接使用在 ImageNet 上预训练好的模型参数再针对自己的数据集如 CIFAR10做微调。本文将基于 PyTorch 带你完成四件事下载预训练好的 VGG16 模型查看模型的函数用法与网络结构在模型末尾追加一个线性层适配 CIFAR10 的 10 分类任务修改模型内部的分类器替换最后一层输出维度。环境说明本文基于torchvision内置的 VGG16 实现代码可直接在 Jupyter Notebook 或 Python 脚本中运行。2. 下载网络模型首先我们使用torchvision.models来加载 VGG16。这里有两种方式pretrainedTrue下载在 ImageNet 上训练好的权重参数pretrainedFalse只创建网络结构不加载任何预训练参数。importtorchvision# 注意ImageNet 数据集已无法公开访问这里仅下载模型权重vgg16_truetorchvision.models.vgg16(pretrainedTrue)# 加载 ImageNet 预训练参数vgg16_falsetorchvision.models.vgg16(pretrainedFalse)# 不加载预训练参数print(ok)print(vgg16_true)运行后控制台会打印出 VGG16 的完整网络结构VGG( (features): Sequential( (0): Conv2d(3, 64, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (1): ReLU(inplaceTrue) (2): Conv2d(64, 64, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (3): ReLU(inplaceTrue) (4): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse) (5): Conv2d(64, 128, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (6): ReLU(inplaceTrue) (7): Conv2d(128, 128, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (8): ReLU(inplaceTrue) (9): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse) (10): Conv2d(128, 256, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (11): ReLU(inplaceTrue) (12): Conv2d(256, 256, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (13): ReLU(inplaceTrue) (14): Conv2d(256, 256, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (15): ReLU(inplaceTrue) (16): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse) (17): Conv2d(256, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (18): ReLU(inplaceTrue) (19): Conv2d(512, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (20): ReLU(inplaceTrue) (21): Conv2d(512, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (22): ReLU(inplaceTrue) (23): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse) (24): Conv2d(512, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (25): ReLU(inplaceTrue) (26): Conv2d(512, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (27): ReLU(inplaceTrue) (28): Conv2d(512, 512, kernel_size(3, 3), stride(1, 1), padding(1, 1)) (29): ReLU(inplaceTrue) (30): MaxPool2d(kernel_size2, stride2, padding0, dilation1, ceil_modeFalse) ) (avgpool): AdaptiveAvgPool2d(output_size(7, 7)) (classifier): Sequential( (0): Linear(in_features25088, out_features4096, biasTrue) (1): ReLU(inplaceTrue) (2): Dropout(p0.5, inplaceFalse) (3): Linear(in_features4096, out_features4096, biasTrue) (4): ReLU(inplaceTrue) (5): Dropout(p0.5, inplaceFalse) (6): Linear(in_features4096, out_features1000, biasTrue) ) )可以看到VGG16 由三部分组成features卷积层 池化层负责提取图像特征avgpool自适应平均池化将特征图缩放到7×7classifier全连接分类器最终输出 1000 类ImageNet 类别数。3. 查看函数用法如果你对vgg16函数的参数不太熟悉可以直接用help()查看官方文档importtorchvisionhelp(torchvision.models.vgg16)输出内容如下Help on function vgg16 in module torchvision.models.vgg: vgg16(pretrained: bool False, progress: bool True, **kwargs: Any) - torchvision.models.vgg.VGG VGG 16-layer model (configuration D) Very Deep Convolutional Networks For Large-Scale Image Recognition https://arxiv.org/pdf/1409.1556.pdf The required minimum input size of the model is 32x32. 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关键参数说明参数类型说明pretrainedbool是否加载 ImageNet 预训练权重默认Falseprogressbool下载时是否显示进度条默认True注意模型要求输入图像的最小尺寸为32×32因此 CIFAR10 的32×32图片刚好满足要求。4. 网络模型添加CIFAR10 数据集共有10 个类别而 VGG16 原始输出是1000 类。因此我们需要在模型末尾追加一个线性层把输出维度从 1000 改为 10。这里使用add_module()方法在 VGG16 后面添加一个名为add_linear的线性层importtorchvisionfromtorchimportnn# 下载 CIFAR10 训练集datasettorchvision.datasets.CIFAR10(./dataset,trainTrue,transformtorchvision.transforms.ToTensor(),downloadTrue)# 加载预训练模型vgg16_truetorchvision.models.vgg16(pretrainedTrue)# 在模型末尾追加一个线性层1000 - 10vgg16_true.add_module(add_linear,nn.Linear(1000,10))print(vgg16_true)运行后网络结构末尾会多出add_linear这一层VGG( (features): Sequential( # ... 卷积部分省略 ... ) (avgpool): AdaptiveAvgPool2d(output_size(7, 7)) (classifier): Sequential( (0): Linear(in_features25088, out_features4096, biasTrue) (1): ReLU(inplaceTrue) (2): Dropout(p0.5, inplaceFalse) (3): Linear(in_features4096, out_features4096, biasTrue) (4): ReLU(inplaceTrue) (5): Dropout(p0.5, inplaceFalse) (6): Linear(in_features4096, out_features1000, biasTrue) ) (add_linear): Linear(in_features1000, out_features10, biasTrue) )小结add_module()适合在模型最外层追加新模块操作简单直观。5. 网络模型修改除了在末尾追加新层我们也可以直接修改模型内部的某一层。例如把classifier中最后一层索引为 6的输出维度从 1000 改为 10importtorchvisionfromtorchimportnn# 创建不带预训练参数的模型vgg16_falsetorchvision.models.vgg16(pretrainedFalse)print(修改前)print(vgg16_false)# 替换 classifier 中索引为 6 的线性层vgg16_false.classifier[6]nn.Linear(4096,10)print(修改后)print(vgg16_false)修改后classifier的最后一层变为(classifier): Sequential( (0): Linear(in_features25088, out_features4096, biasTrue) (1): ReLU(inplaceTrue) (2): Dropout(p0.5, inplaceFalse) (3): Linear(in_features4096, out_features4096, biasTrue) (4): ReLU(inplaceTrue) (5): Dropout(p0.5, inplaceFalse) (6): Linear(in_features4096, out_features10, biasTrue) # 已修改 )小结通过索引直接赋值可以精准替换模型内部的任意子模块适合修改分类头等场景。6. 两种修改方式对比方式方法适用场景示例追加层add_module()在模型最外层新增模块vgg16_true.add_module(add_linear, nn.Linear(1000, 10))修改层索引赋值替换模型内部已有模块vgg16_false.classifier[6] nn.Linear(4096, 10)推荐做法在迁移学习中通常直接修改classifier[6]因为这样不会额外增加网络深度且能保留预训练权重若使用pretrainedTrue。7. 总结本文通过四个步骤带你完整走了一遍 VGG16 在 PyTorch 中的使用流程下载模型pretrainedTrue加载 ImageNet 预训练权重查看用法用help()了解函数参数追加层用add_module()在模型末尾添加线性层修改层用索引赋值替换classifier最后一层。掌握这些操作后你就可以轻松将 VGG16 迁移到自己的分类任务中。下一篇文章可以继续探讨如何冻结特征层、只训练分类头进一步提升微调效率。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑