【问题标题】:Find input shape from onnx file从 onnx 文件中查找输入形状
【发布时间】:2019-11-06 03:25:45
【问题描述】:

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

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

谢谢

【问题讨论】:

    标签: python onnx


    【解决方案1】:

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

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

    form google.protobuf.json_format import MessageToDict
    
    model = onnx.load("path/to/model.onnx")
    for _input in model.graph.input:
        print(MessageToDict(_input))
    
    

    将给出如下输出:

    {'name': '0', 'type': {'tensorType': {'elemType': 2, 'shape': {'dim': [{'dimValue': '4'}, {'dimValue': '3'}, {'dimValue': '384'}, {'dimValue': '640'}]}}}}
    

    我不太清楚每个model.graph.input 是否是RepeatedCompositeContainer 对象,但是当它是RepeatedCompositeContainer 时,有必要使用for 循环。

    那么你需要从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]
    

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

    model = onnx.load("path/to/model.onnx")
    for _input in model.graph.input:
        dim = _input.type.tensor_ype.shape.dim
        input_shape = [MessgeToDict(d).get("dimValue") for d in dim]
        # if you prefer the python naming style, using the line below
        # input_shape = [MessgeToDict(d, preserving_proto_field_name=True).get("dim_value") for d in dim]
    

    单行版本:

    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]
    

    参考:

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

    AttributeError: 'google.protobuf.pyext._message.RepeatedCompositeCo' object has no attribute 'append'

    【讨论】:

    • 感谢您的建议,Yunnosch。我已经更新了答案。
    • 谢谢。现在看起来像一个解释的答案。 (请理解我不会投票,因为我无法判断这是否是技术上正确的答案。)祝你好运。
    【解决方案2】:

    是的,只要输入模型有信息。请注意,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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 2012-03-28
      • 2022-08-04
      • 1970-01-01
      • 2022-10-04
      • 2022-08-09
      相关资源
      最近更新 更多