当前位置: 首页 > news >正文

ResNet50V2学习笔记

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

一、前期准备

importtorchimporttorch.nnasnnimporttorch.optimasoptim

二、定义残差块

classResidualBlockV2(nn.Module):expansion=4def__init__(self,in_channels,out_channels,stride=1):super(ResidualBlockV2,self).__init__()# 预激活(Pre-activation)self.bn1=nn.BatchNorm2d(in_channels)self.relu=nn.ReLU(inplace=True)# 主干道:三层卷积self.conv1=nn.Conv2d(in_channels,out_channels,kernel_size=1,stride=stride,bias=False)self.bn2=nn.BatchNorm2d(out_channels)self.conv2=nn.Conv2d(out_channels,out_channels,kernel_size=3,padding=1,bias=False)self.bn3=nn.BatchNorm2d(out_channels)self.conv3=nn.Conv2d(out_channels,out_channels*self.expansion,kernel_size=1,bias=False)# 捷径:如果形状对不上,就用1x1卷积修一下self.shortcut=nn.Sequential()ifstride!=1orin_channels!=out_channels*self.expansion:self.shortcut=nn.Conv2d(in_channels,out_channels*self.expansion,kernel_size=1,stride=stride,bias=False)defforward(self,x):# 先激活,再分叉pre_act=self.relu(self.bn1(x))shortcut=self.shortcut(pre_act)out=self.conv1(pre_act)out=self.conv2(self.relu(self.bn2(out)))out=self.conv3(self.relu(self.bn3(out)))# 直接相加,后面没有激活函数,这就是V2returnout+shortcut

三、组装完整的ResNet-50V2模型

classResNet50V2(nn.Module):def__init__(self,num_classes=2):super(ResNet50V2,self).__init__()self.in_channels=64# 开头的特征提取层self.conv1=nn.Conv2d(3,64,kernel_size=7,stride=2,padding=3,bias=False)self.bn1=nn.BatchNorm2d(64)self.relu=nn.ReLU(inplace=True)self.maxpool=nn.MaxPool2d(kernel_size=3,stride=2,padding=1)# 堆叠50层的四个阶段self.layer1=self._make_layer(64,3,stride=1)self.layer2=self._make_layer(128,4,stride=2)self.layer3=self._make_layer(256,6,stride=2)self.layer4=self._make_layer(512,3,stride=2)# 最后的输出层self.bn=nn.BatchNorm2d(2048)self.avgpool=nn.AdaptiveAvgPool2d((1,1))self.fc=nn.Linear(2048,num_classes)def_make_layer(self,out_channels,blocks,stride):layers=[ResidualBlockV2(self.in_channels,out_channels,stride)]self.in_channels=out_channels*4for_inrange(1,blocks):layers.append(ResidualBlockV2(self.in_channels,out_channels))returnnn.Sequential(*layers)defforward(self,x):x=self.maxpool(self.relu(self.bn1(self.conv1(x))))x=self.layer4(self.layer3(self.layer2(self.layer1(x))))x=self.fc(torch.flatten(self.avgpool(self.relu(self.bn(x))),1))returnx

四、测试模型

if__name__=="__main__":print("正在组装 ResNet-50 V2")model=ResNet50V2(num_classes=2)print("正在生成一张虚拟的医学 X 光片送入模型...")dummy_input=torch.randn(2,3,224,224)output=model(dummy_input)print("PyTorch 代码翻译成功!模型结构正确!")print(f"模型的输出形状为:{output.shape}(预期看到的是 torch.Size([2, 2]))")

五、总结

本周我们完成了两大任务:

  1. 理论升级:理解ResNet-V2架构为何优于 V1。
  2. 框架迁移:将模型代码从TensorFlow翻译成PyTorch风格。

一、 理论篇:ResNet-V1 vs ResNet-V2 的区别

这两代网络的核心区别,在于激活函数(ReLU)和归一化(Batch Normalization, BN)放置的位置。

对比维度ResNet-V1 (后激活 Post-activation)ResNet-V2 (预激活 Pre-activation)
操作顺序卷积(Conv) -> 归一化(BN) -> 激活(ReLU)归一化(BN) -> 激活(ReLU) -> 卷积(Conv)
合并点后捷径(Shortcut)与主路相加后,还要经过一次 ReLU捷径(Shortcut)与主路相加后,直接输出,无 ReLU
反向传播梯度(Gradient)回传时,容易被最后的 ReLU 阻挡,导致梯度消失梯度可以通过捷径无损回传,畅通无阻。
最终效果网络深度通常局限在 100-200 层左右。彻底打破深度限制,可以训练1000 层以上的超深网络。

V2 的精髓就是“预激活(Pre-activation)”,把处理数据的操作提前。它的终极目的就是为了保持“捷径(Shortcut/Skip Connection)”的绝对纯净。只要捷径上没有激活函数拦路,模型犯错后的“纠错信号(梯度)”就能完美传回前面的层。


