将TensorFlow训练好的模型迁移到Android APP上(TensorFlowLite)

2023-05-16

将TensorFlow训练好的模型迁移到Android APP上(TensorFlowLite)

1. 写在前面

  最近在做一个数字手势识别的APP(关于这个项目,我会再写一篇博客仔细介绍,博客地址:一步步做一个数字手势识别APP,源代码已经开源在github上,地址:Chinese-number-gestures-recognition),要把在PC端训练好的模型放到Android APP上,调研了下,谷歌发布了TensorFlow Lite可以把TensorFlow训练好的模型迁移到Android APP上,百度也发布了移动端深度学习框架mobile-deep-learning(MDL),这个框架应该是paddlepaddle的手机版,具体的细节没有了解过。因为对TensorFlow稍微熟悉些,因此就决定用TensorFlow来做。
  关于在PC端如何处理数据及训练模型,请参见博客:一步步做一个数字手势识别APP,代码已经开源在github上,上面有代码的说明和APP演示。这篇博客只介绍如何把TensorFlow训练好的模型迁移到Android Studio上进行APP的开发。

2. 模型训练注意事项

  第一步,首先在pc端训练模型的时候要模型保存为.pb模型,在保存的时候有一点非常非常重要,就是你待会再Android studio是使用这个模型用到哪个参数,那么你在保存pb模型的时候就把给哪个参数一个名字,再保存。否则,你在Android studio中很难拿出这个参数,因为TensorFlow Lite的fetch()函数是根据保存在pb模型中的名字去寻找这个参数的。(如果你已经训练好了模型,并且没有给参数名字,且你不想再训练模型了,那么你可以尝试下面的方法去找到你需要使用的变量的默认名字,见下面的代码):

#输出保存的模型中参数名字及对应的值
with tf.gfile.GFile('model_50_200_c3//./digital_gesture.pb', "rb") as f:  #读取模型数据
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read()) #得到模型中的计算图和数据
with tf.Graph().as_default() as graph:  # 这里的Graph()要有括号,不然会报TypeError
    tf.import_graph_def(graph_def, name="")  #导入模型中的图到现在这个新的计算图中,不指定名字的话默认是 import
    for op in graph.get_operations():  # 打印出图中的节点信息
        print(op.name, op.values())

这段代码打出的变量的名字以及对应的值。

言归正传,通常情况该你应该保存参数的时候都给参数一个指定的名字,如下面这样(通过name参数给变量指定名字),关于训练CNN的完整代码请参见下一篇博客或者github:

X = tf.placeholder(tf.float32, [None, 64, 64, 3], name="input_x")
y = tf.placeholder(tf.float32, [None, 11], name="input_y")
kp = tf.placeholder_with_default(1.0, shape=(), name="keep_prob")
lam = tf.placeholder(tf.float32, name="lamda")
#中间略过若干代码
z_fc2 = tf.add(tf.matmul(z_fc1_drop, W_fc2),b_fc2, name="outlayer")
prob = tf.nn.softmax(z_fc2, name="probability")
pred = tf.argmax(prob, 1, output_type="int32", name="predict")
3. 在Android Studio中配置

  第二步,开始把pb模型移植到Android Studio上,网上绝大部分资料都是说用bazel重新编译模型生成依赖,这种方法难度太大。其实没必须这样做,TensorFlow Lite官方的例子中已经给我们展示了,我们其实只需要两个文件:libandroid_tensorflow_inference_java.jar 和 libtensorflow_inference.so。这两个文件我已经放到github上了,大家可以自行下载使用,下载地址:libandroid_tensorflow_inference_java.jar、libtensorflow_inference.so。

注:检神说,直接用aar依赖也可以,这个我没试过。。有兴趣的可以试一下。

准备工作已经完毕,下面正式开始Android Studio中的配置。

  首先把训练好的pb模型放到Android项目中app/src/main/assets下,若不存在assets目录,则自己新建一个。如图所示:

pb模型目录

  其次,把刚刚下载的 libandroid_tensorflow_inference_java.jar 文件放到 app/libs 目下,把libtensorflow_inference.so 放到 app/libs/armeabi-v7a 目录下,如下图所示:

TensorFlow依赖目录

然后在app/build.gradle里进行如下配置:
  在defaultConfig里添加

multiDexEnabled true
        ndk {
            abiFilters "armeabi-v7a"
        }

  在android里添加

 sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['libs']
        }
    }

如图所示:

