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

Python训练营打卡 Day50

预训练模型+CBAM模块

知识点回顾:

  1. resnet结构解析
  2. CBAM放置位置的思考
  3. 针对预训练模型的训练策略
    1. 差异化学习率
    2. 三阶段微调

预训练模型 + CBAM 模块

知识点回顾
  1. ResNet 结构解析

    • 残差块:ResNet 的核心是残差块,它通过残差连接解决了深层网络的梯度消失问题。残差块允许梯度直接传播到后面的层,从而使得网络能够训练得更深。

    • 网络结构:ResNet 由多个残差块组成,每个残差块包含两个或三个卷积层,以及一个 shortcut 连接。shortcut 连接将输入直接加到卷积层的输出上。

  2. CBAM 放置位置的思考

    • CBAM 模块:CBAM(Convolutional Block Attention Module)结合了通道注意力和空间注意力,能够动态调整特征图的重要性。CBAM 通常放置在每个残差块的后面,以增强每个块的特征表达能力。

  3. 针对预训练模型的训练策略

    • 微调策略:使用预训练模型作为初始化,然后在目标任务数据上进行微调。微调时可以调整不同的学习率,对不同层进行不同程度的训练。

    • 差异化学习率:对不同的层设置不同的学习率,通常对后面的层设置较高的学习率,对前面的层设置较低的学习率,以保护预训练的特征。

    • 三阶段微调:分阶段进行微调,逐步调整模型的参数,确保模型能够稳定收敛。

用比喻解释
  • ResNet 结构:ResNet 就像是一家连锁餐厅的标准化厨房,每个厨房都有多个工作站(残差块),每个工作站负责特定的烹饪步骤。残差连接就像是每个工作站都有一个直接传递原材料的通道,确保即使某个工作站出现问题,原材料也能顺利传递到下一个工作站。

  • CBAM 模块:CBAM 就像是每个工作站中的“智能烹饪助手”,它能够根据当前的烹饪情况动态调整每个工作站的输出,确保每个工作站的输出都是最优的。

  • 预训练模型:预训练模型就像是这家连锁餐厅已经经过长期运营、积累了丰富经验的厨房,可以快速适应新的菜品需求。

  • 微调策略:微调策略就像是在新店开业时,对已有菜单进行微调,以适应当地顾客的口味。差异化学习率就像是对不同经验的厨师进行不同程度的培训,确保新厨师能够快速学习,而资深厨师能够稳步提升。

  • 三阶段微调:三阶段微调就像是新店开业的三个阶段:试营业、正式营业和优化阶段,逐步调整菜单和厨房流程,确保餐厅能够稳定运营并满足顾客需求。

ps:今日的代码训练时长较长,3080ti大概需要40min的训练时长

作业:

  1. 好好理解下resnet18的模型结构
  2. 尝试对vgg16+cbam进行微调策略
  1. 好好理解下 ResNet-18 的模型结构

    • ResNet-18 是一个较浅的 ResNet 模型,包含 18 层。它的结构相对简单,适合初学者理解 ResNet 的基本原理。通过查阅 PyTorch 的官方文档或使用 torchvision 加载 ResNet-18 模型,你可以查看每个层的定义和作用。

ResNet(残差网络)通过引入残差块解决了深层网络的梯度消失问题,使网络可以训练更深。ResNet18 包含 18 层(1 个卷积层 + 17 个卷积层或全连接层),具体结构如下: 


输入层:接收 224×224×3 的图像
初始卷积层:7×7 卷积,64 通道,步长 2,随后 BatchNorm 和 ReLU
4 个残差模块组:
每个模块组包含多个残差块(BasicBlock)
残差块结构为:3×3 卷积 → BatchNorm → ReLU → 3×3 卷积 → BatchNorm → 残差连接 → ReLU
全局平均池化:将特征图压缩为 1×1 特征向量
全连接层:输出分类结果

  1. 尝试对 VGG-16 + CBAM 进行微调策略

    • 在 VGG-16 模型中集成 CBAM 模块。你可以在每个卷积块的后面添加 CBAM 模块,以增强模型的特征提取能力。微调时,可以对 VGG-16 的前面几层设置较低的学习率,对后面几层和 CBAM 模块设置较高的学习率,以保护预训练的特征并提高模型性能。

