福州市网站建设_网站建设公司_小程序网站_seo优化
2026/1/2 18:37:18 网站建设 项目流程

https://blog.csdn.net/weixin_45655710?type=blog
@浙大疏锦行

DAY 44 预训练模型
知识点回顾:
1.预训练的概念
2.常见的分类预训练模型
3.图像预训练模型的发展史
4.预训练的策略
5.预训练代码实战:resnet18
作业:
1.尝试在cifar10对比如下其他的预训练模型,观察差异,尽可能和他人选择的不同
2.尝试通过ctrl进入resnet的内部,观察残差究竟是什么
1.需要调用预训练模型和加载权重
2.需要resize图片让其可以适配模型
3.需要修改最后的全连接层以适应数据集
其中,训练过程中,为了不破坏最开始的特征提取器的参数,最开始往往先冻结住特征提取器的参数,然后训练全连接层,大约在5-10个epoch后解冻训练。
主要做特征提取的部分叫做backbone骨干网络;负责融合提取的特征的部分叫做Feature Pyramid Network (FPN); 负责输出的预测部分的叫做Head。
首先复用下之前的代码
这句话可以忽略,这是未来的内容

你好!欢迎进入DAY 44:预训练模型与迁移学习

今天的课程标志着你从“从零造轮子”正式迈入“站在巨人肩膀上”的阶段。利用 ImageNet 上预训练好的强大模型(如 ResNet),我们能用极少的数据和时间训练出远超之前的模型。

以下是针对今日作业的详细指导,涵盖了不同预训练模型的对比实验以及对 ResNet 残差结构的探索。


作业 1:对比其他预训练模型 (VGG16 vs MobileNetV2)

为了体现差异性,我选择了两个风格迥异的模型进行对比:

  1. VGG16:经典的“深层堆叠”网络,参数量巨大(约 1.38 亿),特征提取能力强但训练慢。
  2. MobileNetV2:专为移动端设计的轻量级网络,引入了“深度可分离卷积”和“倒残差结构”,速度快但精度略低。
核心代码实现

你需要修改create_model函数来适配不同的架构。注意 VGG 和 MobileNet 的分类头(Head)结构与 ResNet 不同。

fromtorchvisionimportmodelsimporttorch.nnasnndefcreate_model(model_name,num_classes=10,pretrained=True):ifmodel_name=='vgg16':model=models.vgg16(pretrained=pretrained)# VGG16 的分类头是 model.classifier[6]in_features=model.classifier[6].in_features model.classifier[6]=nn.Linear(in_features,num_classes)elifmodel_name=='mobilenet_v2':model=models.mobilenet_v2(pretrained=pretrained)# MobileNetV2 的分类头是 model.classifier[1]in_features=model.classifier[1].in_features model.classifier[1]=nn.Linear(in_features,num_classes)elifmodel_name=='resnet18':model=models.resnet18(pretrained=pretrained)model.fc=nn.Linear(model.fc.in_features,num_classes)returnmodel.to(device)# 在 main 函数中切换 model_name 进行实验# model = create_model('vgg16')# model = create_model('mobilenet_v2')

实验预期观察点

  • VGG16:显存占用极高,训练速度慢,但在小图上可能不容易过拟合(因为参数太多被 Dropout 抑制了)。
  • MobileNetV2:训练飞快,显存占用极低,准确率可能略低于 ResNet18,但性价比极高。

作业 2:深入 ResNet 内部(探索残差结构)

要理解“残差”,最好的办法是看源码。

  1. 操作步骤
  • 在 VSCode 中按住Ctrl(Windows) 或Cmd(Mac) 点击代码中的models.resnet18
  • 跳转后找到ResNet类定义,重点关注BasicBlock类。
  1. 核心代码解读 (BasicBlock)
classBasicBlock(nn.Module):def__init__(self,inplanes,planes,stride=1,downsample=None):super(BasicBlock,self).__init__()# 两个 3x3 卷积self.conv1=conv3x3(inplanes,planes,stride)self.bn1=norm_layer(planes)self.relu=nn.ReLU(inplace=True)self.conv2=conv3x3(planes,planes)self.bn2=norm_layer(planes)self.downsample=downsampledefforward(self,x):identity=x# 1. 保留原始输入(短路连接)out=self.conv1(x)out=self.bn1(out)out=self.relu(out)out=self.conv2(out)out=self.bn2(out)ifself.downsampleisnotNone:identity=self.downsample(x)# 如果维度变了,需要调整 identity 的维度out+=identity# 2. 核心操作:将原始输入加到卷积输出上out=self.relu(out)returnout

残差(Residual)是什么?
传统的网络试图学习 ,而 ResNet 试图学习 (即残差)。

  • 物理意义:如果不加残差,深层网络容易发生“退化”(Degradation),即层数越深效果反而越差。残差连接提供了一条“高速公路”(Shortcut),让梯度能无损地传回前面的层,解决了梯度消失问题,使得训练 100 层甚至 1000 层的网络成为可能。

💡 实验小贴士

  1. 冻结策略:作业代码中已经包含了freeze_model函数。在使用 VGG 时,由于参数量巨大,建议冻结model.features部分,只训练model.classifier,否则你的 GPU 可能会爆显存。
  2. Resize 问题:虽然 CIFAR-10 是 32x32,但大部分预训练模型(如 VGG/ResNet)在 ImageNet 上是 224x224 训练的。直接用 32x32 虽然能跑(卷积核会自动适配),但效果不如Upsample(上采样)到 224x224 好。不过为了节省计算资源,作业中保持 32x32 也是可以接受的,ResNet 对小图的适应性还不错。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询