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

Python训练营打卡Day45

知识点回顾:

  1. tensorboard的发展历史和原理
  2. tensorboard的常见操作
  3. tensorboard在cifar上的实战:MLP和CNN模型

效果展示如下,很适合拿去组会汇报撑页数:

作业:对resnet18在cifar10上采用微调策略下,用tensorboard监控训练过程。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision import datasets, transforms
from torchvision.models import resnet18
from torch.utils.tensorboard import SummaryWriter
import time
import os# 设置随机种子确保结果可复现
torch.manual_seed(42)# 数据预处理
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)),
])# 加载CIFAR-10数据集
trainset = datasets.CIFAR10(root='./data', train=True,download=True, transform=transform_train)
trainloader = DataLoader(trainset, batch_size=128,shuffle=True, num_workers=2)testset = datasets.CIFAR10(root='./data', train=False,download=True, transform=transform_test)
testloader = DataLoader(testset, batch_size=100,shuffle=False, num_workers=2)# 定义类别名称
classes = ('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')# 加载预训练的ResNet18模型
model = resnet18(pretrained=True)# 修改模型以适应CIFAR-10
# 调整输入层以适应32x32的图像
model.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
# 修改最后一层以适应10个类别
model.fc = nn.Linear(model.fc.in_features, 10)# 微调策略:冻结部分层
for param in list(model.parameters())[:-10]:  # 解冻最后10层param.requires_grad = False# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), lr=0.001, momentum=0.9, weight_decay=5e-4)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=200)# 设置TensorBoard写入器
timestamp = time.strftime('%Y%m%d_%H%M%S')
log_dir = os.path.join('runs', f'resnet18_cifar10_finetune_{timestamp}')
writer = SummaryWriter(log_dir)# 训练函数
def train(epoch):model.train()train_loss = 0correct = 0total = 0for batch_idx, (inputs, targets) in enumerate(trainloader):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)total += targets.size(0)correct += predicted.eq(targets).sum().item()# 每100个batch记录一次训练状态if (batch_idx+1) % 100 == 0:step = epoch * len(trainloader) + batch_idxwriter.add_scalar('Train/Loss', loss.item(), step)writer.add_scalar('Train/Accuracy', 100.*correct/total, step)print(f'Epoch: {epoch} | Batch: {batch_idx+1}/{len(trainloader)} | Loss: {loss.item():.3f} | Acc: {100.*correct/total:.3f}%')# 记录每个epoch的平均训练损失和准确率avg_loss = train_loss / len(trainloader)avg_acc = 100. * correct / totalwriter.add_scalar('Epoch/Train_Loss', avg_loss, epoch)writer.add_scalar('Epoch/Train_Accuracy', avg_acc, epoch)return avg_loss, avg_acc# 测试函数
def test(epoch):model.eval()test_loss = 0correct = 0total = 0with torch.no_grad():for batch_idx, (inputs, targets) in enumerate(testloader):inputs, targets = inputs.to(device), targets.to(device)outputs = model(inputs)loss = criterion(outputs, targets)test_loss += loss.item()_, predicted = outputs.max(1)total += targets.size(0)correct += predicted.eq(targets).sum().item()# 记录测试损失和准确率avg_loss = test_loss / len(testloader)avg_acc = 100. * correct / totalwriter.add_scalar('Epoch/Test_Loss', avg_loss, epoch)writer.add_scalar('Epoch/Test_Accuracy', avg_acc, epoch)# 记录学习率writer.add_scalar('Epoch/Learning_Rate', optimizer.param_groups[0]['lr'], epoch)print(f'Test Epoch: {epoch} | Loss: {avg_loss:.3f} | Acc: {avg_acc:.3f}%')# 保存最佳模型global best_accif avg_acc > best_acc:print('Saving best model...')state = {'model': model.state_dict(),'acc': avg_acc,'epoch': epoch,}if not os.path.isdir('checkpoint'):os.mkdir('checkpoint')torch.save(state, './checkpoint/ckpt.pth')best_acc = avg_acc# 记录错误分类的图像if epoch % 10 == 0:  # 每10个epoch记录一次misclassified = []with torch.no_grad():for inputs, targets in testloader:inputs, targets = inputs.to(device), targets.to(device)outputs = model(inputs)_, predicted = outputs.max(1)mis_indices = (predicted != targets).nonzero(as_tuple=True)[0]for idx in mis_indices:if len(misclassified) < 10:  # 只记录10张错误分类的图像misclassified.append({'image': inputs[idx],'predicted': predicted[idx].item(),'actual': targets[idx].item()})if misclassified:for i, item in enumerate(misclassified):img = item['image'].cpu()writer.add_image(f'Misclassified/{classes[item["actual"]]}_as_{classes[item["predicted"]]}',img, epoch)return avg_loss, avg_acc# 可视化模型结构
def visualize_model():sample_input = torch.rand(1, 3, 32, 32).to(device)writer.add_graph(model, sample_input)# 可视化样本数据
def visualize_samples():# 获取一个批次的训练数据images, labels = next(iter(trainloader))# 创建图像网格img_grid = torchvision.utils.make_grid(images)# 添加图像网格到TensorBoardwriter.add_image('CIFAR10_Samples', img_grid)# 添加标签到TensorBoardclass_labels = [classes[i] for i in labels]writer.add_embedding(images.view(images.size(0), -1),metadata=class_labels,label_img=images,global_step=0)# 可视化特征图
def visualize_feature_maps(inputs, epoch):model.eval()# 获取第一层卷积的特征图first_conv = model.conv1feature_maps = first_conv(inputs.to(device))# 创建特征图网格grid = torchvision.utils.make_grid(feature_maps[:8].unsqueeze(1),  # 只显示前8个特征图nrow=4, normalize=True, scale_each=True)writer.add_image('FeatureMaps/Conv1', grid, epoch)# 主训练循环
if __name__ == '__main__':device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')model.to(device)best_acc = 0start_epoch = 0# 可视化模型和样本visualize_model()visualize_samples()# 训练模型total_epochs = 50for epoch in range(start_epoch, total_epochs):print(f'Epoch {epoch}/{total_epochs-1}')print('-' * 10)train_loss, train_acc = train(epoch)test_loss, test_acc = test(epoch)# 学习率调度scheduler.step()# 可视化训练过程中的特征图if epoch % 5 == 0:  # 每5个epoch可视化一次inputs, _ = next(iter(testloader))visualize_feature_maps(inputs[:1], epoch)# 记录训练过程中的权重和梯度直方图if epoch % 10 == 0:  # 每10个epoch记录一次for name, param in model.named_parameters():if param.requires_grad:writer.add_histogram(f'Params/{name}', param, epoch)if param.grad is not None:writer.add_histogram(f'Grads/{name}', param.grad, epoch)print()# 关闭TensorBoard写入器writer.close()print('Training completed!')print(f'Best accuracy: {best_acc:.2f}%')    

  1. tensorboard和torch版本存在一定的不兼容性,如果报错请新建环境尝试。启动tensorboard的时候需要先在cmd中进入对应的环境,conda activate xxx,再用cd命令进入环境(如果本来就是正确的则无需操作)。
  2. tensorboard的代码还有有一定的记忆量,实际上深度学习的经典代码都是类似于八股文,看多了就习惯了,难度远远小于考研数学等需要思考的内容
  3. 实际上对目前的ai而言,你只需要先完成最简单的demo,然后让他给你加上tensorboard需要打印的部分即可。---核心是弄懂tensorboard可以打印什么信息,以及如何看可视化后的结果,把ai当成记忆大师用到的时候通过它来调取对应的代码即可。

