文章目录

前言

正文

  • 1-1 使用tflite如何移植
  • 1-2 转换格式
  • 1-3 安卓运行环境配置
  • 2 使用pb
  • 小结

前言

因为业务需要最近开始做tensorflow的移植工作了,一通下来发现有坑无数,萌新表示只能顺着大佬们的步伐前进。

正文

1-1 使用tflite如何移植

tensorflow官方提供了对移动端的支持。tf lite

https://tensorflow.google.cn/lite/guide

Android有face id的权限吗_解决方案

由两个模块组成:

tflite解释器和tflite转换器。

通过转换器将我们的模型转换为tflite支持的指定格式,再由解释器在各端运行即可。

1-2 转换格式

Android有face id的权限吗_java_02

这里告诉我们格式转换的好处,和一些注意事项:可以优化模型大小,利用一些折衷的办法对移动端的执行进行优化。 当然,不是所有模型可以被转换,这个我们后面再看

Android有face id的权限吗_解决方案_03

这里提供了转换器的使用方式,正好是用python的api。

总共三个步骤:获取模型,转换,最后保存为tflite格式。问题收集:

1)module ‘tensorflow’ has no attribute ‘lite’

我的tf版本是1.11,去官网查下api

Android有face id的权限吗_解决方案_04

发现是1.14版本,于是用conda搭建个1.14版的环境出来,运行,果然有第二个错误2)SavedModel file does not exist at : xxx/{saved_model.pbtxt|saved_model.pb}

这个肯定跟输入的格式有关,再查一下,其支持以下几种输入模型

Android有face id的权限吗_解决方案_05

目前还不知道这些不同的模型有啥区别,不过我提供了模型路径,后提示没有pbtxt或者pb格式的文件。这个pb文件很眼熟,facenet预训练模型中会有,不过我的再训练模型中没有。

经过一阵实验过程, 最终在这里找到的解决方案,成功生成了.tflite文件https://xbuba.com/questions/53596521

1-3 安卓运行环境配置

继续参考官方文档https://tensorflow.google.cn/lite/guide/android 1)添加对tensorflow-lite的依赖,顺便加上gpu依赖

dependencies {
    implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly'
    implementation 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly'
}

2)对ndk进行配置

android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
    }
    //set no compress models
    aaptOptions {
        noCompress "tflite"
    }
}

貌似其他的没找着,参考下别人写的

3)在main目录下创建assets文件夹,这个文件夹主要是存放tflite模型和label名称文件。把刚才转好的.tflite文件丢进来

4)编写调用代码

在java中进行调用

try (Interpreter interpreter = new Interpreter(tensorflow_lite_model_file)) {
  interpreter.run(input, output);
}
//gpu版
GpuDelegate delegate = new GpuDelegate();
Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
Interpreter interpreter = new Interpreter(tensorflow_lite_model_file, options);
try {
  interpreter.run(input, output);
}

问题收集: 1)如果碰到安卓bitmap读取为空,八成是权限问题,7.0系统以上需要动态获取权限 2)如果碰到assets读取不到模型时,八成是模型被压缩了,也就是配置的时候是不是忘了将noCompress那段放进去了。 3)java.lang.IllegalArgumentException: Cannot convert between a TensorFlowLite tensor with type UINT8 and a Java object of type [F (which is compatible with the TensorFlowLite type FLOAT32).

这个问题是因为在做tflite_convert的时候,我们将inference_type和inference_input_type设置为QUANTIZED_UNIT8, 为了顺利的跑起来,先把inference_type和inference_input_type改回FLOAT。至于返回是(1,512)的张量这种小问题相信都可以解决了。

2 使用pb

facenet源代码中自带了src/freeze_grapy.py ,可以使用它来生成pb文件,如果在安卓中调用的时候发生如下问题: Not a valid TensorFlow Graph serialization: NodeDef mentions attr ‘explicit_paddings’ not in… 解决方案是,你的python版tensorflow版本号,必须和安卓中使用的一致

在左侧Project模式下External Libraries中查询安卓中的版本

Android有face id的权限吗_解决方案_06

小结

最终是跑出来了,效果咋样等待测试,不过一下子没办法测试,以后补回测试结果。这还只是个facenet,还有mtcnn也需要移植。还有inference_type和inference_input_type设置为QUANTIZED_UNIT8可以对模型进行压缩,但是后面该怎么对上类型呢? 太多问题。时间太紧,后面再慢慢填坑。