CBAM(卷积注意力模块)可以增强特征表达能力,将其应用于 VGG16 时,可以放置在每个卷积组之后。以下是针对 VGG16+CBAM 的三阶段微调策略:

 

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import models
from torch.optim.lr_scheduler import StepLR# 定义 CBAM 模块
class ChannelAttention(nn.Module):def __init__(self, in_channels, reduction_ratio=16):super(ChannelAttention, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1)self.max_pool = nn.AdaptiveMaxPool2d(1)self.fc = nn.Sequential(nn.Conv2d(in_channels, in_channels // reduction_ratio, 1, bias=False),nn.ReLU(),nn.Conv2d(in_channels // reduction_ratio, in_channels, 1, bias=False))def forward(self, x):avg_out = self.fc(self.avg_pool(x))max_out = self.fc(self.max_pool(x))out = avg_out + max_outreturn torch.sigmoid(out)class SpatialAttention(nn.Module):def __init__(self, kernel_size=7):super(SpatialAttention, self).__init__()self.conv = nn.Conv2d(2, 1, kernel_size, padding=kernel_size//2, bias=False)def forward(self, x):avg_out = torch.mean(x, dim=1, keepdim=True)max_out, _ = torch.max(x, dim=1, keepdim=True)out = torch.cat([avg_out, max_out], dim=1)out = self.conv(out)return torch.sigmoid(out)class CBAM(nn.Module):def __init__(self, in_channels, reduction_ratio=16, kernel_size=7):super(CBAM, self).__init__()self.channel_att = ChannelAttention(in_channels, reduction_ratio)self.spatial_att = SpatialAttention(kernel_size)def forward(self, x):x = x * self.channel_att(x)x = x * self.spatial_att(x)return x# 修改 VGG16 模型,添加 CBAM
def vgg16_cbam(pretrained=True):model = models.vgg16(pretrained=pretrained)# 在每个 block 后添加 CBAMfeatures = list(model.features)new_features = []# VGG16 的 block 划分点block_end_indices = [4, 9, 16, 23, 30]current_block = 0for i, layer in enumerate(features):new_features.append(layer)if i == block_end_indices[current_block] and current_block < len(block_end_indices) - 1:# 除了最后一个 block,其他都添加 CBAMin_channels = list(filter(lambda x: isinstance(x, nn.Conv2d), features[:i+1]))[-1].out_channelsnew_features.append(CBAM(in_channels))current_block += 1model.features = nn.Sequential(*new_features)return model# 三阶段微调策略
def train_vgg16_cbam():# 阶段 1: 冻结除最后几层外的所有参数model = vgg16_cbam(pretrained=True)# 冻结大部分参数for param in list(model.parameters())[:-20]:param.requires_grad = Falseoptimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=0.001, momentum=0.9)scheduler = StepLR(optimizer, step_size=5, gamma=0.1)# 训练前 10 个 epochfor epoch in range(10):# 训练代码scheduler.step()# 阶段 2: 解冻更多层,使用差异化学习率for param in list(model.parameters())[-40:]:param.requires_grad = True# 为不同层设置不同学习率params = [{'params': list(model.parameters())[:-40], 'lr': 1e-5},{'params': list(model.parameters())[-40:-20], 'lr': 1e-4},{'params': list(model.parameters())[-20:], 'lr': 1e-3}]optimizer = optim.SGD(params, momentum=0.9)scheduler = StepLR(optimizer, step_size=5, gamma=0.1)# 训练 10-20 个 epochfor epoch in range(10, 20):# 训练代码scheduler.step()# 阶段 3: 解冻所有层,使用更低学习率for param in model.parameters():param.requires_grad = Trueoptimizer = optim.SGD(model.parameters(), lr=1e-4, momentum=0.9)scheduler = StepLR(optimizer, step_size=5, gamma=0.1)# 训练 20-30 个 epochfor epoch in range(20, 30):# 训练代码scheduler.step()return model

策略解释
模型修改:在 VGG16 的每个卷积组后添加 CBAM 模块,增强特征表达能力。

三阶段微调:

阶段 1:冻结大部分预训练参数,仅训练最后几层和 CBAM 模块,防止灾难性遗忘。
阶段 2:解冻更多层,使用差异化学习率(底层小学习率,高层大学习率),微调中间层特征。
阶段 3:解冻所有层,使用低学习率全局微调,进一步优化模型。
学习率调整:使用 StepLR 调度器,每 5 个 epoch 降低学习率,有助于模型收敛。

@浙大疏锦行

相关文章:

  • FreeRTOS信号量
  • @Configuration原理与实战
  • ​计算机网络原理超详解说​
  • Web后端基础:Maven基础
  • Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:智驿AI系统(前后端源码 + 数据库 sql 脚本)
  • P4 QT项目----串口助手(4.2)
  • 2025 高考:AI 都在哪些地方发挥了作用
  • crackme007
  • 电脑一段时间没用就变成登陆的界面
  • CppCon 2015 学习:Implementing class properties effectively
  • RocketMQ延迟消息机制
  • 【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
  • 第5章 类的基本概念 笔记
  • 不变性(Immutability)模式
  • b2b企业网络营销如何用deepseek、豆包等AI平台获客 上海添力
  • switch选择语句
  • 打造多模态交互新范式|彩讯股份中标2025年中国移动和留言平台AI智能体研发项目
  • Linux内核 -- INIT_WORK 使用与注意事项
  • Win系统下的Linux系统——WSL 使用手册
  • 如何根据excel表生成sql的insert脚本
  • 四川网站建设设计公司/互联网平台推广是什么意思
  • 网站建设的一般流程/关键词优化排名的步骤
  • 宁波宇丰建设有限公司网站/aso优化平台有哪些
  • 微信文章转wordpress/太原seo优化公司
  • 政府网站建设合同.doc/企业培训公司
  • 海外营销网站设计/国家市场监管总局