从 onnx 文件中查找输入形状

Nic*_*ker 4 python onnx

如何找到 onnx 模型的输入大小?我最终想从 python 编写脚本。

使用 tensorflow 我可以恢复图定义,从中找到输入候选节点,然后获取它们的大小。我可以用 ONNX(甚至更简单)做类似的事情吗?

谢谢

小智 14

请不要用作input变量名,因为它是内置函数。

我想到的第一个想法是,google.protobuf.json_format.MessageToDict()如果我需要 protobuf 对象的名称、data_type 或某些属性,请使用该方法。例如:

from google.protobuf.json_format import MessageToDict

model = onnx.load("path/to/model.onnx")
for _input in model.graph.input:
    print(MessageToDict(_input))

Run Code Online (Sandbox Code Playgroud)

将给出如下输出:

{'name': '0', 'type': {'tensorType': {'elemType': 2, 'shape': {'dim': [{'dimValue': '4'}, {'dimValue': '3'}, {'dimValue': '384'}, {'dimValue': '640'}]}}}}
Run Code Online (Sandbox Code Playgroud)

我不太清楚 every 是否model.graph.input是一个RepeatedCompositeContainer对象,但是for当它是一个RepeatedCompositeContainer.

然后您需要从现场获取形状信息dim

model = onnx.load("path/to/model.onnx")
for _input in model.graph.input:
    m_dict = MessageToDict(_input))
    dim_info = m_dict.get("type").get("tensorType").get("shape").get("dim")  # ugly but we have to live with this when using dict
    input_shape = [d.get("dimValue") for d in dim_info]  # [4,3,384,640]
Run Code Online (Sandbox Code Playgroud)

如果您需要唯一的暗淡,请改用消息对象。

model = onnx.load("path/to/model.onnx")
for _input in model.graph.input:
    dim = _input.type.tensor_type.shape.dim
    input_shape = [MessageToDict(d).get("dimValue") for d in dim] # ['4', '3', '384', '640']
    # if you prefer the python naming style, using the line below
    # input_shape = [MessageToDict(d, preserving_proto_field_name=True).get("dim_value") for d in dim]
Run Code Online (Sandbox Code Playgroud)

一行版本:

model = onnx.load("path/to/model.onnx")
input_shapes = [[d.dim_value for d in _input.type.tensor_type.shape.dim] for _input in model.graph.input]
Run Code Online (Sandbox Code Playgroud)

参考文献:

https://github.com/googleapis/python-vision/issues/70

AttributeError:“google.protobuf.pyext._message.RepeatedCompositeCo”对象没有属性“append”


小智 13

是的,前提是输入模型具有信息。请注意,ONNX 模型的输入可能具有未知等级,或者可能具有具有固定维度(如 100)或符号(如“N”)或完全未知的已知等级。您可以按如下方式访问:

import onnx

model = onnx.load(r"model.onnx")

# The model is represented as a protobuf structure and it can be accessed
# using the standard python-for-protobuf methods

# iterate through inputs of the graph
for input in model.graph.input:
    print (input.name, end=": ")
    # get type of input tensor
    tensor_type = input.type.tensor_type
    # check if it has a shape:
    if (tensor_type.HasField("shape")):
        # iterate through dimensions of the shape:
        for d in tensor_type.shape.dim:
            # the dimension may have a definite (integer) value or a symbolic identifier or neither:
            if (d.HasField("dim_value")):
                print (d.dim_value, end=", ")  # known dimension
            elif (d.HasField("dim_param")):
                print (d.dim_param, end=", ")  # unknown dimension with symbolic name
            else:
                print ("?", end=", ")  # unknown dimension with no name
    else:
        print ("unknown rank", end="")
    print()
Run Code Online (Sandbox Code Playgroud)


dev*_*hye 10

如果使用onnxruntime而不是onnx进行推理。

尝试使用下面的代码。

import onnxruntime as ort
model = ort.InferenceSession("model.onnx", providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
input_shape = model.get_inputs()[0].shape
Run Code Online (Sandbox Code Playgroud)