最新Java教程:在Java中使用便携式ONNX AI模型

在我们关于2020年使用便携式神经网络的系列文章中,您将了解如何在x64架构上安装ONNX并在Java中使用它。

微软与Facebook和AWS共同开发了ONNX。ONNX格式和ONNXRuntime都得到了业界的支持,以确保所有重要的框架都能够将它们的图导出到ONNX,并且这些模型可以在任何硬件配置上运行。

ONNXRuntime是一个用于运行已转换为ONNX格式的机器学习模型的引擎。传统的机器学习模型和深度学习模型(神经网络)都可以输出到ONNX格式。该运行时可以在Linux、Windows和Mac上运行,并且可以在各种芯片架构上运行。它还可以利用GPU和TPU等硬件加速器。不过,并不是每一种操作系统、芯片架构和加速器的组合都有安装包,所以如果您没有使用常见的组合,可能需要从源码中构建运行时。请查看ONNX运行时网站,获取所需组合的安装说明。本文将介绍如何在使用默认CPU的x64架构和使用GPU的x64架构上安装ONNXRuntime。

除了能够在多种硬件配置上运行,运行时还可以从大多数流行的编程语言中调用。本文的目的是展示如何在Java中使用ONNX运行时。我将展示如何安装onnxruntime包。安装ONNXRuntime后,我将把之前导出的MNIST模型加载到ONNXRuntime中,并使用它进行预测。

安装和导入ONNX运行时系统

在使用ONNX运行时之前,您需要为您的构建工具添加适当的依赖性。Maven资源库是为Maven和Gradle等各种工具设置ONNX运行时的良好来源。要在x64架构和默认CPU上使用运行时,请参考以下链接。https://mvnrepository.com/artifact/org.bytedeco/onnxruntime-platform

要在x64架构的GPU上使用运行时,请使用以下链接。https://mvnrepository.com/artifact/org.bytedeco/onnxruntime-platform-gpu

一旦安装了运行时,就可以通过下图所示的导入语句将其导入到你的Java代码文件中。导入TensorProto工具的导入语句将帮助我们为ONNX模型创建输入,它还将帮助解释ONNX模型的输出(预测)。

import ai.onnxruntime.OnnxMl.TensorProto;import ai.onnxruntime.OnnxMl.TensorProto.DataType;import ai.onnxruntime.OrtSession.Result;import ai.onnxruntime.OrtSession.SessionOptions;import ai.onnxruntime.OrtSession.SessionOptions.ExecutionMode;import ai.onnxruntime.OrtSession.SessionOptions.OptLevel;

加载ONNX模型

下面的片段显示了如何将ONNX模型加载到以Java运行的ONNXRuntime中。这段代码创建了一个会话对象,可用于进行预测。这里使用的模型是从PyTorch导出的ONNX模型。

这里有几件事值得注意。首先,您需要查询会话以获取其输入。这是通过会话的getInputInfo方法完成的。我们的MNIST模型只有一个输入参数:一个由784个浮点组成的数组,代表MNIST数据集中的一张图像。如果您的模型有多个输入参数,那么InputMetadata将为每个参数设置一个条目。

