DAY 38 模型可视化与推理

一、模型结构可视化

1.nn.model自带的方法

这些是 PyTorch 原生支持的方法,无需额外安装依赖,核心用于打印 / 遍历模型层级、参数等信息。

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

将模型中带有weight的参数(即权重)提取出来,并转为 numpy 数组形式,对其计算统计分布,并且绘制可视化图表。

python 复制代码
# 提取权重数据
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)

2.torchsummary库的summary方法

torchsummary 是早期常用的 PyTorch 模型结构可视化工具,核心通过 summary 方法打印模型的层结构、输出形状、参数数量等信息。

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

核心限制:

  • 仅支持单输入张量,多输入模型会报错;
  • 对嵌套过深的自定义 nn.Module 兼容性差;
  • 仅支持 CPU/CUDA 设备;
  • 无法显示参数占比、训练 / 非训练参数区分等细节。

|------------|------------|-----------------------------------------------------|
| 参数 | 类型 | 模型 |
| model | nn.Module | 待可视化的模型实例(需已初始化) |
| input_size | tuple/list | 输入张量的形状(不含 batch_size),如 (3, 32, 32)(3 通道 32x32 图片) |
| batch_size | int | 批次大小,默认 -1(不显示 batch 维度),指定后输出形状会包含 batch_size |
| device | str | 模型运行设备,可选 "cuda"/"cpu",默认 "cuda"(无 GPU 自动切 CPU) |

该方法不显示输入层的尺寸,因为输入的神经网是自己设置的,所以不需要显示输入层的尺寸。

但是在使用该方法时,input_size=(4,) 参数是必需的,因为 PyTorch 需要知道输入数据的形状才能推断模型各层的输出形状和参数数量。

这是因为PyTorch的模型在定义时是动态的,它不会预先知道输入数据的具体形状。nn.Linear(4, 10) 只定义了 "输入维度是 4,输出维度是 10",但不知道输入的批量大小和其他维度,比如卷积层需要知道输入的通道数、高度、宽度等信息。----并非所有输入数据都是结构化数据

因此,要生成模型摘要(如每层的输出形状、参数数量),必须提供一个示例输入形状,让 PyTorch "运行" 一次模型,从而推断出各层的信息。

summary 函数的核心逻辑是:

  1. 创建一个与 input_size 形状匹配的虚拟输入张量(通常填充零)

  2. 将虚拟输入传递给模型,执行一次前向传播(但不计算梯度)

  3. 记录每一层的输入和输出形状,以及参数数量

  4. 生成可读的摘要报告

3.torchinfo库的summary方法

torchinfo 是 torchsummary 的升级版,是 PyTorch 模型可视化的首选工具,其核心 summary 方法支持多输入、嵌套模块、多设备(CUDA/CPU/MPS)、自定义显示列等,能精准展示每层的输入输出形状、参数数量、训练状态、内存占用等关键信息。

python 复制代码
from torchinfo import summary
summary(model, input_size=(4, ))

二、进度条功能

1.手动更新

python 复制代码
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步
python 复制代码
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

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

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

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

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

2.自动更新

python 复制代码
from tqdm import tqdm
import time

# 直接将range(3)传给tqdm,自动生成进度条
# 这个写法我觉得是有点神奇的,直接可以给这个对象内部传入一个可迭代对象,然后自动生成进度条
for i in tqdm(range(3), desc="处理任务", unit="epoch"):
    time.sleep(1)
python 复制代码
# 用tqdm的set_postfix方法在进度条右侧显示实时数据(如当前循环的数值、计算结果等):
from tqdm import tqdm
import time

total = 0  # 初始化总和
with tqdm(total=10, desc="累加进度") as pbar:
    for i in range(1, 11):
        time.sleep(0.3)
        total += i  # 累加1+2+3+...+10
        pbar.update(1)  # 进度+1
        pbar.set_postfix({"当前总和": total})  # 显示实时总和

三、模型的推理

模型推理(Inference)是指使用训练好的模型对新数据进行预测 / 分类 / 回归的过程,核心目标是高效、准确地得到模型输出。在 PyTorch 中,推理流程需重点关注「模型状态切换、梯度关闭、数据预处理、设备匹配、效率优化」等关键点。

python 复制代码
# 在测试集上评估模型,此时model内部已经是训练好的参数了
# 评估模型
model.eval() # 设置模型为评估模式
with torch.no_grad(): # torch.no_grad()的作用是禁用梯度计算,可以提高模型推理速度
    outputs = model(X_test)  # 对测试数据进行前向传播,获得预测结果
    _, predicted = torch.max(outputs, 1) # torch.max(outputs, 1)返回每行的最大值和对应的索引
 
    correct = (predicted == y_test).sum().item() # 计算预测正确的样本数
    accuracy = correct / y_test.size(0)
    print(f'测试集准确率: {accuracy * 100:.2f}%')

核心原则:

  • 推理时需将模型切换为 eval() 模式(禁用 BatchNorm/Dropout 等训练特有的层行为);
  • 关闭梯度计算(torch.no_grad()),节省内存、加速推理;
  • 数据预处理需与训练时完全一致(如归一化、尺寸、通道顺序);
  • 保证输入数据与模型设备(CPU/GPU/MPS)一致。

前提:训练好的模型保存,推理的前提是有训练好的模型权重文件,先演示模型保存。

模型推理的核心流程:

模型加载与eval模式 → 数据预处理(与训练一致) → 关闭梯度的前向传播 → 结果后处理

@浙大疏锦行

相关推荐
艾上编程2 小时前
第二章——数据分析场景之用Python进行CSV/Excel数据清洗:为数据分析筑牢根基
python·数据分析·excel
闲人编程2 小时前
FastAPI性能优化技巧
后端·python·性能优化·fastapi·性能·codecapsule
Amazon数据采集2 小时前
# 🚀 亚马逊URL参数拼接实战:数据采集效率提升指南
python
岁月宁静2 小时前
FastAPI 入门指南
人工智能·后端·python
AI小云2 小时前
【数据操作与可视化】Serborn绘图-类别散点图和热力图
python·数据可视化
码界奇点2 小时前
基于Python与Django的白泽自动化运维系统设计与实现
运维·python·django·毕业设计·源代码管理
semantist@语校2 小时前
第五十五篇|从解释约束到结构化认知:京都国际学院的语言学校Prompt工程化实践
大数据·数据库·人工智能·python·百度·prompt·知识图谱
我送炭你添花2 小时前
Pelco KBD300A 模拟器:05.校验算法终极对比 + 完整 100+ 指令封装 + KBD300A 所有隐藏功能函数化
python·算法·自动化·运维开发
八年。。2 小时前
simulink与python联合仿真(一)安装MATLAB引擎
开发语言·python