python打卡 DAY 35 模型可视化与推理

目录

一、模型可视化方法

1. 三种主流可视化方案对比

2. torchinfo使用详解

3. 权重分布可视化

二、进度条实现方案

1. 手动实现进度条

2. 自动进度条(推荐)

3. 训练循环集成示例

三、模型推理规范写法

1. 标准推理流程

2. 生产环境推理优化

四、综合应用示例

完整训练-验证-测试流程

五、常见问题解决方案

1. 可视化相关

2. 推理相关

六、扩展技巧

1. 高级进度条功能

2. 模型结构导出


一、模型可视化方法

1. 三种主流可视化方案对比

方法 工具/库 优点 缺点 适用场景
torchinfo torchinfo.summary() 轻量级、参数统计全 无结构图 快速调试
权重分布 matplotlib直方图 直观显示数值分布 需手动实现 权重分析
结构可视化 torchviz/Netron 图形化展示 依赖外部工具 架构设计

2. torchinfo使用详解

from torchinfo import summary

# 基本用法
model = MyCNN()
summary(model, input_size=(16, 3, 224, 224))  # batch,channels,height,width

# 输出示例
"""
=================================================================
Layer (type:depth-idx)        Output Shape              Param #
=================================================================
CNN                           [16, 10]                  --
├─Conv2d: 1-1                [16, 32, 222, 222]        896
├─ReLU: 1-2                   [16, 32, 222, 222]        --
├─MaxPool2d: 1-3             [16, 32, 111, 111]        --
├─Flatten: 1-4               [16, 394272]              --
├─Linear: 1-5                [16, 10]                  3,942,730
=================================================================
Total params: 3,943,626
Trainable params: 3,943,626
Non-trainable params: 0
=================================================================
"""

3. 权重分布可视化

import matplotlib.pyplot as plt

def plot_weights(model):
    weights = []
    for name, param in model.named_parameters():
        if 'weight' in name:
            weights.append(param.data.cpu().numpy().flatten())
    
    plt.figure(figsize=(10, 5))
    plt.hist(np.concatenate(weights), bins=50)
    plt.title("Weight Distribution")
    plt.xlabel("Value")
    plt.ylabel("Frequency")
    plt.show()

# 训练前后对比
plot_weights(untrained_model)
plot_weights(trained_model)

二、进度条实现方案

1. 手动实现进度条

def manual_progress(iterable, total=None):
    total = total or len(iterable)
    for i, item in enumerate(iterable, 1):
        percent = i / total * 100
        bar = '■' * int(percent//2) + ' ' * (50 - int(percent//2))
        print(f"\r[{bar}] {percent:.1f}%", end='')
        yield item
    print()  # 换行

# 使用示例
for batch in manual_progress(train_loader):
    train_batch(batch)

2. 自动进度条(推荐)

from tqdm import tqdm

# 基本用法
for epoch in tqdm(range(epochs), desc="Training"):
    for batch in tqdm(train_loader, leave=False, desc=f"Epoch {epoch}"):
        train_batch(batch)

# 自定义样式
with tqdm(total=len(dataset), 
          bar_format="{l_bar}{bar:20}{r_bar}",
          colour='green') as pbar:
    for data in dataloader:
        process(data)
        pbar.update(len(data))

3. 训练循环集成示例

def train_with_progress(model, loader, epochs):
    model.train()
    with tqdm(total=epochs * len(loader)) as pbar:
        for epoch in range(epochs):
            for batch in loader:
                loss = train_step(model, batch)
                pbar.set_postfix(loss=f"{loss:.4f}")
                pbar.update(1)

三、模型推理规范写法

1. 标准推理流程

def inference(model, dataloader, device='cuda'):
    model.eval()  # 关键:切换到评估模式
    predictions = []
    
    with torch.no_grad():  # 禁用梯度计算
        for inputs in tqdm(dataloader, desc="Inferencing"):
            inputs = inputs.to(device)
            outputs = model(inputs)
            preds = outputs.argmax(dim=1)
            predictions.extend(preds.cpu().numpy())
    
    model.train()  # 恢复训练模式(可选)
    return predictions

2. 生产环境推理优化

@torch.inference_mode()  # PyTorch 1.9+ 更高效
def optimized_inference(model, inputs):
    model.eval()
    inputs = inputs.to(next(model.parameters()).device)
    return model(inputs)

# 使用TorchScript加速
traced_model = torch.jit.trace(model, example_input)
traced_model.save("deploy_model.pt")

四、综合应用示例

完整训练-验证-测试流程

def full_pipeline(model, train_loader, val_loader, test_loader, epochs=10):
    # 初始可视化
    summary(model, input_size=next(iter(train_loader))[0].shape)
    plot_weights(model)
    
    # 训练阶段
    optimizer = torch.optim.Adam(model.parameters())
    for epoch in tqdm(range(epochs), desc="Epochs"):
        model.train()
        for batch in tqdm(train_loader, leave=False, desc="Training"):
            inputs, targets = batch
            outputs = model(inputs)
            loss = F.cross_entropy(outputs, targets)
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
        
        # 验证阶段
        model.eval()
        val_loss, val_acc = evaluate(model, val_loader)
        tqdm.write(f"Epoch {epoch}: Val Loss={val_loss:.4f}, Acc={val_acc:.2f}%")
    
    # 最终测试
    test_results = inference(model, test_loader)
    print(f"\nFinal Test Accuracy: {100 * sum(test_results)/len(test_results):.2f}%")
    
    # 权重分析
    plot_weights(model)

五、常见问题解决方案

1. 可视化相关

问题 解决方案
torchinfo报维度错误 检查input_size与真实输入是否匹配
权重分布图显示异常 添加plt.clf()清除之前绘图
进度条重复打印 设置leave=False或使用tqdm.write()

2. 推理相关

问题 解决方案
推理结果不一致 确保model.eval()torch.no_grad()
内存不足 减小batch_size或使用del及时释放张量
速度慢 启用torch.inference_mode()或使用TorchScript

六、扩展技巧

1. 高级进度条功能

# 多进度条嵌套
with tqdm(total=100, desc="Main") as pbar_main:
    for i in range(10):
        with tqdm(total=10, desc=f"Sub {i}", leave=False) as pbar_sub:
            for j in range(10):
                time.sleep(0.1)
                pbar_sub.update(1)
                pbar_main.update(1)

2. 模型结构导出

# 导出为ONNX格式
torch.onnx.export(
    model,
    torch.randn(1, 3, 224, 224),
    "model.onnx",
    input_names=["input"],
    output_names=["output"]
)

# 使用Netron可视化
import netron
netron.start("model.onnx")

@浙大疏锦行

你可能感兴趣的:(Python打卡,python,开发语言,算法,笔记,深度学习)