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

Python训练营打卡Day49

  1. 通道注意力模块复习
  2. 空间注意力模块
  3. CBAM的定义

作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.tensorboard import SummaryWriter
import torchvision.models as models
from torchsummary import summary
import numpy as np
import os# 通道注意力模块
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))self.sigmoid = nn.Sigmoid()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 self.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)self.sigmoid = nn.Sigmoid()def forward(self, x):avg_out = torch.mean(x, dim=1, keepdim=True)max_out, _ = torch.max(x, dim=1, keepdim=True)x_cat = torch.cat([avg_out, max_out], dim=1)out = self.conv(x_cat)return self.sigmoid(out)# CBAM模块
class CBAM(nn.Module):def __init__(self, in_channels, reduction_ratio=16, kernel_size=7):super(CBAM, self).__init__()self.channel_attention = ChannelAttention(in_channels, reduction_ratio)self.spatial_attention = SpatialAttention(kernel_size)def forward(self, x):x = x * self.channel_attention(x)x = x * self.spatial_attention(x)return x# 带CBAM的ResNet模块
class ResidualBlockWithCBAM(nn.Module):def __init__(self, in_channels, out_channels, stride=1, reduction_ratio=16):super(ResidualBlockWithCBAM, self).__init__()self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)self.bn1 = nn.BatchNorm2d(out_channels)self.relu = nn.ReLU(inplace=True)self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(out_channels)self.cbam = CBAM(out_channels, reduction_ratio)self.shortcut = nn.Sequential()if stride != 1 or in_channels != out_channels:self.shortcut = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(out_channels))def forward(self, x):residual = xout = self.relu(self.bn1(self.conv1(x)))out = self.bn2(self.conv2(out))# 应用CBAMout = self.cbam(out)out += self.shortcut(residual)out = self.relu(out)return out# 简化版ResNet18+CBAM模型
class ResNet18WithCBAM(nn.Module):def __init__(self, num_classes=1000, reduction_ratio=16):super(ResNet18WithCBAM, self).__init__()self.in_channels = 64self.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)# 残差块self.layer1 = self._make_layer(64, 2, stride=1, reduction_ratio=reduction_ratio)self.layer2 = self._make_layer(128, 2, stride=2, reduction_ratio=reduction_ratio)self.layer3 = self._make_layer(256, 2, stride=2, reduction_ratio=reduction_ratio)self.layer4 = self._make_layer(512, 2, stride=2, reduction_ratio=reduction_ratio)self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(512, num_classes)def _make_layer(self, out_channels, num_blocks, stride, reduction_ratio):strides = [stride] + [1] * (num_blocks - 1)layers = []for stride in strides:layers.append(ResidualBlockWithCBAM(self.in_channels, out_channels, stride, reduction_ratio))self.in_channels = out_channelsreturn nn.Sequential(*layers)def forward(self, x):out = self.relu(self.bn1(self.conv1(x)))out = self.maxpool(out)out = self.layer1(out)out = self.layer2(out)out = self.layer3(out)out = self.layer4(out)out = self.avgpool(out)out = torch.flatten(out, 1)out = self.fc(out)return out# 计算模型参数数量
def count_parameters(model):return sum(p.numel() for p in model.parameters() if p.requires_grad)# 训练函数
def train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=10, device='cuda'):# 创建TensorBoard记录器writer = SummaryWriter('runs/cbam_experiment')model.to(device)# 添加模型图到TensorBoardfor images, _ in train_loader:images = images.to(device)writer.add_graph(model, images)breakbest_val_acc = 0.0for epoch in range(num_epochs):# 训练阶段model.train()train_loss = 0.0train_correct = 0train_total = 0for batch_idx, (inputs, targets) in enumerate(train_loader):inputs, targets = inputs.to(device), targets.to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, targets)loss.backward()optimizer.step()train_loss += loss.item()_, predicted = outputs.max(1)train_total += targets.size(0)train_correct += predicted.eq(targets).sum().item()# 每100个batch记录一次损失if (batch_idx + 1) % 100 == 0:writer.add_scalar('Training Loss', train_loss / 100, epoch * len(train_loader) + batch_idx)train_loss = 0.0# 验证阶段model.eval()val_loss = 0.0val_correct = 0val_total = 0with torch.no_grad():for inputs, targets in val_loader:inputs, targets = inputs.to(device), targets.to(device)outputs = model(inputs)loss = criterion(outputs, targets)val_loss += loss.item()_, predicted = outputs.max(1)val_total += targets.size(0)val_correct += predicted.eq(targets).sum().item()# 计算准确率train_acc = 100.0 * train_correct / train_totalval_acc = 100.0 * val_correct / val_total# 记录准确率到TensorBoardwriter.add_scalar('Training Accuracy', train_acc, epoch)writer.add_scalar('Validation Accuracy', val_acc, epoch)# 记录学习率writer.add_scalar('Learning Rate', optimizer.param_groups[0]['lr'], epoch)# 保存最佳模型if val_acc > best_val_acc:best_val_acc = val_acctorch.save(model.state_dict(), 'best_cbam_model.pth')print(f'Epoch: {epoch+1}/{num_epochs}, Train Acc: {train_acc:.2f}%, Val Acc: {val_acc:.2f}%')writer.close()return model# 示例:如何使用上述代码
def main():# 创建模型model_with_cbam = ResNet18WithCBAM(num_classes=10, reduction_ratio=16)model_vanilla = models.resnet18(pretrained=False)model_vanilla.fc = nn.Linear(512, 10)  # 修改最后一层以匹配类别数# 计算参数数量params_with_cbam = count_parameters(model_with_cbam)params_vanilla = count_parameters(model_vanilla)print(f"ResNet18 with CBAM parameters: {params_with_cbam:,}")print(f"Vanilla ResNet18 parameters: {params_vanilla:,}")print(f"Parameter increase: {((params_with_cbam - params_vanilla) / params_vanilla) * 100:.2f}%")# 这里应该有数据加载代码,为了简化,我们只展示训练函数的调用# train_loader, val_loader = load_data()# 定义损失函数和优化器# criterion = nn.CrossEntropyLoss()# optimizer = torch.optim.SGD(model_with_cbam.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4)# 训练模型# trained_model = train_model(model_with_cbam, train_loader, val_loader, criterion, optimizer, num_epochs=5)if __name__ == "__main__":main()

