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

python学习打卡day35

DAY 35 模型可视化与推理

外出几天,所以提前更新几日作业,对应5.24作业

知识点回顾:

  1. 三种不同的模型可视化方法:推荐torchinfo打印summary+权重分布可视化
  2. 进度条功能:手动和自动写法,让打印结果更加美观
  3. 推理的写法:评估模式

作业:调整模型定义时的超参数,对比下效果。

1.三种不同的模型可视化方法:推荐torchinfo打印summary+权重分布可视化

1.1 nn.model自带方法

#  nn.Module 的内置功能,直接输出模型结构
print(model)

MLP是nn.model中自带的模型,因此可以直接打印-------不推荐

nn.Module 的内置功能,返回模型的可训练参数迭代器 

# nn.Module 的内置功能,返回模型的可训练参数迭代器
for name, param in model.named_parameters():print(f"Parameter name: {name}, Shape: {param.shape}")

相较第一种清晰了很多 

1.2 torchsummary库的summary方法

from torchsummary import summary
# 打印模型摘要,可以放置在模型定义后面
summary(model, input_size=(4,))

 1.3 torchinfo库的summary方法

from torchinfo import summary
summary(model, input_size=(4, ))

 

torchifo库和torchsummary库的使用方法一致,但结果更清晰,因此更推荐 

可视化权重分配:

# 提取权重数据
import numpy as np
weight_data = {}
for name, param in model.named_parameters():if 'weight' in name:weight_data[name] = param.detach().cpu().numpy()# 可视化权重分布
fig, axes = plt.subplots(1, len(weight_data), figsize=(15, 5))
fig.suptitle('Weight Distribution of Layers')for i, (name, weights) in enumerate(weight_data.items()):# 展平权重张量为一维数组weights_flat = weights.flatten()# 绘制直方图axes[i].hist(weights_flat, bins=50, alpha=0.7)axes[i].set_title(name)axes[i].set_xlabel('Weight Value')axes[i].set_ylabel('Frequency')axes[i].grid(True, linestyle='--', alpha=0.7)plt.tight_layout()
plt.subplots_adjust(top=0.85)
plt.show()# 计算并打印每层权重的统计信息
print("\n=== 权重统计信息 ===")
for name, weights in weight_data.items():mean = np.mean(weights)std = np.std(weights)min_val = np.min(weights)max_val = np.max(weights)print(f"{name}:")print(f"  均值: {mean:.6f}")print(f"  标准差: {std:.6f}")print(f"  最小值: {min_val:.6f}")print(f"  最大值: {max_val:.6f}")print("-" * 30)

所以torchinfo打印summary+权重分布可视化是比较好的选择

2.进度条功能:手动和自动写法,让打印结果更加美观

2.1手动写法

from tqdm import tqdm  # 先导入tqdm库
import time  # 用于模拟耗时操作# 创建一个总步数为10的进度条
with tqdm(total=10) as pbar:  # pbar是进度条对象的变量名# pbar 是 progress bar(进度条)的缩写,约定俗成的命名习惯。for i in range(10):  # 循环10次(对应进度条的10步)time.sleep(0.5)  # 模拟每次循环耗时0.5秒pbar.update(1)  # 每次循环后,进度条前进1步

可以在进度条中加入文字:

desc参数是在进度条最前方加中文字符

unit 参数的核心作用是明确进度条中每个进度单位的含义,使可视化信息更具可读性。在深度学习训练中,常用的单位包括:

- epoch:训练轮次(遍历整个数据集一次)。

- batch:批次(每次梯度更新处理的样本组)。

- sample:样本(单个数据点)

from tqdm import tqdm
import time# 创建进度条时添加描述(desc)和单位(unit)
with tqdm(total=5, desc="下载文件", unit="个") as pbar:# 进度条这个对象,可以设置描述和单位# desc是描述,在左侧显示# unit是单位,在进度条右侧显示for i in range(5):time.sleep(1)pbar.update(1)  # 每次循环进度+1

# 训练模型
num_epochs = 20000  # 训练的轮数# 用于存储每100个epoch的损失值和对应的epoch数
losses = []
epochs = []start_time = time.time()  # 记录开始时间# 创建tqdm进度条
with tqdm(total=num_epochs, desc="训练进度", unit="epoch") as pbar:# 训练模型for epoch in range(num_epochs):# 前向传播outputs = model(X_train)  # 隐式调用forward函数loss = criterion(outputs, y_train)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()# 记录损失值并更新进度条if (epoch + 1) % 200 == 0:losses.append(loss.item())epochs.append(epoch + 1)# 更新进度条的描述信息pbar.set_postfix({'Loss': f'{loss.item():.4f}'})# 每1000个epoch更新一次进度条if (epoch + 1) % 1000 == 0:pbar.update(1000)  # 更新进度条# 确保进度条达到100%if pbar.n < num_epochs:pbar.update(num_epochs - pbar.n)  # 计算剩余的进度并更新time_all = time.time() - start_time  # 计算训练时间
print(f'Training time: {time_all:.2f} seconds')

 

