Android TensorFlow

用TensorFlow在Android使用WaveNet,重写成Java,Python模块,从音频中提取特征。

根据用户口音训练”ok Google”,当听到“ok Google”时,激活用户手机。这可以应用于智能家居上,而不连接互联网。


使用训练好的WaveNet model在Android上使用TensorFlow。

这里写图片描述

在Android上使用WaveNet,整个过程分为3步。


开发环境

  • 手机:Pixel, CPU: ARM64
  • Android 7.1
  • Android NDK 15.2
  • Android gradle plugin 2.3.0
  • TensorFlow 1.3.0
  • bazel 0.5.4 - homebrew

TensorFlow on mobile with speech-to-text DL models

第一步:模型压缩

为了在手机/嵌入式设备上使用深度学习模型,我们必须减少模型对内存的占用,减小推理时间和尽量减少耗电。有好几种方法可以处理这些问题,比如量化,权重裁剪、将大模型变成小模型。

在这里使用TensorFlow量化工具对模型进行压缩。只用权重量化减小模型,Eight-bit Calculations并没有办法减少推理时间。Eight-bit Calculations 并没有针对CPU进行优化。如果你对这个话题感兴趣,可以参考这里

为了对模型量化权重:

  • 将模型改成protocol buffer文件
  • 从源文件安装,构建tensorflow
  • 在tensorflow目录下执行如下命令

bazel build tensorflow/tools/graph_transforms:transform_graph
bazel-bin/tensorflow/tools/graph_transforms/transform_graph \
–in_graph=/your/.pb/file \
–outputs=”output_node_name” \
–out_graph=/the/quantized/.pb/file \
–transforms=’quantize_weights’

量化后,预训练的WaveNet模型从15.5MB降到4.0MB。把模型文件放到Android项目的assets文件夹下。

第二步:给Android添加TensorFlow 库

用tensorflow构建Android应用程序,可以先学习TensorFlow Android Demo。这个例子中使用 TF speech example作为模板。例子中的gradle file可以用来构建和编译Android TF库。但这个预编译的TF库并不包括我们模型所有必要的操作,需要列出WaveNet需要的操作,编译成.so文件,做成Android APK。

为了找到这些操作,先用tf.train.write_graph输出图细节,再在命令行下运行以下命令

grep “op: ” PATH/TO/mygraph.txt | sort | uniq | sed -E ‘s/^.+”(.+)”.?$/\1/g’

接下来,编辑/tensorflow/tensorflow/core/kernels/下的BUILD文件,添加操作到Android库的 ‘android_extended_ops_group1’ 或 ‘android_extended_ops_group2’ 中。删掉不需要的操作,可以使.so文件更小。

然后,运行:

bazel build -c opt //tensorflow/contrib/android:libtensorflow_inference.so \
–crosstool_top=//external:android/crosstool \
–host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
–cpu=armeabi-v7a

这样就可以找到 libtensorflow_inference.so 文件:

bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so

除了.so文件,还需要一个JAR 文件

运行:

bazel build
//tensorflow/contrib/android:android_tensorflow_inference_java

就可以找到文件:

bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar

把.so和.jar文件放到Android项目的libs文件夹里。

第三步: Android 数据预处理

最后,要降输入数据处理成训练好的模型的格式。对音频系统,原始语音转换成 Mel Frequency Cepstral Coefficients (MFCC),这样人耳才能听到。TensorFlow可以对音频处理,提取特征。在执行这个会话的时候,有几个变量,如图2,TensorFlow 音频处理的MFCC和librosa处理不一样,预训练WaveNet的python库可以做这种训练格式的转换。

这里写图片描述

MFCC from librosa and TensorFlow audio ops are at different scales.

如果要训练自己的模型或是使用一个训练好的模型,预处理训练数据的时候,要考虑设备上的数据流程。这里把librosa MFCC用Java进行了重写。

效果

下图是最后APP的效果,这里模型没有语言模型,识别是用文字,可以看到有的字是写错了。尽管没有严谨的测试,还是可以看到权重量化后,精度有些降低,系统对周围噪声比较敏感。

这里写图片描述

推理时间如下:
权重量化可以帮助减小文件大小,但对推理时间和功耗没有太大影响。

这里写图片描述

Inference time before and after weights quantization. Tested with my Pixel phone and Macbook air.

后续工作

  • 添加语言模型防止拼写错误
  • 添加噪声降采样模型减小环境噪声的影响
  • 加快推理时间,减小功耗:使用NEON优化,用gemmlowp进行低精度矩阵运算
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