avatar GDYSHI

gdyshi 的个人博客

  • 首页
  • 子域
  • 分类
  • 标签
  • 归档
  • 关于
首页 tensorflow模型部署系列————单机java部署
文章

tensorflow模型部署系列————单机java部署

发表于 2019/07/01
作者 gdyshi
10 分钟阅读
tensorflow模型部署系列————单机java部署
tensorflow模型部署系列————单机java部署
  • 摘要
  • 引言
  • 主题
    • 实现方案选择
    • 官方java库
      • 安装
      • API讲解
      • java部署代码
        • 模型封装库
        • 模型封装类示例代码
    • 自定义jni封装接口
      • jni接口封装
      • java部署代码
        • 模型封装库
        • 模型封装类示例代码
  • 示例代码
  • 附录
  • 参考

摘要

本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的部署。本文主要实现用JAVA接口调用tensorflow模型进行推理。相关源码见链接


引言

本文为系列博客tensorflow模型部署系列的一部分,用于JAVA语言实现通用模型的部署。本文主要使用pb格式的模型文件,其它格式的模型文件请先进行格式转换,参考tensorflow模型部署系列————预训练模型导出。从模型文件中获取输入输出op名请参考博客tensorflow模型部署系列————单机python部署

主题

上一篇博文tensorflow模型部署系列————单机C++部署就如何使用C/C++语言加载模型文件并利用模型文件进行推理进行讲解,博文中也开放了使用python进行模型推理的代码,本文参照python模型部署代码进行C++模型部署。

实现方案选择

有两种方案可以做tensorflow的java部署

  • 直接使用tensorflow官方提供的java库。优点是可直接近乎无脑使用,这里是tensorflow java库官方安装指南。缺点是它目前是google的实验性API,后续的更改不保证向后兼容,基于此库的应用代码可能需要重写。
  • 在上一篇博文tensorflow模型部署系列————单机C++部署基础上加入jni接口。这一块只是对C接口的封装,优点是tensorflow模型部署系列————单机C++部署封装用的C库属于tensorflow api稳定性保障范围内,可以简单的更新到新的tensorflow中。缺点是需要自己做C和java之间的接口封装。下面分别针对这两种方式分别进行介绍

官方java库

安装

进入网页下载jar包和jni文件,目前已编译的jni支持linux-x86 windows-x86 macOS, arm处理器并不支持,需要自行编译。关于tensorflow源码编译过程请关注我的博客,后续会有专门博文讲解

API讲解