配置文件

  在dependencies中添加libandroid_tensorflow_inference_java.jar,即:

implementation files('libs/libandroid_tensorflow_inference_java.jar')

如图所示:

dependencies

至此,所有配置已经完成,下面是模型调用。

4. 在Android Studio中调用模型

在要用到模型的地方,首先要加载libtensorflow_inference.so库和初始化TensorFlowInferenceInterface对象,代码为:

TensorFlowInferenceInterface inferenceInterface;

    static {
        //加载libtensorflow_inference.so库文件
        System.loadLibrary("tensorflow_inference");
        Log.e("tensorflow","libtensorflow_inference.so库加载成功");
    }
    Classifier(AssetManager assetManager, String modePath) {
        //初始化TensorFlowInferenceInterface对象
        inferenceInterface = new TensorFlowInferenceInterface(assetManager,modePath);
        Log.e("tf","TensoFlow模型文件加载成功");
    }

如图所示:

加载TensorFlow依赖库

下面来多看一点东西,看看TensorFlow Lite里提供了哪几个接口,官网地址:Here’s what a typical Inference Library sequence looks like on Android.

// Load the model from disk.
TensorFlowInferenceInterface inferenceInterface =
new TensorFlowInferenceInterface(assetManager, modelFilename);

// Copy the input data into TensorFlow.
inferenceInterface.feed(inputName, floatValues, 1, inputSize, inputSize, 3);

// Run the inference call.
inferenceInterface.run(outputNames, logStats);

// Copy the output Tensor back into the output array.
inferenceInterface.fetch(outputName, outputs);

下面就可以愉快地使用模型了。放一段我调用模型的代码,以供大家参考:

public ArrayList predict(Bitmap bitmap)
    {
        ArrayList<String> list = new ArrayList<>();
        float[] inputdata = getPixels(bitmap);
        for(int i = 0; i <30; ++i)
        {
            Log.d("matrix",inputdata[i] + "");
        }
        inferenceInterface.feed(inputName, inputdata, 1, IMAGE_SIZE, IMAGE_SIZE, 3);
        //运行模型,run的参数必须是String[]类型
        String[] outputNames = new String[]{outputName,probabilityName,outlayerName};
        inferenceInterface.run(outputNames);
        //获取结果
        int[] labels = new int[1];
        inferenceInterface.fetch(outputName,labels);
        int label = labels[0];
        float[] prob = new float[11];
        inferenceInterface.fetch(probabilityName, prob);
//        float[] outlayer = new float[11];
//        inferenceInterface.fetch(outlayerName, outlayer);

//        for(int i = 0; i <11; ++i)
//        {
//            Log.d("matrix",outlayer[i] + "");
//        }
        for(int i = 0; i <11; ++i)
        {
            Log.d("matrix",prob[i] + "");
        }
        DecimalFormat df = new DecimalFormat("0.000000");
        float label_prob = prob[label];
        //返回值
        list.add(Integer.toString(label));
        list.add(df.format(label_prob));

        return list;
    }

最后放一张做的数字手势识别APP的效果,全部代码,将会开源在github上,欢迎star。

识别结果

再放一张碰运气的识别结果:

碰巧识别

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将TensorFlow训练好的模型迁移到Android APP上(TensorFlowLite) 的相关文章