@浙大疏锦行

http://www.xdnf.cn/news/13668.html

相关文章:

  • 在QtCreator中使用GitHubCopilot
  • UML和模式应用(软件分析设计与建模期末复习)
  • 华为:eSight网管平台使用snmp纳管交换机
  • 利用Snowflake与SNP Glue揭示数据集成新潜力
  • Ozon欧亚仓网战略解析与中国卖家机遇
  • GUI丝滑教程-python tinker
  • Middleware
  • 力扣HOT100之技巧:287. 寻找重复数
  • 安装配置以太链钱包工具
  • 好用的培训教务管理系统哪个用的最多?
  • 68元开启智能硬件新纪元——明远智睿SSD2351开发板引领创新浪潮
  • java_api路径_@Parameter与@RequestParam区别
  • 【hadoop】疫情离线分析案例
  • 关于使用EasyExcel、 Vue3实现导入导出功能
  • 系统功耗管理
  • 25年春招:米哈游运维开发一面总结
  • Java反射机制深度解析与实战应用
  • C# net8生成excel,并设置列规则导出文件
  • 【Linux】Linux基础I/O
  • 织梦dedecms内容页调用seotitle标题的写法
  • Python训练营---DAY52
  • day01 ——Java基础入门
  • 135. Candy
  • C# 界面检测显示器移除并在可用显示器上显示
  • 关键领域软件测试新范式:如何在安全合规前提下提升效率?
  • 14.FTP传输分析
  • 云安全【阿里云ECS攻防】
  • 解决office各种疑难杂症
  • HarmonyOS运动开发:深度解析文件预览的正确姿势
  • win11系统部署tomcat10教程