可视化 PyTorch 模型
PyTorch是一个深度学习库。您可以使用 PyTorch 构建非常复杂的深度学习模型。但是,有时您希望具有模型体系结构的图形表示。
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
可视化 PyTorch 模型
概述
这篇文章分为两部分;他们是
- 为什么 PyTorch 模型的图形表示很难
- 如何使用Netron创建模型图
为什么 PyTorch 模型的图形重置很难
PyTorch是一个非常灵活的深度学习库。严格来说,它从不强制要求你应该如何构建你的模型,只要它像一个可以将输入张量转换为输出张量的函数一样工作。这是一个问题:对于模型,除非遵循输入张量并收集跟踪,直到获得输出张量,否则您永远不知道它是如何工作的。因此,将 PyTorch 模型转换为图片并非易事。
有多个库可以解决此问题。但一般来说,只有两种方法可以解决它:你可以跟随前向传递上的张量,看看应用了什么操作(即层),或者跟随反向传递上的张量,看看梯度是如何传播到输入的。您只能以这种方式找到有关模型内部结构的线索。
如何使用Netron创建模型图
当您保存 PyTorch 模型时,您正在保存其状态。您可以使用 获取模型状态。虽然权重张量具有名称,因此可以帮助您将它们恢复到模型中,但您没有关于权重如何相互连接的线索。连接张量并找出它们关系的唯一方法是获得张量梯度:当您运行模型并获得输出时,所涉及的计算(包括对其他张量的依赖关系)会被每个中间张量记住,以便可以执行自动微分。model.state_dict()
事实上,如果你想知道 PyTorch 模型背后的算法,这也是你要走的路。只有少数工具可以从 PyTorch 模型创建图形。在下面,您将了解工具Netron。它是一个“深度学习模型查看器”。它是您可以在macOS,Linux和Windows上安装和运行的软件。您可以访问以下页面并下载适用于您平台的软件:
- https://github.com/lutzroeder/netron/releases
还有一个在线版本可用,您可以通过上传模型文件来查看您的模型。
Netron无法从保存的状态中可视化PyTorch模型,因为没有足够的线索来说明模型的结构。但是,PyTorch允许您将模型转换为Netron可以理解的交换格式ONNX。
让我们从一个例子开始。在下面,您创建了一个简单的模型来对鸢尾花数据集进行分类。这是一个具有三个类的分类问题。因此,模型应输出三个值的向量。您将为此问题创建的完整代码如下,数据集是从scikit-learn获得的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split data = load_iris() X = data['data'] y = data['target'] X = torch.tensor(X, dtype=torch.float32) y = torch.tensor(y, dtype=torch.long) # split X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, shuffle=True) class IrisModel(nn.Module): def __init__(self): super().__init__() self.hidden = nn.Linear(4, 8) self.act = nn.ReLU() self.output = nn.Linear(8, 3) def forward(self, x): x = self.act(self.hidden(x)) x = self.output(x) return x # loss metric and optimizer model = IrisModel() loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # prepare model and training parameters n_epochs = 100 batch_size = 10 batch_start = torch.arange(0, len(X_train), batch_size) # training loop for epoch in range(n_epochs): for start in batch_start: # take a batch X_batch = X_train[start:start+batch_size] y_batch = y_train[start:start+batch_size] # forward pass y_pred = model(X_batch) loss = loss_fn(y_pred, y_batch) # backward pass optimizer.zero_grad() loss.backward() # update weights optimizer.step() # validating model y_pred = model(X_test) acc = (torch.argmax(y_pred, 1) == y_test).float().mean() acc = float(acc)*100 print("Model accuracy: %.2f%%" % acc) |
运行上述程序会产生以下内容,例如:
1 | Model accuracy: 97.78% |
所以你知道这是一个 PyTorch 模型,它可以接受一个张量并返回一个张量。您可以使用以下函数将此模型转换为 ONNX 格式:model
torch.onnx.export()
1 | torch.onnx.export(model, X_test, 'iris.onnx', input_names=["features"], output_names=["logits"]) |
运行此操作将在本地目录中创建一个文件。您需要提供一个与模型一起使用的示例张量作为输入(在上面的示例中)。这是因为在转换过程中,它需要遵循此示例张量以了解应应用哪些操作,以便您可以逐步将算法转换为 ONNX 格式。PyTorch 模型中的每个权重都是一个张量,并且为它们分配了一个名称。但是输入和输出张量通常不命名,因此您需要在运行时为它们提供一个名称。这些名称应作为字符串列表提供,因为通常,模型可以采用多个张量并返回多个张量。iris.onnx
X_test
export()
通常你应该在训练循环后跑步。这是因为创建的 ONNX 模型包含一个完整的模型,您可以在没有 PyTorch 库的情况下运行该模型。您想为其节省优化的重量。但是,为了在Netron中可视化模型,模型的质量不是问题。您可以在创建 PyTorch 模型后立即运行。export()
export()
启动Netron后,您可以打开保存的ONNX文件。在此示例中,应看到以下屏幕:
它显示了输入张量如何通过深度学习模型中的不同操作连接到输出张量。您提供给函数的输入和输出张量的名称将在可视化中使用。单击一个框将为您提供有关该特定张量或操作的更多详细信息。但是,您在Netron中看到的操作名称可能与您在PyTorch中调用它们的名称不同。在上面的屏幕中,您会看到该层变为“Gemm”,代表“通用矩阵乘法”操作。您甚至可以使用 Netron 通过几个点和单击来检查图层上的权重。export()
nn.Linear()
如果要保留此可视化的副本,可以在 Netron 中将其导出为 PNG 格式。
3D建模学习工作室 翻译整理,转载请注明出处!