tensorflow的java接口详见官方文档。这里针对常用接口做一个说明,并跟将JAVA接口与tensorflow模型部署系列————单机python部署](https://blog.csdn.net/chongtong/article/details/90693787)中的python代码进行对应,以便于读者更好地理解接口

  • 创建图,直接使用java封装类Graph即可

    1
    
    Graph graph = new Graph()
    
  • 加载模型文件,对应python代码tensors = tf.import_graph_def(output_graph_def, name="")

    1
    
    graph.importGraphDef()
    
  • 创建session,直接使用java封装类Graph即可,对应python代码self.__sess = tf.Session()

    1
    
    Session session = new Session(graph)
    
  • 获取输入输出OP,对应python代码self.__input = graph.get_tensor_by_name("input:0")

    op名称的获取方式见tensorflow模型部署系列————单机python部署。

    1
    
    java代码直接使用op名称作为参数即可
    
  • 张量填充,无对应python代码,python可直接赋值

    java需创建Tensor,在创建的同时进行数据填充

    1
    
    Tensor<T> input = Tensor.create()
    
  • 运行OP,对应python代码output = self.__sess.run(self.__output, feed_dict={self.__input: input})

    使用session.runner().run()运行session

    1
    2
    3
    4
    5
    6
    
    tenss= session.runner().feed("sequential_1_input", input).fetch("output/Softmax").run()
     其中
     runner()用于获取运行对象
     feed()用于填充输入占位符
     fetch()用于指定需获取的tensor
     run()用于运行session
    
  • 获取张量值,无对应python代码,因python可直接获取

    op运行完毕后就可以通过TF_TensorData找到张量的数据缓冲区地址,并获取输出数据了

    1
    2
    3
    4
    
    Tensor<Float> output = tenss.get(0).expect(Float.class)
    其中
    get()用于获取运行后的张量值
    expect()作用为类型检查
    

java部署代码

模型封装库

模型封装类主要包括两个方法:初始化和推理。

初始化只用于处理与sess.run无关的所有操作,以减少推理时的操作,保证模型推理高效运行。初始化主要进行的操作包括:模型文件加载、获取计算图和计算session。

推理主要进行的操作有:输入张量填充、sesson.run、和输出张量获取。从模型文件中获取输入输出op名请参考博客tensorflow模型部署系列————单机python部署

模型封装类示例代码

经过模型封装类封装以后,示例代码就很简单了。只用准备数据,然后推理就行了。

自定义jni封装接口

jni接口封装

jni接口封装我参考android ndk开发包中的工具源码,并在此基础上做了部分修改。

jni接口封装将上一篇博文tensorflow模型部署系列————单机C++部署的封装库接口包装成jni接口。参考android ndk开发包中的工具源码将需要包装的接口函数放进如下数组中

1
2
3
4
5
static JNINativeMethod gjniDiagnoseMethods[] = {
{(char *)"model_init",          (char *)"(Ljava/lang/String;)I",            (void *) jni_model_init},        
{(char *)"model_deinit",        (char *)"()I",                              (void *) jni_model_deinit},        
{(char *)"model_inference",     (char *)"(I[F[F)I",                         (void *) jni_model_inference},
};

然后定义调用此jni接口的类名#define JNI_ADAPTER_CLASS "JavaModel"即可

java部署代码

模型封装库

模型封装类主要包括三个方法:初始化、去初始化和推理。

初始化只用于处理与sess.run无关的所有操作,以减少推理时的操作,保证模型推理高效运行。初始化主要进行的操作包括:模型文件加载、获取计算图和计算session、根据输入输出tensor名称获取输入输出tensor。从模型文件中获取输入输出op名请参考博客tensorflow模型部署系列————单机python部署

推理主要进行的操作有:数据类型转换、输入张量填充、sesson.run、和输出张量获取

去初始化用于释放资源,这一块是python所没有的。主要操作包括:session的关闭和释放、计算图的释放

模型封装类示例代码

经过模型封装类封装以后,示例代码就很简单了。只用准备数据,然后推理就行了。

示例代码

  • 使用官方java库进行模型部署代码

    • 官方java接口的模型封装类代码
    • 官方java接口的示例代码
    • tf模型封装库代码
    • tf模型封装库示例代码
    • 编译及运行方法
  • 自定义jni封装接口进行模型部署代码

    • jni接口封装C代码
    • jni接口封装工具代码
    • jni接口封装java代码
    • tf模型封装库java示例代码
    • 编译脚本
    • 编译及运行方法

附录

参考


  • tensorflow 官方 java库安装教程
  • tensorflow 官方 java接口文档
tensorflow
tensorflow keras 模型部署 java 神经网络
本文由作者按照 CC BY 4.0 进行授权
分享

最近更新

  • paho.mqtt.embedded掉线问题记录
  • tensorflow模型部署系列————TensorFlow Serving部署
  • tensorflow模型部署系列————独立简单服务器部署
  • tensorflow模型部署系列————浏览器前端部署
  • tensorflow模型部署系列————独立简单服务器部署
外部链接
  • 996.icu
  •  此博客的 Github 仓库
  •  GDYSHI 的个人博客

文章内容

相关文章

2019/07/10

tensorflow模型部署系列————嵌入式部署

摘要 引言 主题 tflite介绍 应用场景 模型文件转换 从session转换 从pb文件转换 python部署 安装 API讲...

2019/06/14

tensorflow模型部署系列————单机C++部署

摘要 引言 主题 C库介绍 获取库文件 API讲解 C++部署代码 tensorflow库接口封装 模型封装库 模型封装类示例代码 示例代...

2019/05/30

tensorflow模型部署系列————单机python部署

摘要 引言 主题 查看已保存模型的结构 keras模型文件 pb模型文件 查看已保存模型的输入和输出 通过tensorboard图查看 通过代码查看 python部署...

tensorflow模型部署系列————单机C++部署

tensorflow模型部署系列————嵌入式部署

© 2025 gdyshi. 保留部分权利。

本站采用 Jekyll 主题 Chirpy

热门标签

tensorflow keras 模型部署 神经网络 机器学习 flask python 服务器 译文 人脸识别

发现新版本的内容。