随机推荐

  • 希尔排序算法

    本章介绍排序算法中的希尔排序 内容包括 xff1a 1 希尔排序介绍 2 希尔排序图文说明 3 希尔排序的时间复杂度和稳定性 4 希尔排序实现 4 1 希尔排序C实现 4 2 希尔排序C 43 43 实现 4 3 希尔排序Java实现 转载
  • 归并排序算法

    概要 本章介绍排序算法中的归并排序 内容包括 xff1a 1 归并排序介绍 2 归并排序图文说明 3 归并排序的时间复杂度和稳定性 4 归并排序实现 4 1 归并排序C实现 4 2 归并排序C 43 43 实现 4 3 归并排序Java实现
  • 拓扑排序算法

    拓扑排序介绍 拓扑排序 Topological Order 是指 xff0c 将一个有向无环图 Directed Acyclic Graph简称DAG 进行排序进而得到一个有序的线性序列 这样说 xff0c 可能理解起来比较抽象 下面通过简
  • 线性时不变系统输出调节问题

    线性时不变系统输出调节问题 最近在学习 Nonlinear output regulation 中的linear output regulation时 xff0c 对于linear robust output regulation的问题时
  • MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本

    MinGW w64安装教程 著名C C 43 43 编译器GCC的Windows版本 MinGW w64安装教程 著名C C 43 43 编译器GCC的Windows版本 本文主要讲述如何安装 C语言 编译器 MinGW w64 xff0c
  • RT-Thread实时操作系统简介

    目录 一 概述 二 架构 三 版本选择 四 内核启动流程 五 自动初始化机制 六 内核对象模型 七 I O设备模型 1 框架 2 设备驱动使用序列图 3 设备类型 八 FinSH控制台 九 ENV工具 1 menuconfig 2 Scon
  • PCIe RAS

    对于Linux系统针对RAS的AER错误处理机制完成 PCIe RAS简单来讲就是PCIe的错误检测 纠正以及汇报的机制 它可以方便我们准确的定位 xff0c 纠正和分析错误增强系统的健壮性和可靠性 PCIe错误的分类 PCIe错误分为可校
  • Linux下的regulator调试

    先看regulator使用的小demo 如 i2c8 touchscreen 64 28 vddcama supply 61 lt amp xxxxx gt int ret struct regulator power static int
  • 关于添加系统调用遇到 Unable to handle kernel paging request at virtual address 的解决

    Unable to handle kernel paging request at virtual address 是内存访问异常的错误 xff0c 原因通常有三种 xff1a virtual address 为 0x00000000 时
  • vscode安装配置clang-format插件及使用

    vscode安装配置clang format插件及使用 首先安装插件 在vscode扩展里搜索clang format xff0c 安装排名第一的xaver clang format 确认clang format可执行程序路径 window
  • 简历中项目描述怎么写啊

    http wenda tianya cn question 7ade6dc9324bed88
  • 树莓派(Raspberry Pi 3) - 系统烧录及系统使用

    树莓派 xff08 Raspberry pi xff09 是一块集成度极高的ARM开发板 xff0c 不仅包含了HDMI xff0c RCA xff0c CSI xff0c HDMI xff0c GPIO等端口 xff0c 还支持蓝牙以及无
  • flashcache原理

    介绍flashcache的文章很多 xff0c 我就不废话了 使用上 xff0c 有余峰老哥的 文章 xff1b 原理上 xff0c 有ningoo同学的 flashcache系列 但是ningoo同学漏掉了device mapper和fl
  • 无人机算法之PID

    xff08 未完成 xff09 一 PID介绍 xff08 百度百科 xff09 PID 控制器 xff08 比例 积分 微分控制器 xff09 是一个在工业控制应用中常见的反馈回路部件 xff0c 由比例单元 P 积分单元 I 和微分单元
  • java:接口、lambda表达式与内部类

    接口 xff08 interface 接口用来描述类应该做什么 xff0c 而不指定他们具体应该如何做 接口不是类 xff0c 而是对符合这个接口的类的一组需求 接口定义的关键词是interface span class token key
  • 卫星系统算法课程设计 - 第二部分 qt的安装与创建项目

    上一篇文章只讲了基本的东西 xff0c 这一篇要完成qt的安装 xff0c 构建项目 xff0c 并且将上一篇的代码导入进去 某比利比例搜qt安装 xff0c 看到qt5 14 2的下载安装 xff0c 跟着做 1 创建项目 创建新项目 x
  • 无人机-材料准备

    xff08 未完成 xff09 一 使用空心杯电机 xff0c 型号8520 xff0c 1S版本 xff0c 约5G每只 二 空心杯机架 xff0c 型号QX90 xff0c 约8 5g 三 使用55MM桨 四 1S 600MA电池 五
  • CMake中链接库的顺序问题

    原文链接 xff1a https blog csdn net lifemap article details 7586363 cmake中链接库的顺序是a依赖b xff0c 那么b放在a的后面 例如进程test依赖a库 b库 a库又依赖b
  • 鸿蒙wifi Demo运行

    title 鸿蒙Wi Fi Demo运行 date 2021 1 1 22 25 10 categories harmony 本文首发于LHM s notes 欢迎关注我的博客 坑有点多 由于之前没有看过wifi的内核态代码 xff0c 所
  • 将TensorFlow训练好的模型迁移到Android APP上(TensorFlowLite)

    将TensorFlow训练好的模型迁移到Android APP上 xff08 TensorFlowLite xff09 1 写在前面 最近在做一个数字手势识别的APP xff08 关于这个项目 xff0c 我会再写一篇博客仔细介绍 xff0