2.2自动更新 

from tqdm import tqdm
import time# 直接将range(3)传给tqdm,自动生成进度条
# 这个写法我觉得是有点神奇的,直接可以给这个对象内部传入一个可迭代对象,然后自动生成进度条
for i in tqdm(range(3), desc="处理任务", unit="epoch"):time.sleep(1)

for i in tqdm(range(3), desc="处理任务", unit="个")这个写法则不需要在循环中调用update()方法,更加简洁

3模型推理:

# 在测试集上评估模型,此时model内部已经是训练好的参数了
# 评估模型
model.eval() # 设置模型为评估模式
with torch.no_grad(): # torch.no_grad()的作用是禁用梯度计算,可以提高模型推理速度outputs = model(X_test)  # 对测试数据进行前向传播,获得预测结果_, predicted = torch.max(outputs, 1) # torch.max(outputs, 1)返回每行的最大值和对应的索引#这个函数返回2个值,分别是最大值和对应索引,参数1是在第1维度(行)上找最大值,_ 是Python的约定,表示忽略这个返回值,所以这个写法是找到每一行最大值的下标# 此时outputs是一个tensor,p每一行是一个样本,每一行有3个值,分别是属于3个类别的概率,取最大值的下标就是预测的类别# predicted == y_test判断预测值和真实值是否相等,返回一个tensor,1表示相等,0表示不等,然后求和,再除以y_test.size(0)得到准确率# 因为这个时候数据是tensor,所以需要用item()方法将tensor转化为Python的标量# 之所以不用sklearn的accuracy_score函数,是因为这个函数是在CPU上运行的,需要将数据转移到CPU上,这样会慢一些# size(0)获取第0维的长度,即样本数量correct = (predicted == y_test).sum().item() # 计算预测正确的样本数accuracy = correct / y_test.size(0)print(f'测试集准确率: {accuracy * 100:.2f}%')

测试集准确率: 96.67%

作业:

超参数调整

1.只调整隐藏层参数

    def __init__(self):super(MLP, self).__init__()self.fc1 = nn.Linear(4, 20)  # 输入层到隐藏层self.relu = nn.ReLU()self.fc2 = nn.Linear(20, 3)  # 隐藏层到输出层

损失并没有下降 

2.调整优化器


optimizer = optim.Adam(model.parameters(), lr=0.001)

3.优化器+隐藏层

 @浙大疏精行

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

相关文章:

  • 操作系统与底层安全
  • 跨链风云:打破区块链孤岛,实现价值自由流转
  • SDC命令详解:使用set_logic_dc命令进行约束
  • 【软考向】Chapter 2 程序设计语言基础知识
  • Vanna.AI:解锁连表查询的新境界
  • uni-app学习笔记十--vu3综合练习
  • 前端实战:用 JavaScript 模拟文件选择器,同步实现图片预览与 Base64 转换
  • Python序列化与反序列化
  • 人工智能在医疗影像诊断上的最新成果:更精准地识别疾病
  • python:机器学习概述
  • csp备考Day1|string和vector
  • BSDIFF算法详解
  • 2025陕西ICPC邀请赛题解(部分)
  • JVM学习(五)--执行引擎
  • 内容中台的数字化管理核心是什么?
  • 使用Spring Boot和Redis实现高效缓存机制
  • 网络安全给数据工厂带来的挑战
  • 25年软考架构师真题(回忆更新中)
  • 深度学习——超参数调优
  • 前端框架token相关bug,前后端本地联调
  • SGlang 推理模型优化(PD架构分离)
  • 从脑电图和大脑记录中学习稳健的深度视觉表征
  • 【HarmonyOS Next之旅】DevEco Studio使用指南(二十六) -> 创建端云一体化开发工程
  • 廉价却有效?ESD防护中的电容
  • 微前端架构:从单体到模块化的前端新革命
  • 【MySQL系列】 MySQL 中的 TINYINT 类型
  • C/C++STL---<chrono>
  • [SWPUCTF 2021 新生赛]简简单单的解密
  • CDGA|一线二线企业数据治理项目目前发展状况
  • 运维实施36-逻辑卷管理 (LVM)