我的目的是实现一个二分类的手机分类器(多分类同理),网上关于移动端实现MobileNet的教程有一大堆,这里推荐一个比较典型的博客。之所以还写一个教程,是因为网上搜索到的都是基于TensorFlow MobileNet官方代码实现的(据说这种方法在2019年已经被停止维护了)。于是,我跟随着上面博客的脚步准备数据(数据准备按上面博客就行了),试图跟着大佬一路走到黑,直到找到了官代上的tensorflow/examples/image_retraining/retrain.py。然而当我信心满满点开代码时,发现该代码已被弃用,请转到新地址,如下图。emmmmmm...只能跟着更新后的官方教程来了,从此开启了踩坑之路。

第一步:直接访问自定义训练的新代码,这个代码是用来替换原来的retrain.py(tensorflow/examples/image_retraining/)的,原始的retrain.py是用TensorFlow1.X版本写的,本人是没跑起来,于是看起了新代码。根据新代码中的README,要求使用TensorFlow2.X版本(推荐直接安装GPU版),还需要安装一个tensorflow-hub,终端命令如下(我习惯用pip3)
$ pip3 install "tensorflow-gpu~=2.0"
$ pip3 install "tensorflow-hub[make_image_classifier]~=0.6"安装之后可以检查一下,终端输入pip3 list,会找到tensorflow-gpu和tensorflow-hub,如图
![]()
第二步:用自己的数据训练MobileNet。跟着官方教程来,直接开终端输入以下命令(不需要进入make_image_classifier.py所在文件夹):
$ make_image_classifier \
--image_dir my_image dir \
--tfhub_module https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4 \
--image_size 224 \
--saved_model_dir my_dir/new_model \
--labels_output_file class_labels.txt \
--tflite_output_file new_mobile_model.tflite--image_dir 数据集所在文件夹路径
--tfhub_module 这是个外网地址,需要翻墙才能访问。如果能翻墙,直接写上面的网址就可以了(注意查看mobilenet对应版本)。Ubuntu翻墙我失败了,于是在Windows上访问,会下载一个压缩包包含下面这些东西,用解压后的文件夹路径替换上述网址即可

--image_size 关于输入图像的尺寸请参考上面的博客
--saved_model_dir 用来保存结果的文件夹路径
--labels_output_file 代码会自动生成一个.txt文件,里面包含了你数据集的所有分类,给出一个以.txt结尾的路径即可
--tflite_output_file 代码会自动生成一个.tflite文件,给出一个以.tflite结尾的路径即可
第三步:开始训练自定义数据集的mobilenet模型,训练过程如图

所有epoch结束后会生成下图文件,后面会用到的是class_labels.txt和new_mobile_model.tflite

第四步:转移到Android端。需要安装Android Studio和配套的JKD、SDK、NDK等,请自行搜索安装教程。安装完成后回到一开始的tensorflow代码。找到/tensorflow/tensorflow/lite/java/demo文件夹,直接用Android Studio打开demo。Android Studio会自动下载各种依赖包,很多用的都是外网,会造成等待超时的错误,因此要先把下载源图换成`替换成阿里源。找到build.gradle文件,在下图的两个位置加上一句话
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
修改build文件后,IDE会自动提示下图,点击Sync Now就可以了(没有的话直接重启Android Studio)

下载完成后会提示下图

在工具栏上找到并点击Build-->Make Project,进行程序编译,成功后如下图

编译成功后开始进行运行前的重要准备。首先找到tensorflow/tensorflow/lite/java/demo/app/src/main/assets文件夹,将之前训练得到的class_labels.txt和new_mobile_model.tflite文件拷贝到该文件夹下,如图

然后找到/tensorflow/tensorflow/lite/java/demo/app/build.gradle文件,如图。注意!!!此时的build文件是在app目录下的,刚才修改阿里源的build文件是在demo目录下的,这两个build文件不是同一个文件!!!

打开该文件,找到下图位置,从62行到最后全部注释掉。原因是63-66行是在下载官方示例代码中提供的mobilenet权重,而且每次打开项目都会自动下载(需要访问外网)。然而我们的目的是用自己训练好的权重文件替换原始的示例权重,因此直接注释掉即可,再点击右上角的Sync Now

将手机通过数据线连接在电脑上,且必须打开手机的开发者模式
最后一步!!!!!!找到demo/app/src/main/java/com/example/android/tflitecamerademo/ImageClassifierFloatMobileNet.java文件,如下图位置,将50和54行都替换成刚刚拷贝到assets下的文件名,ImageClassifierFloatInception和ImageClassifierQuantizedMobileNet文件中的相应位置不要进行改动,否则会造成手机端app闪退(具体原因不清楚),最后点击Run-->Run 'app'即可

运行时手机端会有安装响应,直接安装即可。结果如下图,第一张图是示例代码的结果(在ImageNet上训练的1000分类),第二张图是我自定义数据集的结果(Complete和Others)两个分类。手机分类器的部署到此圆满结束,以上步骤建议完成时长3天。

