在Java中加载ONNX模型

在Java中加载ONNX模型,java,caffe2,Java,Caffe2,我有一个训练有素的PyTorch模型,现在我想使用ONNX导出到Caffe2。这一部分似乎相当简单,并且有很好的文档记录。但是,我现在想将该模型“加载”到Java程序中,以便在我的程序(Flink流媒体应用程序)中执行预测。最好的方法是什么?我在网站上找不到任何文档来描述如何做到这一点。目前这有点棘手,但有一种方法。您需要使用JavaCPP: 图形 ONNX 我将以以下为例: //read ONNX byte[] bytes = Files.readAllBytes(Path

我有一个训练有素的PyTorch模型,现在我想使用ONNX导出到Caffe2。这一部分似乎相当简单,并且有很好的文档记录。但是,我现在想将该模型“加载”到Java程序中,以便在我的程序(Flink流媒体应用程序)中执行预测。最好的方法是什么?我在网站上找不到任何文档来描述如何做到这一点。

目前这有点棘手,但有一种方法。您需要使用JavaCPP:

  • 图形
  • ONNX
我将以以下为例:

    //read ONNX
    byte[] bytes = Files.readAllBytes(Paths.get("single_relu.onnx"));
    ModelProto model = new ModelProto(); 
    ParseProtoFromBytes(model, new BytePointer(bytes), bytes.length); // parse ONNX -> protobuf model

    //preprocess model in any way you like (you can skip this step)
    check_model(model);
    InferShapes(model);
    StringVector passes = new StringVector("eliminate_nop_transpose", "eliminate_nop_pad", "fuse_consecutive_transposes", "fuse_transpose_into_gemm");
    Optimize(model, passes);
    check_model(model);
    ConvertVersion(model, 8);
    BytePointer serialized = model.SerializeAsString();
    System.out.println("model="+serialized.getString());

    //prepare nGraph backend
    Backend backend = Backend.create("CPU");
    Shape shape = new Shape(new SizeTVector(1,2 ));
    Tensor input =backend.create_tensor(f32(), shape);
    Tensor output =backend.create_tensor(f32(), shape);
    Function ng_function = import_onnx_model(serialized); // convert ONNX -> nGraph
    Executable exec = backend.compile(ng_function);
    exec.call(new NgraphTensorVector(output), new NgraphTensorVector(input));

    //collect result to array
    float[] r = new float[2];
    FloatPointer p = new FloatPointer(r);
    output.read(p, 0, r.length * 4);
    p.get(r);

    //print result
    System.out.println("[");
    for (int i = 0; i < shape.get(0); i++) {
        System.out.print(" [");
        for (int j = 0; j < shape.get(1); j++) {
            System.out.print(r[i * (int)shape.get(1) + j] + " ");
        }
        System.out.println("]");
    }
    System.out.println("]");
//读取ONNX
byte[]bytes=Files.readAllBytes(path.get(“single_relu.onnx”);
ModelProto model=新ModelProto();
ParseProtoFromBytes(模型,新的BytePointer(字节),bytes.length);//解析ONNX->protobuf模型
//以您喜欢的任何方式预处理模型(您可以跳过此步骤)
检查_模型(模型);
模型;
StringVector passs=新的StringVector(“消除转置”、“消除转置”、“融合连续转置”、“融合转置到gemm”);
优化(模型、过程);
检查_模型(模型);
转换版本(型号8);
BytePointer serialized=model.SerializeAsString();
System.out.println(“model=“+serialized.getString());
//准备nGraph后端
Backend=Backend.create(“CPU”);
形状=新形状(新尺寸向量(1,2));
张量输入=后端。创建张量(f32(),形状);
Tensor输出=后端。创建_Tensor(f32(),shape);
函数ng_Function=import_onnx_model(序列化);//转换ONNX->nGraph
可执行exec=backend.compile(ng_函数);
执行调用(新的NgraphTensorVector(输出),新的NgraphTensorVector(输入));
//将结果收集到数组中
浮动[]r=新浮动[2];
浮动指针p=新的浮动指针(r);
输出读取(p,0,r.length*4);
p、 get(r);
//打印结果
System.out.println(“[”);
for(int i=0;i
你好!你有关于这个问题的更新或解决方案吗?很遗憾,我没有。现在我只是在Python中使用AWS Lambda,并像调用程序中的任何其他API一样调用它。我很想听听如何用Java加载模型。您可以尝试一下CNTK的实验性Java绑定。就我所能测试的而言,它们在非周期性模型中运行良好。递归模型是一个问题,因为当前绑定使得构建观测序列非常困难。现在可以使用PyTrac的C++ API直接使用java的Pavthpp预置,因此您甚至不用担心ONNX: