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

打卡day54

作业:
1.对inception网络在cifar10上观察精度
2.消融实验:引入残差机制和cbam模块分别进行消融

import os
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torch.utils.checkpoint import checkpoint
from tqdm import tqdm
import matplotlib.pyplot as plt# 显存优化设置(必须放在所有torch导入之前)
os.environ['PYTORCH_CUDA_ALLOC_CONF'] = 'expandable_segments:True'# 设备配置
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# --------------------------
# 1. 数据准备(CIFAR-10)
# --------------------------
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])transform_test = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])# 减小batch_size以适应显存
train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=2)test_dataset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
test_loader = DataLoader(test_dataset, batch_size=50, shuffle=False, num_workers=2)# --------------------------
# 2. 模型定义(显存优化版)
# --------------------------
class CBAM(nn.Module):"""轻量级CBAM模块(通道和空间注意力)"""def __init__(self, channels, reduction_ratio=8):super(CBAM, self).__init__()self.channel_attention = nn.Sequential(nn.AdaptiveAvgPool2d(1),nn.Conv2d(channels, channels // reduction_ratio, kernel_size=1),nn.ReLU(),nn.Conv2d(channels // reduction_ratio, channels, kernel_size=1),nn.Sigmoid())self.spatial_attention = nn.Sequential(nn.Conv2d(2, 1, kernel_size=7, padding=3),nn.Sigmoid())def forward(self, x):# 通道注意力channel = self.channel_attention(x) * x# 空间注意力spatial_avg = torch.mean(channel, dim=1, keepdim=True)spatial_max, _ = torch.max(channel, dim=1, keepdim=True)spatial = torch.cat([spatial_avg, spatial_max], dim=1)spatial = self.spatial_attention(spatial) * channelreturn spatialclass InceptionModule(nn.Module):"""优化后的Inception模块(通道数减半)"""def __init__(self, in_channels, use_residual=False, use_cbam=False):super(InceptionModule, self).__init__()self.use_residual = use_residualself.use_cbam = use_cbam# 分支1:1x1卷积self.branch1 = nn.Sequential(nn.Conv2d(in_channels, 16, kernel_size=1),nn.BatchNorm2d(16),nn.ReLU())# 分支2:1x1 -> 3x3self.branch2 = nn.Sequential(nn.Conv2d(in_channels, 16, kernel_size=1),nn.BatchNorm2d(16),nn.ReLU(),nn.Conv2d(16, 24, kernel_size=3, padding=1),nn.BatchNorm2d(24),nn.ReLU())# 分支3:1x1 -> 5x5self.branch3 = nn.Sequential(nn.Conv2d(in_channels, 16, kernel_size=1),nn.BatchNorm2d(16),nn.ReLU(),nn.Conv2d(16, 24, kernel_size=5, padding=2),nn.BatchNorm2d(24),nn.ReLU())# 分支4:3x3池化 -> 1x1self.branch4 = nn.Sequential(nn.MaxPool2d(kernel_size=3, stride=1, padding=1),nn.Conv2d(in_channels, 16, kernel_size=1),nn.BatchNorm2d(16),nn.ReLU())# CBAM模块(如果启用)if use_cbam:self.cbam = CBAM(16 + 24 + 24 + 16)# 残差连接(如果启用)if use_residual:self.residual = nn.Sequential(nn.Conv2d(in_channels, 16 + 24 + 24 + 16, kernel_size=1),nn.BatchNorm2d(16 + 24 + 24 + 16))def forward(self, x):residual = x# 并行分支b1 = self.branch1(x)b2 = self.branch2(x)b3 = self.branch3(x)b4 = self.branch4(x)# 合并分支out = torch.cat([b1, b2, b3, b4], dim=1)# 应用CBAMif self.use_cbam:out = self.cbam(out)# 残差连接if self.use_residual:residual = self.residual(residual)out += residualreturn outclass InceptionNet(nn.Module):"""完整的轻量化Inception网络"""def __init__(self, num_classes=10, use_residual=False, use_cbam=False):super(InceptionNet, self).__init__()# 初始层(通道数减半)self.stem = nn.Sequential(nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(32),nn.ReLU())# Inception模块堆叠self.inception1 = InceptionModule(32, use_residual, use_cbam)self.inception2 = InceptionModule(16+24+24+16, use_residual, use_cbam)self.inception3 = InceptionModule(16+24+24+16, use_residual, use_cbam)# 分类头self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(16+24+24+16, num_classes)def forward(self, x):x = self.stem(x)x = self.inception1(x)x = self.inception2(x)x = self.inception3(x)x = self.avgpool(x)x = torch.flatten(x, 1)x = self.fc(x)return x# --------------------------
# 3. 训练与评估函数(含混合精度)
# --------------------------
def train_model(model, train_loader, criterion, optimizer, epoch):model.train()running_loss = 0.0correct = 0total = 0# 混合精度训练scaler = torch.cuda.amp.GradScaler()for inputs, labels in tqdm(train_loader, desc=f'Train Epoch {epoch}'):inputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()with torch.cuda.amp.autocast():outputs = model(inputs)loss = criterion(outputs, labels)scaler.scale(loss).backward()scaler.step(optimizer)scaler.update()running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()train_loss = running_loss / len(train_loader)train_acc = 100. * correct / totalreturn train_loss, train_accdef evaluate_model(model, test_loader, criterion):model.eval()running_loss = 0.0correct = 0total = 0with torch.no_grad():for inputs, labels in tqdm(test_loader, desc='Evaluating'):inputs, labels = inputs.to(device), labels.to(device)outputs = model(inputs)loss = criterion(outputs, labels)running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()test_loss = running_loss / len(test_loader)test_acc = 100. * correct / totalreturn test_loss, test_acc# --------------------------
# 4. 消融实验主流程
# --------------------------
def run_ablation(use_residual=False, use_cbam=False):print(f"\nRunning experiment: Residual={use_residual}, CBAM={use_cbam}")# 初始化模型model = InceptionNet(use_residual=use_residual, use_cbam=use_cbam).to(device)# 损失函数和优化器criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)# 训练记录train_losses, train_accs = [], []test_losses, test_accs = [], []# 训练循环(epochs减少以节省时间)for epoch in range(15):train_loss, train_acc = train_model(model, train_loader, criterion, optimizer, epoch)test_loss, test_acc = evaluate_model(model, test_loader, criterion)scheduler.step()train_losses.append(train_loss)train_accs.append(train_acc)test_losses.append(test_loss)test_accs.append(test_acc)print(f'Epoch {epoch}: Train Loss: {train_loss:.4f}, Acc: {train_acc:.2f}% | 'f'Test Loss: {test_loss:.4f}, Acc: {test_acc:.2f}%')# 保存结果torch.save(model.state_dict(), f'best_model_res{use_residual}_cbam{use_cbam}.pth')# 绘制曲线plt.figure()plt.plot(train_accs, label='Train Acc')plt.plot(test_accs, label='Test Acc')plt.title(f'Accuracy (Residual={use_residual}, CBAM={use_cbam})')plt.legend()plt.savefig(f'result_res{use_residual}_cbam{use_cbam}.png')plt.close()# --------------------------
# 5. 执行所有消融实验
# --------------------------
if __name__ == '__main__':# 基础模型(无残差无CBAM)run_ablation(use_residual=False, use_cbam=False)# 仅残差run_ablation(use_residual=True, use_cbam=False)# 仅CBAMrun_ablation(use_residual=False, use_cbam=True)# 残差+CBAMrun_ablation(use_residual=True, use_cbam=True)
http://www.xdnf.cn/news/14622.html

相关文章:

  • AC-MT
  • C语言常用库函数
  • LangChain面试内容整理-知识点14:工具包(Toolkits)与用法
  • 生成对抗网络(GANs)入门介绍指南:让AI学会“创造“的魔法(二)【深入版】
  • Textacy:Python 中的文本数据清理和规范化简介
  • 自我实现的量子隐喻:在可能性场域中动态拓展涌现节点
  • LLMs:《WebDancer: Towards Autonomous Information Seeking Agency》翻译与解读
  • 02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序
  • Sa-Token全面深入学习指南
  • 【慧游鲁博】【15】后台管理系统功能完善:仪表盘、多模态交互日志、简单问答词条管理
  • 建造者模式Builder Pattern
  • 深度解析5W2H:高效思维与问题解决工具详解
  • 离散隐藏变量下期望最大化(EM)算法的简化
  • LeetCode 第77题:组合
  • SimpleQtLogger 使用总结
  • 深入理解滑动窗口算法:原理、应用与 C++ 实现
  • C# 事件详解
  • React组件通信——发布订阅(pub/sub)
  • 紧急救援!Ubuntu崩溃修复大赛
  • 在Qt中使用OpenGL显示大量点(点云)
  • 136. 只出现一次的数字
  • 算法题(力扣每日一题)—改变一个整数能得到的最大差值
  • Arthas 全面学习指南
  • 动手实践:LangChain流图可视化全解析
  • [从0到1]环境准备--anaconda与pycharm的安装
  • Linux系统firewall-offline-cmd命令在企业网络安全防护中的应用案例分析
  • 图形编辑器基于Paper.js教程29:基于图层的所有矢量图元的填充规则实现
  • 【C++】list容器实现
  • Lighthouse与首屏优化
  • 【看到哪里写到哪里】如何在C中使用多进程设计(1)