如何修改预训练ONNX模型的固定输入输出形状?
修改固定形状预训练ONNX模型的输入输出形状的可行方案
方案1:直接通过ONNX库修改并做形状推断
适合有基础Python能力的用户,直接操作模型结构:
- 第一步:查看当前模型的输入输出形状
import onnx model = onnx.load("your_model.onnx") # 打印输入信息 for idx, input in enumerate(model.graph.input): dims = [dim.dim_value for dim in input.type.tensor_type.shape.dim] print(f"输入{idx+1}:名称={input.name},形状={dims}") # 打印输出信息 for idx, output in enumerate(model.graph.output): dims = [dim.dim_value for dim in output.type.tensor_type.shape.dim] print(f"输出{idx+1}:名称={output.name},形状={dims}") - 第二步:修改输入输出的目标形状
找到要修改的输入/输出节点,直接替换dim_value的值:# 示例:修改第一个输入的第一个维度为64(根据你的需求调整索引和数值) model.graph.input[0].type.tensor_type.shape.dim[0].dim_value = 64 # 对应修改输出的匹配维度 model.graph.output[0].type.tensor_type.shape.dim[0].dim_value = 64 - 第三步:形状推断并保存模型
修改后需要确保所有节点的形状逻辑一致,用ONNX的形状推断工具修正:
注意:如果模型内存在硬编码形状的算子(如固定尺寸的池化、卷积),此方法可能报错,需结合方案3调整算子属性。inferred_model = onnx.shape_inference.infer_shapes(model) onnx.save(inferred_model, "modified_model.onnx")
方案2:先转动态形状再固定为目标形状
针对你之前使用make_dynamic_shape_fixed失败的情况,可以先将固定形状转为动态,再设置目标固定形状:
- 第一步:转换为动态形状模型
运行命令行工具:python -m onnxruntime.tools.convert_onnx_models_to_dynamic your_model.onnx dynamic_model.onnx - 第二步:固定为目标形状
替换命令中的input_name、output_name和目标形状为你的实际信息:python -m onnxruntime.tools.make_dynamic_shape_fixed dynamic_model.onnx modified_model.onnx \ --input_shapes "input_name:[64,3,224,224]" \ --output_shapes "output_name:[64,1000]"
方案3:用Netron可视化工具修改(新手友好)
- 下载Netron本地桌面版,打开你的ONNX模型
- 找到输入节点,右键选择「Edit Shape」,输入目标形状数值
- 同理修改输出节点的形状,完成后保存模型
- 验证修改后的模型:
import onnxruntime as ort import numpy as np sess = ort.InferenceSession("modified_model.onnx") # 构造符合新形状的输入数据(替换为你的目标形状) input_data = np.random.randn(64, 3, 224, 224).astype(np.float32) outputs = sess.run(None, {sess.get_inputs()[0].name: input_data}) print(f"输出形状:{outputs[0].shape}")
注意事项
- 如果修改后模型运行报错,优先检查是否有算子依赖原固定形状(如池化层的stride/padding与输入尺寸绑定),可通过Netron查看算子属性并手动调整。
- 跨框架转换(如转TensorFlow)容易丢失模型细节,不建议作为首选方案。
内容的提问来源于stack exchange,提问作者Montparg
相关产品推荐
相关产品推荐

