torchinfo.summary()可打印含输入尺寸的完整拓扑,显示每层输入/输出shape、参数量、内存占用及flops,比print(model)更全面;需指定input_size(如(16,3,224,224)),避免设备不一致或动态分支导致的报错。

用 torchinfo.summary() 打印带输入尺寸的完整拓扑
直接 print(model) 只显示模块嵌套关系,不体现每层输入/输出 shape、参数量、内存占用,对调试和模型分析帮助有限。torchinfo 是目前最轻量且兼容性最好的替代方案(已取代老旧的 torchsummary)。
安装后必须传入实际的 input_size(batch 维必须显式指定),否则会报 RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the same 类错误:
pip install torchinfo from torchinfo import summary summary(model, input_size=(16, 3, 224, 224)) # 注意:不是 (3, 224, 224)
- batch size 设太小(如 1)可能导致某些层(如 BatchNorm)因统计量不足而报错;设太大可能 OOM,建议从 8 或 16 开始试
- 若模型含动态控制流(如
if x.sum() > 0:),torchinfo会静默失败或只显示部分分支 —— 这时只能退回到手动插入钩子或分段打印 - 支持多输入:传入 tuple,如
input_size=([(1, 3, 224, 224), (1, 100)])
导出 .onnx 后用 Netron 查看可视化拓扑图
Netron 不解析 Python 代码,它只读取序列化后的模型文件(如 .onnx、.pt、.pth)。PyTorch 原生 .pt 文件若含自定义 forward 逻辑,Netron 往往无法还原计算图;必须先转成 ONNX 格式。
导出时容易漏掉 training=False 和 opset_version,导致 Netron 打开后节点异常或缺失:
import torch.onnx
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
model.eval(), # 必须调用 .eval()
dummy_input,
"model.onnx",
input_names=["input"],
output_names=["output"],
opset_version=13, # 推荐 12–14,太高(如 17)部分算子不兼容
training=torch.onnx.TrainingMode.EVAL
)
- 若模型含
torch.jit.script或nn.ModuleList动态索引,ONNX 导出可能失败,需改用torch.jit.trace+torch.jit.save再用 Netron 打开.pt - Netron 网页版(netron.app)不支持上传大文件(>100MB),本地桌面版更稳
- 导出后双击
.onnx即可打开,右侧可逐层查看 tensor shape、数据类型、算子属性
不用第三方库,只靠 PyTorch 原生 API 拆解层级结构
当环境受限(如离线服务器)或需精确控制打印粒度时,应放弃封装库,直接遍历 named_children() 和 named_modules()。
关键区别在于:named_children() 只返回直接子模块(一层深),适合查看顶层 block;named_modules() 返回所有嵌套模块(递归),但会包含重复或无意义的中间 wrapper:
# 只看主干结构(如 ResNet 的 layer1/layer2/...)
for name, module in model.named_children():
print(f"{name}: {module.__class__.__name__}")
<h1>查看所有叶子层(含 Conv/BatchNorm/Linear 等)</h1><p>for name, module in model.named_modules():
if len(list(module.children())) == 0 and not isinstance(module, nn.Sequential):
print(f"{name} -> {module.<strong>class</strong>.<strong>name</strong>}")</p>
-
model.modules()不带名字,调试时难定位;务必优先用named_modules() - 注意
nn.Sequential本身是容器,其内部子模块不会被named_children()列出,需额外递归处理 - 若想打印某一层的权重 shape,用
list(module.parameters())[0].shape,但要确保该层确实有参数(比如nn.ReLU就没有)
为什么 torchsummary 容易报错而 torchinfo 更稳
torchsummary 已停止维护,其底层仍基于旧版 PyTorch 的 register_forward_hook 实现,在 PyTorch ≥ 2.0 中与新编译器(torch.compile)、启用 torch.inference_mode() 或使用 nn.utils.parametrize 时极易触发 AttributeError: 'NoneType' object has no attribute 'size'。
torchinfo 改用前向执行 + 自动 shape 推导(类似 ONNX 的 shape inference),绕过了 hook 机制的副作用:
- 它默认在 CPU 上运行推导,避免 GPU/CPU 设备不一致问题;如需 GPU 推导,得手动把
dummy_input和model都.to("cuda") - 遇到
torch.nn.Identity或自定义空操作层时,torchinfo会跳过而非崩溃,而torchsummary常卡死 - 不支持 JIT 模型(
torch.jit.ScriptModule),此时只能用model.code看 IR,或回退到named_modules()方案
真正麻烦的是那些依赖运行时条件分支的模型——无论用哪个工具,都只能看到“静态展开”后的路径。这时候,得靠在 forward 里插 print(x.shape) 或用 torch.utils.hooks 捕获实际走过的层。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











