本文来自AI新媒体量子位(QbitAI)

上周末,量子位翻译了一份MobileNet教程,其中讲述了怎样在一个新的数据集上重新训练MobileNet,那篇文章的成果,是一个分类器,能在电脑上以每秒钟400张的速度,识别图片是否为道路。

MobileNet是为移动端量身打造的,因此这次我们准备把之前做的辨别道路的模型应用到一个Android App中,看看它在移动设备上效果如何。

目标和计划

首先,让我们明确目标和计划,我们希望做到:

  • 在很小的特定数据上重新训练MobileNet;
  • 模型在hold out测试集(即模型训练前为测试留出的样本)上达到95%的准确率;
  • 程序运行时对300美元以下价位手机CPU的占用要小于5%。

为了达到这些目标,我们的计划是:

  1. 生成一个新的训练数据集;
  2. 训练多个MobileNet结构,从而寻找所能够达到准确率目标(95%)的最小型网络;
  3. 与在Android上运行的Inception V3做对比;
  4. 将TensorFlow上Android example App中的模型替换为我们的MobileNet;
  5. 大量的测试;
  6. 进行调试,从而将CPU的占用调到5%以下。

建立数据集

在前一篇推送中,我们为了辨认“道路/非道路”,从多个来源拉取了图片作为训练素材。

现在我们再来思考一下这样做是否有必要。

如果你记得的话,这个项目的目标是为了保护用户隐私,当车上的摄像头打开的时候,如果它看见的不是道路,就应该自动关掉。

所以,为了建立我们的训练数据集,我需要录制一些(跟驾驶相关)日常生活中的场景:比说我家的周围、我车子的外部,我在车上摆弄收音机、逗猫等等。这些会被当做非道路的数据用来训练模型。

 一些“非道路”的示例图片

而训练数据的“道路”部分,是从Coastline driving dataset中随机取出的,这些图片都是由车的前置摄像头拍摄的。

 一些“道路”的示例图片,注意这些图片中都有山坡,因此,为了防止模型把判断道路错认为判断山坡,我们需要对训练数据进行一些扩展。

为道路和非道路数据集各收集3000张图片后,下一步就是开始训练了。

用特定数据集训练MobileNet

下一步,是看看不同结构的MobileNet在经过训练后能达到什么样的准确度。

我们先从最“宽”的MobileNet开始训练:MobileNet 1.0 @ 128。 因为我们想把这个模型应用到移动设备上,因此我们将会采用权值量化,从而进一步减少内存占用。

关于重新训练MobileNet的操作细节,可以看我的前一篇推送。

在TensorFlow的根目录下,运行以下脚本:

python tensorflow/examples/image_retraining/retrain.py \--image_dir ~/ml/blogs/road-not-road/data/ \--learning_rate=0.0005 \--testing_percentage=15 \--validation_percentage=15 \--train_batch_size=32 \--validation_batch_size=-1 \--flip_left_right True \--random_scale=30 \--random_brightness=30 \--eval_step_interval=100 \--how_many_training_steps=1000 \--architecture mobilenet_1.0_128_quantized

在经历1000步的训练后,我们在测试集上达到了99.7%的准确率。

以下是模型做出了错误判断的一些图片:

 被错认为道路的非道路图片,我不得不说这种失误是可以接受的,这显然是路,但不是我们要的类型 。

 被错认为非道路的道路图片,我认为这是因为在训练集中没有出现桥架在道路上的图片,更多的训练数据能解决这个问题。

接下来让我们在最小的MobileNet上(0.25@128)训练,同样采用权值量化。在1000步训练后,我们达到了92.6%的正确率,没有达到我们的目标。

那么让它稍微变宽些呢,比如说0.5@128?

准确率达到了95%,最终的模型大小为1.6MB。值得一提的是我们训练模型只用了10分钟10fps的视频,所以在训练数据的收集上还有很大的提升空间。

接下来我们很快试一下看看模型是否能够如预计般工作:

python tensorflow/examples/label_image/label_image.py \ --graph=/tmp/output_graph.pb \--labels=/tmp/output_labels.txt \--image=/home/harvitronix/ml/blogs/road-not-road/test-image.jpg \--input_layer=input \--output_layer=final_result \--input_mean=128 \--input_std=128 \--input_width=128 \--input_height=128

 系统认为这张图片是道路的可能性为99.023%

这个系统速度很快,在我们搭载NVIDIA GeForce 960m GPU的笔记本上,识别1,000张图片只需要3.36秒,即每秒钟能识别297.6张图片。

把MobileNet应用到Android App中

现在我们拥有了一个小巧、快速、足够精确的模型,接下来我们准备把它搭载到一个Android App上,从而在真实环境中进行测试。