Utilities.LoadTensorData();
String modelPath = "pytorch_mnist.onnx";try (OrtSession session = env.createSession(modelPath, options)) {
   Map<String, NodeInfo> inputMetaMap = session.getInputInfo();
   Map<String, OnnxTensor> container = new HashMap<>();
   NodeInfo inputMeta = inputMetaMap.values().iterator().next();   float[] inputData = Utilities.ImageData[imageIndex];
   string label = Utilities.ImageLabels[imageIndex];
   System.out.println("Selected image is the number: " + label);   // this is the data for only one input tensor for this model
   Object tensorData =
            OrtUtil.reshape(inputData, ((TensorInfo) inputMeta.getInfo()).getShape());
   OnnxTensor inputTensor = OnnxTensor.createTensor(env, tensorData);
   container.put(inputMeta.getName(), inputTensor);   // Run code omitted for brevity.}

上面的代码中没有显示的是读取原始MNIST图像并将每幅图像转换为784个浮动数组的实用程序。每个图像的标签也从MNIST数据集中读取,这样就可以确定预测的准确性。这段代码是标准的Java代码,但我们仍然鼓励你检查并使用它。如果您需要读取与MNIST数据集相似的图像,它将为您节省时间。

使用ONNX运行时间进行预测。

下面的功能显示了如何使用我们加载ONNX模型时创建的ONNX会话。

try (OrtSession session = env.createSession(modelPath, options)) {   // Load code not shown for brevity.

   // Run the inference
   try (OrtSession.Result results = session.run(container)) {      // Only iterates once
      for (Map.Entry<String, OnnxValue> r : results) {
         OnnxValue resultValue = r.getValue();
         OnnxTensor resultTensor = (OnnxTensor) resultValue;
         resultTensor.getValue()
         System.out.println("Output Name: {0}", r.Name);         int prediction = MaxProbability(resultTensor);
         System.out.println("Prediction: " + prediction.ToString());
}
   }
}

大多数神经网络不直接返回预测。它们会返回每个输出类的概率列表。在我们MNIST模型的情况下,每个图像的返回值将是一个10个概率的列表。具有最高概率的条目就是预测。您可以做的一个有趣的测试是,当ONNX模型在创建模型的框架内运行时,比较ONNX模型返回的概率和原始模型返回的概率。理想情况下,模型格式和运行时的变化不应改变任何产生的概率。这将是一个很好的单元测试,每次模型发生变化时都会运行。

总结和下一步

在本文中,我简要介绍了ONNX运行时和ONNX格式。然后,我展示了如何在ONNX运行时使用Java加载和运行ONNX模型。

本文的代码示例包含一个工作控制台应用程序,演示了这里所展示的所有技术。该代码示例是Github资源库的一部分,该资源库探讨了如何使用神经网络来预测MNIST数据集中发现的数字。具体来说,有一些样本展示了如何在Keras、PyTorch、TensorFlow1.0和TensorFlow2.0中创建神经网络。

(0)

相关推荐

  • PyTorch深度学习技术生态

    磐创AI 512篇原创内容 公众号   磐创AI分享   转自 | 机器学习实验室 作者 | louwill 来源 | Machine Learning Lab 随着近几年的大力发展,PyTorch逐 ...

  • 【杂谈】一招,同时可视化18个开源框架的网络模型结构和权重

    深度学习开源框架众多,对于开发者来说其中有一个很硬的需求,就是模型结构和权重的可视化.使用过Caffe的同学都因为强大的Netscope可以离线修改实时可视化网络结构而暗爽,那其他的框架怎么样呢? 今 ...

  • 【杂谈】抽奖送5台GPU使用权限,有三AI季划成员专属GPU也安排上了

    5台24G显存的GPU 本次免费的GPU来自于我们的老牌合作伙伴FlyAI,很多同学应该都知道,也在里面打过榜赢过钱,有三AI与FlyAI还一起举办过比赛,这是一个有奖竞赛社区. 如果不清楚FlyAI ...

  • tensorflow使用自制MNIST数据集训练识别LCD数字模型

    项目背景 最近老师需要我识别LCD数显仪表的数字,我首先想到的是采用类似车牌分割的办法,先把数字分割出来,再采用神经网络识别数字. 为什么不直接将整个LCD图片放进一个网络识别? 因为如果这样做的话需 ...

  • 模型部署翻车记:pytorch转onnx踩坑实录

    作者丨nihate 审稿丨邓富城 编辑丨极市平台 极市导读 本文记录了作者在深度学习模型部署是,从pytorch转换onnx的过程中的踩坑记录. >>加入极市CV技术交流群,走在计算机视觉 ...

  • 2021最新整理Java教程:Java 智能卡迷你计算器

    介绍 本文是关于编写基于Java智能卡的应用程序.本教程将帮助初学者理解Java智能卡和主机应用程序之间的概念和通信.我已经看到Java智能卡技术的初学者提出了一些简单的问题,所以我决定为他们提供一个 ...

  • Java教程:Java Boolean类

    Boolean类将基本类型为boolean的值包装在一个对象中.一个Boolean类的对象只包含一个类型为boolean的字段.此外,此类还为boolean和String的相互转换提供了很多方法,并提 ...

  • Java教程:Java Byte类

    Byte类将基本类型为byte的值包装在一个对象中.一个Byte类的对象只包含一个类型为byte的字段.此外,该类还为byte和String的相互转换提供了方法,并提供了一些处理byte时非常有用的常 ...

  • Java教程- Java中hashCode与equals方法

    如何在父类中为子类自动完成hashCode和equals实现,这么做有什么优劣?说一下Object类中hashCode与equals方法的理解,在什么场景下需要实现这两个方法? 有没有可能两个不相等的 ...

  • idea 快速删除代码中的空行丶Java教程网

    有的时候,队友拒绝使用 Git 这里版本管理工具,而且 Mac 与 Windows 或者不同的 IDE 的关系,总是有时候队友编辑后端的文档就会出现很多空行.这个时候不想理他的话可以自己使用 正则 查 ...

  • 中级Java教程面试题

    对java面试而言,面试前的准备一定要有面试题收集和学习这一项,因为在招聘公司看来,对java工程师职位的最大关注就是专业知识和技能水平的考察,所以程序员去公司面试,无论怎样都要先做一套面试题.对于不 ...

  • Java教程——LinkedHashMap源码分析

    大多企业级项目开发都会选择Java,这使得我们Java工程师们都是"全能型"人才,这使得项目经验成为了Java人面试的重头戏之一. 简介 LinkedHashMap内部维护了一个双 ...

  • Java教程的基础语法大汇总

    一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作.下面简要介绍下类.对象.方法和实例变量的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的 ...

  • Java基础教程:Java的对象和类

    Java是一种面向对象的编程语言,那什么是对象,什么是类,又怎么使用呢? 什么是对象 客观存在的事物皆为对象,所以我们也常常说万物皆对象.换作Java语言,对象是一种类的实例.相当于现实生活中加一个量 ...