onnx网络中指定层的结果/中间层结果获取

背景

  • 有时候我们需要对模型推理的中间层结果进行对比分析,这时候如何方便快捷地将指定中间层的结果保存下来就很重要了。
  • 具体方法如下:
    • 核心:在模型推理之前将指定的中间层/所有的层放到输出节点中

代码

from onnx import load_model, save_model
import onnx
import onnxruntime as rt
import torch
import numpy as np
from collections import OrderedDict


# 该设置可以将每层tensor完整地输出,而非输出部分(即省略中间,只显示收尾)
# tips:终端中通常不能全部显示大尺寸的tensor,可以重定向到文本中~
np.set_printoptions(threshold=np.inf)


def to_numpy(tensor):
    return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy()

def read_file(N, C, H, W, bin_path):
    input_size = N * C * H * W
    file = open(bin_path, "rb")
    data = np.fromfile(file, dtype=np.uint8)
    data = data.astype(np.float32) / 255
    data_tensor = torch.from_numpy(data[0:input_size])
    return data_tensor.reshape(N, C, H, W)

# 加载模型
model = onnx.load('./model.onnx')

for node in model.graph.node:
    for output in node.output:
        model.graph.output.extend([onnx.ValueInfoProto(name=output)])
        print('node is: ', onnx.ValueInfoProto(name=output))

# 将指定结点打印出来,检查是否是自己想要的
print(model.graph.output)

# 将模型进行序列化为二进制格式
session = rt.InferenceSession(model.SerializeToString())

# 读取模型的输入
x1 = read_file(1, 1, 128, 128, "./input1.bin")
# x2 = read_file(1, 1, 224, 224, "./input2.bin")

# single input
ort_inputs = {session.get_inputs()[0].name: to_numpy(x1)}
# multiple inputs
# ort_inputs = {session.get_inputs()[0].name: to_numpy(x1), session.get_inputs()[1].name: to_numpy(x2)}
# 执行前向推理,保存结果
ort_out = session.run(None, ort_inputs)

print(ort_out)

# 获取前面循环中指定的所有节点输出
outputs = [x.name for x in session.get_outputs()]
# 将输出压缩在字典中,这样便于通过中间层名字作为key,获取具体的输出tensor值
ort_out = OrderedDict(zip(outputs, ort_out))

# print(len(ort_out))
# print(ort_out)
# 通过中中间层名称访问其输出tensor
# print(ort_out["layer_conv3"])

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 65
    评论
是的,`torch.onnx.export`函数可以获取网络中间层的输出,但需要注意以下几点: 1. 需要在定义模型时将中间层的输出作为返回值,否则在导出ONNX模型时无法获取到这些输出。 2. 在调用`torch.onnx.export`函数时,需要指定`opset_version`参数,以支持所需的ONNX版本。具体来说,如果要支持获取中间层的输出,需要指定`opset_version`为9或更高版本。 3. 导出的ONNX模型中间层的输出将作为额外的输出张量被包含在模型。 以下是一个简单的示例,演示如何使用`torch.onnx.export`函数导出带有中间层输出的ONNX模型: ```python import torch import torch.onnx class MyModel(torch.nn.Module): def __init__(self): super().__init__() self.conv1 = torch.nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1) self.relu1 = torch.nn.ReLU() self.conv2 = torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) self.relu2 = torch.nn.ReLU() def forward(self, x): x = self.conv1(x) out1 = self.relu1(x) x = self.conv2(out1) out2 = self.relu2(x) return out2, out1 model = MyModel() dummy_input = torch.randn(1, 3, 224, 224) output_path = "my_model.onnx" torch.onnx.export( model, dummy_input, output_path, opset_version=11, input_names=["input"], output_names=["output", "mid_output"] ) ``` 在上述示例,`MyModel`类定义了一个包含两个卷积和两个ReLU激活函数的简单神经网络,其在第一个卷积和第二个卷积后分别添加了一个中间层的输出。在调用`torch.onnx.export`函数时,指定`output_names`参数为`["output", "mid_output"]`,以将第一个中间层的输出命名为`"mid_output"`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 65
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值