继续使用TensorFlow提供的工具,我们马上就会使用里面的Android示例项目完成模型的搭载。

1. 建立项目

如果你还没有准备好,可以从TensorFlow的repository下载这个Android示例项目:

git clone https://github.com/tensorflow/tensorflow.git --depth 1

具体的文件夹是tensorflow/examples/android。用Android Studio打开这个文件夹,编译,然后把生成的APK安装包搭载到你的手机上,你就得到了一个搭载着在ImageNet数据集上训练出的Inception V3模型的图像分类器App,它能够准确地把猫咪跟鸭嘴兽区分开来。

如果你编译apk安装包过程有问题,可以参考他们的readme文档中的指示。(https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android)

我遇到的最大的挑战是NDK(Native Developer Kit)的版本问题,降级到r12b版本后才能正常的编译。

2. 评测搭载了Inception的App

我们现在运行的app上搭载的是Inception模型,让我们它做一些测评,从而可以与之后的MobileNet模型比较。

搭载了Inception的这个app的大小是53.9Mb,而搭载MobileNet的只有1.6Mb。它能够以240ms的速度识别一张图片(即4fps),CPU的占用达到了40%。

 搭载Inception V3的App在4fps速度下运行时的CPU占用情况

让我们把运行速度调到1fps试试:

 搭载Inception V3的app在1fps速度下运行时的CPU占用情况

现在,内存的占用仍然在35%以上,让我们盼着MobileNet能够比这表现得好些,否则我们就达不到之前定下的目标了(内存占用上限为5%)。

3. 换成MobileNet

接下里让我们对这个Android project做一些小修改,从而搭载上我们的MobileNet。

首先,把你的模型和标签文件复制到project的assets文件夹里。我的是分别是/tmp/output_graph.pb 和 /tmp/output_labels.txt。

接下来,打开ClassifierActivity,具体地址是在:

tensorflow/examples/android/src/org/tensorflow/demo/ClassifierActivity.java

将这个文件中的开头部分中定义的参数设置为我们的新模型。即从一打开时的这样:

private static final int INPUT_SIZE = 224;
private static final int IMAGE_MEAN = 117;
private static final float IMAGE_STD = 1;
private static final String INPUT_NAME = "input";
private static final String OUTPUT_NAME = "output";private static final String MODEL_FILE = "file:///android_asset/tensorflow_inception_graph.pb";
private static final String LABEL_FILE =    "file:///android_asset/imagenet_comp_graph_label_strings.txt";

改为这样:

private static final int INPUT_SIZE = 128;
private static final int IMAGE_MEAN = 128;
private static final float IMAGE_STD = 128;
private static final String INPUT_NAME = "input";
private static final String OUTPUT_NAME = "final_result";private static final String MODEL_FILE = "file:///android_asset/output_graph.pb";
private static final String LABEL_FILE =    "file:///android_asset/output_labels.txt";

点击运行从而开始编译,然后在你的手机上运行相应的apk安装包,你就得到了自己的道路识别器。

结果

下面是我实际使用我这个app的视频,我对UI进行了一些小改动,从而使显示结果更直观。

那么它运行速度和CPU占用的情况怎样呢?

在我的小米5上,它识别一张图片需要55毫秒,也就是每秒18帧(18fps)。

不过,在这个识别速度下,CPU的占用也比较大。在加足马力运行的情况下,CPU的占用大概为25到30%。

 搭载MobileNet的App在18fps速度下运行时的CPU占用情况

如果我们希望这个数字能到5%,那么我们可以降低app的运行速度,因为在我们的使用场景中并不需要连续地进行图像识别。将识别速度调整到每秒1张,CPU的占用的平均值就下降到了5.5%。

 搭载MobileNet的App在1fps速度下运行时的内存占用和CPU占用情况

总结一下,我们的MobileNet的模型只有Inception的1/30,而运行起来识别图片的速度大概是后者的三倍,同时使用了占用的CPU空间也更少。

相关链接

教程原文:
https://hackernoon.com/building-an-insanely-fast-image-classifier-on-android-with-mobilenets-in-tensorflow-dc3e0c4410d4

下载作者训练好的模型:
https://s3-us-west-1.amazonaws.com/coastline-automation/demo/mobilenet-road-not-road.tar.gz
这里面包括一个.pb模型文件和一个存储标签(“road”,“not road”)的.txt文件。

—— ——

本文作者:王瀚宸 
原文发布时间:2017-08-06

MobileNet教程(2):用TensorFlow搭建安卓手机上的图像分类App相关推荐

  1. 使用Termux在安卓手机上搭建本地Git服务器

    一.安装安卓终端模拟器Termux https://github.com/termux/termux-app/releases 手机是arm 64位的,就下载 'termux-app_v0.118.0 ...

  2. iphone照片恢复至android,绝招!如何恢复苹果/安卓手机上误删的照片,详细教程奉上!...

    原标题:绝招!如何恢复苹果/安卓手机上误删的照片,详细教程奉上! 经常是怕占内存 就把手机里的照片删除了 然后就是某一天 突然反悔了想把照片找回来 或是真的不小心就把照片误删了 小伙伴们有过这种烦恼吗 ...

  3. 在安卓手机上安装Ubuntu详细教程(无需root)

    在安卓手机上安装Ubuntu详细教程(无需root)    Android系统是基于Linux的,但是要在安卓上安装Linux却没有那么容易.本文法针对安卓手机上安装Ubuntu系统提出了一种方法,安 ...

  4. kali安装卡在最后一步_黑客系统指南-在安卓手机上安装kali分步教程

    总结一些小笔记,下面我将会分享给大家在安卓手机上安装kali的详细步骤. 首先是把手机ROOT,不想忍受小米官方root的25秒骚扰,就想刷个原生的系统.我用的手机是小米NOTE 顶配版,这个手机版本 ...

  5. android客户端恢复教程,如何从安卓手机上恢复数据?

    软件升级维护中,请免费试用,确认能恢复了,再购买会员服务 万兴恢复专家-安卓恢复是一款专业的安卓手机数据恢复软件,支持从三星.华为.LG. vivo. OPPO.小米等国内外主流安卓品牌手机和平板等移 ...

  6. android模糊后面视频,在安卓手机上怎么制作中间是横视频上下是模糊效果的竖视频?手机视频短片制作...

    注意此教程方案是『安卓手机端教程方案』 今天要介绍的是安卓手机视频短片制作软件,可以在安卓手机上制作手机视频短片哦,制作那种中间是横视频上下是模糊效果的竖视频哦~不是手机看的视频片,手机怎么下载好看的 ...

  7. 安卓怎么下载python-教你在安卓手机上安装python程序

    编程就是告诉计算机要做什么,计算机只是一些没有生命的机器,它们可不知道自己要做什么,一切都得你来告诉它.对于计算机是这样,对于安卓手机也是这样.本文将教授大家在如何在安卓手机上安装Python程序,有 ...

  8. 使用Termux在安卓手机上运行tomcat服务器

    使用Termux在安卓手机上安装运行tomcat服务器 简单背景 探索尝试 尝试一:使用limbo虚拟机(失败) 想念二:使用Linux Deploy安装(直接放弃) 尝试三:使用Aid Learni ...

  9. android 水印视频教程,如何给视频添加一个摇摆的文字水印?安卓手机视频编辑助手app给视频加文字水印...

    注意此教程方案是『安卓手机端教程方案』 如果在手机端操作不方便或对眼睛不好 也可以用另外电脑端的教程方案操作:视频加旋转水印[找更多方案] 今天要介绍安卓手机上视频编辑助手是可以给视频添加摇摆的文字水 ...

最新文章

  1. INSTALL_FAILED_USER_RESTRICTED
  2. 【救援过程】升级openssl导致libcrypto.so.1.1动态库不可用
  3. 金山卫士UI原理解析(2)CBkWindow
  4. selenium2与python自动化1-selenium简介与降级
  5. PCB生成光绘文件教程 (Z)
  6. 男人对待恋爱的不同阶段......
  7. aws s3 命令行_通过命令行界面使用AWS ElasticMapReduce
  8. python天天向上续2_2019/2/12 Python今日收获
  9. Spring 自定义注解,配置简单日志注解
  10. 厉害了,比Transformer还好用!
  11. Python基础——元组与列表
  12. 消息队列技术终结者(一)—通俗深刻地认识JMS(即Java Message Service)
  13. 运用正则表达式在Asp中过滤Html标签代码的四种不同方法
  14. 计算机网络练习题-1
  15. 海康威视提前批-大数据算法工程师面试
  16. Android 显示大尺寸图片
  17. android monkey 工具,Maxim-高速 Android Monkey 工具使用记录
  18. 如何快速建搭建企业官方网站
  19. 如何做好基层管理者(二)
  20. 【BLE MESH】PB-ADV入网详解

热门文章

  1. 数据库设计原则【转】
  2. 巧用row_number和partition by分组取top数据
  3. Mac OS X 创新卡关三年,唯一看得出版本不同之处是「预设桌布」
  4. Java中的String字符串
  5. 当技术面试官的一些心得
  6. 人少,登录速度就是快.
  7. Jenkins执行脚本,提示“sudo: no tty present and no askpass program specified”解决方法
  8. 数据库知识点补充::约束
  9. Metasploit漏洞利用基础教程要出版了
  10. Swift3.0语言教程使用编码创建和初始化字符串