onnx::ModelProto mymodel;
onnx::GraphProto graph;
mymodel.clear_graph();
mymodel.set_producer_name("pytorch 1.3");//important
onnx::OperatorSetIdProto* myopset = mymodel.add_opset_import(); //important
mymodel.set_allocated_graph(&graph);
graph.clear_node();
graph.clear_input();
graph.clear_output();
onnx::TypeProto input_type;
onnx::TypeProto_Tensor input_tensor_type;
onnx::TensorShapeProto input_shape;
onnx::ValueInfoProto*input = graph.add_input();
input->set_name("myinput");
input->set_allocated_type(&input_type);
input_type.set_allocated_tensor_type(&input_tensor_type);
input_tensor_type.set_elem_type(onnx::AttributeProto_AttributeType_FLOAT);
input_tensor_type.set_allocated_shape(&input_shape);
onnx::TensorShapeProto_Dimension* dim = input_shape.add_dim();
dim->set_dim_value(1);
dim = input_shape.add_dim();
dim->set_dim_value(512);
dim = input_shape.add_dim();
dim->set_dim_value(64);
dim = input_shape.add_dim();
dim->set_dim_value(64);
onnx::TypeProto output_type;
onnx::TypeProto_Tensor output_tensor_type;
onnx::TensorShapeProto output_shape;
onnx::ValueInfoProto*output = graph.add_output();
output->set_name("output");
output->set_allocated_type(&output_type);
output_type.set_allocated_tensor_type(&output_tensor_type);
output_tensor_type.set_elem_type(onnx::AttributeProto_AttributeType_FLOAT);
output_tensor_type.set_allocated_shape(&output_shape);
dim = output_shape.add_dim();
dim->set_dim_value(1);
dim = output_shape.add_dim();
dim->set_dim_value(128);
dim = output_shape.add_dim();
dim->set_dim_value(128);
dim = output_shape.add_dim();
dim->set_dim_value(128);
onnx::NodeProto *depthtospace = graph.add_node();
depthtospace->set_op_type("DepthToSpace");
onnx::AttributeProto* blocksize = depthtospace->add_attribute();
blocksize->set_type(onnx::AttributeProto_AttributeType_INT);
blocksize->set_name("blocksize");
blocksize->set_i(2);
onnx::AttributeProto* mode = depthtospace->add_attribute();
mode->set_type(onnx::AttributeProto_AttributeType_STRING);
mode->set_name("mode");
mode->set_s("CRD");
depthtospace->add_input("myinput");
depthtospace->add_output("output");
int fd = open("out.onnx", O_WRONLY | O_CREAT| O_BINARY,0644);
bool suc = mymodel.SerializeToFileDescriptor(fd);
close(fd);
目前能够通过netron打开,但是onnxruntime导入模型会有失败的error:
onnxruntime.capi.onnxruntime_pybind11_state.InvalidArgument: [ONNXRuntimeError] : 2 :
INVALID_ARGUMENT : Failed to load model with error: Unknown model file format version.
目前还不知道怎么修改,暂留以待后续解决...
不过可以按照这个方式通过netron显示其它格式的模型(自定义的模型)
问题修改:
1、需要设置 model的ir version
2、需要设置opset_import的domain、version
完成上述修改即可使用onnxruntime对生成的模型进行inference:
onnx::ModelProto mymodel;
onnx::GraphProto graph;
mymodel.clear_graph();
mymodel.set_producer_name("pytorch 1.3");//important
mymodel.set_ir_version(4);
onnx::OperatorSetIdProto* myopset = mymodel.add_opset_import(); //important
myopset->set_domain("com.microsoft"); //"com.microsoft" "ai.onnx v11"
myopset->set_version(1);
mymodel.set_allocated_graph(&graph);
graph.clear_node();
graph.clear_input();
graph.clear_output();
onnx::TypeProto input_type;
onnx::TypeProto_Tensor input_tensor_type;
onnx::TensorShapeProto input_shape;
onnx::ValueInfoProto*input = graph.add_input();
input->set_name("myinput");
input->set_allocated_type(&input_type);
input_type.set_allocated_tensor_type(&input_tensor_type);
input_tensor_type.set_elem_type(onnx::AttributeProto_AttributeType_FLOAT);
input_tensor_type.set_allocated_shape(&input_shape);
onnx::TensorShapeProto_Dimension* dim = input_shape.add_dim();
dim->set_dim_value(1);
dim = input_shape.add_dim();
dim->set_dim_value(512);
dim = input_shape.add_dim();
dim->set_dim_value(64);
dim = input_shape.add_dim();
dim->set_dim_value(64);
onnx::TypeProto output_type;
onnx::TypeProto_Tensor output_tensor_type;
onnx::TensorShapeProto output_shape;
onnx::ValueInfoProto*output = graph.add_output();
output->set_name("output");
output->set_allocated_type(&output_type);
output_type.set_allocated_tensor_type(&output_tensor_type);
output_tensor_type.set_elem_type(onnx::AttributeProto_AttributeType_FLOAT);
output_tensor_type.set_allocated_shape(&output_shape);
dim = output_shape.add_dim();
dim->set_dim_value(1);
dim = output_shape.add_dim();
dim->set_dim_value(128);
dim = output_shape.add_dim();
dim->set_dim_value(128);
dim = output_shape.add_dim();
dim->set_dim_value(128);
onnx::NodeProto *depthtospace = graph.add_node();
depthtospace->set_op_type("DepthToSpace");
onnx::AttributeProto* blocksize = depthtospace->add_attribute();
blocksize->set_type(onnx::AttributeProto_AttributeType_INT);
blocksize->set_name("blocksize");
blocksize->set_i(2);
onnx::AttributeProto* mode = depthtospace->add_attribute();
mode->set_type(onnx::AttributeProto_AttributeType_STRING);
mode->set_name("mode");
mode->set_s("CRD");
depthtospace->add_input("myinput");
depthtospace->add_output("output");
int fd = open("out.onnx", O_WRONLY | O_CREAT | O_BINARY, 0644);
bool suc = mymodel.SerializeToFileDescriptor(fd);
close(fd);