@浙大疏锦行

http://www.lryc.cn/news/2404413.html

相关文章:

  • Xilinx FPGA 重构Multiboot ICAPE2和ICAPE3使用
  • Redis专题-基础篇
  • springMVC-11 中文乱码处理
  • 【iOS安全】iPhone X iOS 16.7.11 (20H360) WinRa1n 越狱教程
  • MongoDB检查慢查询db.system.profile.find 分析各参数的作用
  • 智能标志桩图像监测装置如何守护地下电缆安全
  • 【网站建设】网站 SEO 中 meta 信息修改全攻略 ✅
  • 计算机视觉处理----OpenCV(从摄像头采集视频、视频处理与视频录制)
  • elasticsearch基本操作笔记
  • LVGL手势识别事件无上报问题处理记录
  • 《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- 第一篇:MIPI CSI-2基础入门
  • 变幻莫测:CoreData 中 Transformable 类型面面俱到(一)
  • 开源技术驱动下的上市公司财务主数据管理实践
  • 婚恋小程序直播系统框架搭建
  • day46 python预训练模型补充
  • CCPC chongqing 2025 H
  • Java建造者模式(Builder Pattern)详解与实践
  • ant-design4.xx实现数字输入框; 某些输入法数字需要连续输入两次才显示
  • 使用ORM Bee (ormbee) ,如何利用SQLAlchemy的模型生成数据库表.
  • 【win | 自动更新关闭】win11
  • win32相关(IAT HOOK)
  • 大模型高效提示词Prompt编写指南
  • 零基础玩转物联网-串口转以太网模块如何快速实现与TCP服务器通信
  • 十一、【ESP32开发全栈指南: TCP通信服务端】
  • ESP32开发之LED闪烁和呼吸的实现
  • 【产品业务设计】支付业务设计规范细节记录,含订单记录、支付业务记录、支付流水记录、退款业务记录
  • 2025软件供应链安全最佳实践︱证券DevSecOps下供应链与开源治理实践
  • Linux安装jdk、tomcat
  • WebRTC通话原理与入门难度实战指南
  • N元语言模型 —— 一文讲懂!!!