二、 代码篇:PyTorch 的“造车逻辑”

从 TensorFlow 换到 PyTorch,最大的感受是代码变得更加“面向对象(基于 Class 类)”。写一个 PyTorch 模型的标准动作分为两步:

  1. __init__(初始化函数) —— 准备零件库:
    在这里,我们把所有要用到的层(卷积层Conv2d、归一化层BatchNorm2d、激活函数ReLU、全连接层Linear)全部定义好。注意:这里只是把零件买回来,还没有组装。
  2. forward(前向传播函数) —— 流水线组装:
    在这里,我们规定数据x进入模型后,先经过哪个零件,再经过哪个零件,最后如何输出。这也是为什么捷径的加法out + shortcut是写在forward里面的。

三、 工程篇:工业级架构测试技巧

  • 虚拟输入(Dummy Input):在工程实践中,刚写完一个庞大的模型(如 50 层的 ResNet),我们不会立刻用真实数据集去训练(Training)
  • 结构验证(Architecture Validation):我们会生成一个形状一致的随机张量(例如torch.randn(2, 3, 224, 224),代表 2 张 224x224 的 3 通道图片),将其送入模型进行一次前向传播(Forward Pass)
  • 结论:如果代码能在 1 秒钟内跑通,并且输出的张量形状(Tensor Shape)符合预期(如[2, 2],代表 2 张图,2 个分类概率),这就证明我们的网络架构在逻辑上 100% 正确,没有维度不匹配的 Bug。

四、 拓展资料:V2 思想的跨领域迁移

ResNet-V2 的“预激活(Pre-activation)”思想,其本质是:为了防止深度网络退化,必须清除恒等映射路径(主通道)上的阻碍。

这个思想不仅在图像识别(CV)界称王,还跨界统治了自然语言处理(NLP)界:

  • 当今最火的大语言模型(如 GPT、BERT 内部的Transformer架构),早期使用的是Post-LN(后置层归一化),网络很难加深。
  • 后来全面改用Pre-LN(前置层归一化),这与 ResNet-V2 的预激活思想如出一辙,从而造就了今天几百上千层、参数量千亿级别的超级 AI。
http://www.jsqmd.com/news/694830/

相关文章:

  • 30天快速上手Python-01 开发环境 PyCharm
  • 机器学习中的近似方法:从数学基础到工程实践
  • Qianfan-OCR企业实操:合同文档表格Markdown识别+条款抽取落地案例
  • 奢侈品护理培训 - GrowthUME
  • 算法训练营第十一天| 80.删除有序数组中的重复项||
  • WeChatMsg终极指南:3步永久保存微信聊天记录,让AI记住你的珍贵回忆
  • ESP32接HC-SR04超声波模块,5V Echo信号怎么安全处理?一个电阻分压电路搞定
  • 新手避坑指南:从下载到验证,图文详解JDK1.8和JDK17环境变量配置全流程
  • 机器学习指标解析:AUC与KS值
  • 2026年户外拓展训练正规AI搜索优化服务商选型指南与实力分析 - 商业小白条
  • 从‘彩虹’到‘拖影’:给网络工程师讲明白光纤色散与高速网络故障排查
  • 保姆级教程:手把手教你用AST解混淆+日志插桩搞定某红书X-s签名(附完整代码)
  • TensorBoard可视化进阶:一条命令同时对比YOLOv6等模型的训练曲线(附避坑指南)
  • N_m3u8DL-RE:如何高效下载加密流媒体内容
  • 20260424紫题训练 - Link
  • LinkSwift:八大主流网盘直链下载解决方案的技术实践指南
  • 【ZYNQ进阶】AXI HP口实战:从时序解析到高效DMA引擎设计
  • 智慧树刷课插件终极指南:5分钟实现视频自动化学习
  • P3732 [HAOI2017] 供给侧改革 - Link
  • 2026年4月维普降AI全量横评:嘎嘎降AI和率零领先
  • 企业安全自查手册:利用开源工具V2.0对你的泛微、用友、致远OA做一次深度漏洞扫描
  • 2026年B端行业GEO优化服务商市场研究:推荐3家具备成熟服务能力的专业服务商 - 商业小白条
  • Day07-MySQL
  • 计算机毕业设计:Python量化交易管理平台 Django框架 requests爬虫 数据分析 可视化 大数据 大模型(建议收藏)✅
  • 细粒度并行计算架构Squire的设计与优化实践
  • AI数学基础:线性代数、概率论与微积分实战解析
  • Nucleus Co-Op技术解密:单机游戏分屏多人的创新突破与完整实现指南
  • 别再死记硬背SVPWM公式了!用STM32的定时器PWM模式2,手把手教你从Simulink仿真到代码落地
  • 3步轻松配置TTS-Vue桌面语音合成工具完整指南
  • 创建 ext4/xfs 文件系统供容器挂载