【模型转换】onnx删除并新增节点

本文介绍如何在ONNX模型中删除原有的Squeeze节点,并在同一位置插入新的Squeeze节点,同时设置了新节点的axes参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        仍然以【模型转化】修改onnx节点属性这篇文章中的例子为例来学习onnx的基本操作。这次不再修改Squeeze节点的属性(attribute),而是删除原有Squeeze节点,再在原来位置添加一个新的Squeeze节点。

1.定位要操作的节点

import onnx                                                                                                                                                                                                                                                           
model = onnx.load('my.onnx') 
for node_id,node in enumerate(model.graph.node):
    print("######%s######" % node_id)
    print(node)

要操作的Squeeze为45号节点。

...
 
######45######
input: "384"
output: "385"
name: "Squeeze_250"
op_type: "Squeeze"
                        
...

2. 删除并增加新节点

import onnx                                                                                                                                                                                                                                                           
model = onnx.load('my.onnx')

#删除老节点 
old_squeeze_node = model.graph.node[45]
model.graph.node.remove(old_squeeze_node)

#新建新节点并添加进graph
new_squeeze_node = onnx.helper.make_node(
    name = "Squeeze_250",
    op_type="Squeeze",
    inputs=["384"],
    outputs=["385"],
    axes=[0,3], 
)
model.graph.node.insert(45,new_squeeze_node)
onnx.save(model,"my.onnx")

 Squeeze操作需要的axes参数,我在make_node的时候通过kwargs参数作了指定。关于onnx.helper.make_node用法可参见如下说明。

In [4]: onnx.helper.make_node??                                                                                                                                                                                                                                       
Signature:
onnx.helper.make_node(
    op_type:str,
    inputs:Sequence[str],
    outputs:Sequence[str],
    name:Union[str, NoneType]=None,
    doc_string:Union[str, NoneType]=None,
    domain:Union[str, NoneType]=None,
    **kwargs:Any,
) -> onnx.onnx_ml_pb2.NodeProto
Source:   
def make_node(
        op_type: Text,
        inputs: Sequence[Text],
        outputs: Sequence[Text],
        name: Optional[Text] = None,
        doc_string: Optional[Text] = None,
        domain: Optional[Text] = None,
        **kwargs: Any
) -> NodeProto:
    """Construct a NodeProto.

    Arguments:
        op_type (string): The name of the operator to construct
        inputs (list of string): list of input names
        outputs (list of string): list of output names
        name (string, default None): optional unique identifier for NodeProto
        doc_string (string, default None): optional documentation string for NodeProto
        domain (string, default None): optional domain for NodeProto.
            If it's None, we will just use default domain (which is empty)
        **kwargs (dict): the attributes of the node.  The acceptable values
            are documented in :func:`make_attribute`.
    """

    node = NodeProto()
    node.op_type = op_type
    node.input.extend(inputs)
    node.output.extend(outputs)
    if name:
        node.name = name
    if doc_string:
        node.doc_string = doc_string
    if domain is not None:
        node.domain = domain
    if kwargs:
        node.attribute.extend(
            make_attribute(key, value)
            for key, value in sorted(kwargs.items())
            if value is not None)
    return node

3.检查新生成的onnx

...
 
######45######
input: "384"
output: "385"
name: "Squeeze_250"
op_type: "Squeeze"
attribute {
  name: "axes"
  ints: 0
  ints: 3
  type: INTS 
}
                        
...

### 如何进行ONNX的自定义配置 ONNX(Open Neural Network Exchange)是一种开放格式,用于表示机器学习模型。通过ONNX,可以在不同的框架之间交换模型优化其性能。为了实现ONNX的自定义配置,通常需要关注以下几个方面: #### 1. 导出模型ONNX格式 在PyTorch或其他支持ONNX导出的框架中,可以通过`torch.onnx.export()`函数将训练好的模型转换ONNX文件。此过程允许指定输入形状和其他参数。 以下是基本的代码示例: ```python import torch from models.your_model import YourModel # 假设这是您的模型类 model = YourModel() # 初始化模型实例 dummy_input = torch.randn(1, 3, 224, 224) # 创建虚拟输入张量 (batch_size=1) # 将模型导出为ONNX格式 torch.onnx.export( model, dummy_input, "your_model.onnx", # 输出路径 input_names=["input"], # 输入名称列表 output_names=["output"], # 输出名称列表 dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}, # 动态轴设置 opset_version=13 # 指定使用的ONNX操作集版本 ) ``` 上述代码中的`opset_version`是一个重要参数,它决定了所生成ONNX文件的操作符集合版本[^1]。不同版本可能会影响兼容性和功能特性。 --- #### 2. 自定义ONNX图结构 如果默认导出无法满足需求,则可以手动修改ONNX图结构。这涉及加载已有的ONNX文件通过工具库(如`onnx`或`onnx-simplifier`)调整节点属性、添加新层或将某些运算替换为更高效的替代方案。 以下是如何加载和保存ONNX文件的一个简单例子: ```python import onnx # 加载现有的ONNX模型 onnx_model = onnx.load("your_model.onnx") # 修改模型(例如删除特定节点) for node in onnx_model.graph.node: if node.name == "unwanted_node": onnx_model.graph.node.remove(node) # 验证模型合法性 onnx.checker.check_model(onnx_model) # 保存更新后的模型 onnx.save(onnx_model, "modified_your_model.onnx") ``` 在此过程中需要注意的是,任何更改都应保持整个计算图的一致性,否则可能导致运行时错误或不一致的结果[^2]。 --- #### 3. 解决常见问题——缺失属性异常 当尝试加载ONNX模型时遇到类似于“Can’t get attribute”的错误消息时,通常是由于源代码与目标环境之间的差异引起的。具体来说,在YoloV5项目中提到的`SPPF`模块就是一个典型案例。解决方法包括但不限于以下几种策略: - **重新编译依赖项**:确保所有相关脚本及其子模块均被正确安装至当前工作目录下。 - **冻结Python对象序列化行为**:对于那些动态创建的对象类型(比如继承自基类的新组件),考虑将其显式注册进pickle机制以便跨平台传输无误。 - **升级/降级框架版本**:有时最新版软件包会引入破坏向后兼容性的改动;因此适当回滚至稳定分支或许能缓解此类冲突现象。 --- #### 4. 使用Adapter Tuning技术优化ONNX部署 针对大型预训练语言模型(PLMs),Hugging Face提供了多种微调方式来降低资源消耗的同时维持较高的预测精度。其中一种流行的方法叫做Adapters tuning,即仅对少量新增参数执行梯度下降而固定住原有权重矩阵不变。这种方法特别适合移动端或者边缘设备上轻量化推理场景应用。 要启用适配器模式,请按照官方文档指引完成如下几步操作即可: 1. 安装必要的扩展插件; 2. 调整初始化阶段加入对应选项开关; 3. 训练结束后提取独立出来的adapter部分单独存储成二进制形式供后续导入使用。 最终得到的小型附加组件可以直接嵌入原生ONNX流程当中从而进一步提升效率表现。 --- ### 总结 综上所述,定制化的ONNX配置不仅限于简单的模型转储动作本身,还涵盖了后期维护以及实际生产环境中可能出现的各种复杂状况处理技巧等内容。希望以上介绍能够帮助您更好地理解和实践这一领域内的关键技术要点!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值