基于树莓派和tensorflow的物体识别

『1』对深度学习(Deep Learning)的简单介绍
以下解释来自维基百科:

深度学习是机器学习拉出的分支,它试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

深度学习的用途实在太广泛,最为普通人所熟知的,就是以下和民生相关的应用:人脸识别,语音识别,图像搜索,在线翻译,等等。
目前流行的深度学习框架有TensorFlow(Google开源),MXNet(得到Amazon支持),Theano等,利用这些框架,我们只需要做比较少的工作,就能把深度学习能力带入我们自己的程序。
文章来源: http://www.codelast.com/
『3』树莓派上的深度学习
当前,主流的深度学习框架都不是 主要为了移动平台/嵌入式平台而准备的——这是由于计算能力所限,在移动平台上运行local的深度学习程序,计算速度通常会非常慢。因此,移动平台上主要还是采用向云端提交计算请求、云端计算完成后返回结果的方式来处理数据。
作为一个“类嵌入式”平台,树莓派虽然是同类型里最受关注的产品,但我认为在深度学习的世界里,树莓派还没到像Android、iOS那种“开发一个App必须要支持”的程度。
因此,把任何一个主流的深度学习框架,在树莓派上跑起来都将是一个耗时耗力的工作。
好在TensorFlow是如此流行,并且IT界永远不缺牛人,已经有人把它成功地“移植”到了树莓派3代上( 看这里),所以,在树莓派上用TensorFlow来实现深度学习应用是一个不错的选择。

『3』在树莓派上安装TensorFlow
按作者的文档,通过极其简单的几步操作,就可以在树莓派上把TensorFlow跑起来。如果你有兴趣,可以直接去看作者写的教程。
首先要声明的是:

  • 作者在树莓派上使用的最流行的Linux发行版Raspbian,而我使用的OS是Arch Linux ARM,不过这无所谓,经过我的测试,没有问题(至少我没遇到)
  • 由于在树莓派上开发其他程序的原因,我已经预先安装过了比较多的开发库/软件,类似于Protocol Buffers,NumPy,pip等,而这些软件有些可能会被TensorFlow依赖,所以,我就不需要像作者的文档里说的一样另外再去安装它们了

文章来源:http://www.codelast.com/
然后剩下最关键的一步就是,从GitHub下载一个wheel文件并安装。
wheel是众多Python软件安装包格式中的一种,本质上是一个zip包格式,它使用.whl作为扩展名,用于安装Python模块。

如果你使用Python 2.7:

1
2
wget https: //github .com /samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0 .11.0 /tensorflow-0 .11.0-cp27-none-linux_armv7l.whl
sudo pip install tensorflow-0.11.0-cp27-none-linux_armv7l.whl

如果你使用Python 3.3+(但据作者所说,3.5以及3.6是不保证能支持的,不过,我用3.5.2还是安装成功了):

1
2
wget https: //github .com /samjabrahams/tensorflow-on-raspberry-pi/releases/download/v0 .11.0 /tensorflow-0 .11.0-py3-none-any.whl
sudo pip3 install tensorflow-0.11.0-py3-none-any.whl

下载whl安装包的过程可能会比较漫长,我使用的是Python 3.5.2,下面是我的命令行输出内容:

Processing ./tensorflow-0.10.0-py3-none-any.whl
Collecting protobuf==3.0.0b2 (from tensorflow==0.10.0)
  Downloading protobuf-3.0.0b2-py2.py3-none-any.whl (326kB)
    100% |████████████████████████████████| 327kB 11kB/s
Collecting wheel>=0.26 (from tensorflow==0.10.0)
  Downloading wheel-0.29.0-py2.py3-none-any.whl (66kB)
    100% |████████████████████████████████| 71kB 18kB/s
Requirement already satisfied (use --upgrade to upgrade): numpy>=1.8.2 in /usr/lib/python3.5/site-packages (from tensorflow==0.10.0)
Requirement already satisfied (use --upgrade to upgrade): six>=1.10.0 in /usr/lib/python3.5/site-packages (from tensorflow==0.10.0)
Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/lib/python3.5/site-packages (from protobuf==3.0.0b2->tensorflow==0.10.0)
Installing collected packages: protobuf, wheel, tensorflow
Successfully installed protobuf-3.0.0b2 tensorflow-0.10.0 wheel-0.29.0
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

文章来源:http://www.codelast.com/
然后呢?然后就搞定了!就这么简单!

如果上面的步骤失败了,那么你就只能选择从源码来编译TensorFlow,这是一个相当麻烦的工作,只能祝你好运了,不过好消息就是,作者已经帮大家踩过很多坑了,教程在这里

『4』在树莓派上使用TensorFlow
要识别一张图片里的物体是什么,我们需要先训练一个图像分类模型,这个过程非常消耗计算资源,在树莓派上干这事是不明智的,我们可以直接使用Google已经训练好的Inception-v3模型。

Inception-v3 is trained for the ImageNet Large Visual Recognition Challenge using the data from 2012. This is a standard task in computer vision, where models try to classify entire images into 1000 classes, like "Zebra", "Dalmatian", and "Dishwasher".

先下载Inception-V3模型到任意目录中,并解压出来:

1
2
3
4
mkdir ~ /tensorflow-related/model
cd ~ /tensorflow-related/model
wget http: //download .tensorflow.org /models/image/imagenet/inception-2015-12-05 .tgz
tar xf inception-2015-12-05.tgz

解压出来一堆文件:

classify_image_graph_def.pb
cropped_panda.jpg
imagenet_2012_challenge_label_map_proto.pbtxt
imagenet_synset_to_human_label_map.txt
LICENSE

然后就可以开始进行图像识别啦。在这里我从网上找了一张时下很流行的摩拜单车(Mobike)的图片:

文章来源:http://www.codelast.com/
用TensorFlow来识别它:

1
2
cd /usr/lib/python3 .5 /site-packages/tensorflow/models/image/imagenet
python3.5 classify_image.py --model_dir /root/tensorflow-related/model --image_file /root/tensorflow-related/test-images/mobike .jpg

其中,/usr/lib/python3.5/site-packages/tensorflow/models/image/imagenet 这个路径是TensorFlow的 Python图像分类程序 classify_image.py 所在的路径,不同的OS可能不一样。
--model_dir 参数传入的是我们前面解压出来的模型文件所在的路径,--image_file 是待识别的图片的路径。
注:如果找不到classify_image.py文件,请参考本文末的更新说明。
输出如下:

/usr/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1750: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
  result_shape.insert(dim, 1)
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
bicycle-built-for-two, tandem bicycle, tandem (score = 0.33731)
tricycle, trike, velocipede (score = 0.16082)
unicycle, monocycle (score = 0.12926)
mountain bike, all-terrain bike, off-roader (score = 0.10689)
parking meter (score = 0.01563)
[root@alarmpi imagenet]# python3.5 classify_image.py --model_dir /root/tensorflow-related/model --image_file /root/tensorflow-related/test-images/mobike.jpg
/usr/lib/python3.5/site-packages/tensorflow/python/ops/array_ops.py:1750: VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future
  result_shape.insert(dim, 1)
W tensorflow/core/framework/op_def_util.cc:332] Op BatchNormWithGlobalNormalization is deprecated. It will cease to work in GraphDef version 9. Use tf.nn.batch_normalization().
mountain bike, all-terrain bike, off-roader (score = 0.56671)
tricycle, trike, velocipede (score = 0.12035)
bicycle-built-for-two, tandem bicycle, tandem (score = 0.08768)
lawn mower, mower (score = 0.00651)
alp (score = 0.00387)

可见,TensorFlow认为图片是山地自行车(mountain bike)/全地形自行车(all-terrain bike)/越野车(off-roader)的概率是0.56671,识别结果还算可以。
文章来源:http://www.codelast.com/
『5』计算速度问题
上面的一次图像识别试验,总共花了50多秒的时间!这么慢的速度在实际应用中基本没有实用价值。
但实际上,这个时间是可以大幅缩短的。

  • 为模型“预热”很有必要。根据作者等人的性能测试结果,在合理预热的情况下,计算时间会减少较多。我测试了一下,请看这篇文章
  • 我们每运行一次程序,就重新加载一次模型,而模型文件又很大,这非常浪费时间,所以,应该把程序做成一个常驻内存的程序,只加载一次模型,每次识别一幅图像就能减少很多很多时间。我也实验了一下,请看这篇文章
  • 使用TensorFlow的C++接口来实现程序应该比Python版速度快,可以尝试。
  • 暂时还不能让TensorFlow使用树莓派的GPU来计算(看这里),但大家期待未来有一天这个愿望会实现。

所以至少50多秒这种恐怖的数字是可以避免的。
文章来源:http://www.codelast.com/
『6』在树莓派上跑TensorFlow有什么用
我随意想到的一个可能有意义的应用就是:一个幼儿辅助学习系统。在树莓派上挂载一个摄像头,孩子在摄像头前拿着一样东西,摄像头抓拍一张图片,识别出里面的东西,朗读出概率最大的那个英文单词。
当然,这里面有非常多的工程上的问题需要解决。

我相信,随着树莓派下一代的计算能力继续增强,以及TensorFlow每一次发布,都让性能提高一些,在不久的将来,在树莓派上跑TensorFlow应用的实用性将会非常好。

『7』更新

  • 2017.03.19更新

在本文写完之后不久,作者就发布了基于TensorFlow 1.0.0的Python wheel包,我试验了一下,它无法在Python 3.6.0的环境下安装,提示错误是:

tensorflow-1.0.0-cp34-cp34m-linux_armv7l.whl is not a supported wheel on this platform

作者说这是因为暂时不支持Python 3.5+。所以为了装上新版的TensorFlow,我用回了Python 2.7,然后就发现可以正常安装了:

1
2
pacman -S python2 python2-pip
pip2 install tensorflow-1.0.0-cp27-none-linux_armv7l.whl

期待以后能支持。

  • 2017.08.19更新

如果你安装的是1.1.0版本的TensorFlow on Raspberry Pi,那么你会发现你找不到classify_image.py文件,这是因为此版本确实不再包含该文件,这时你可以在TensorFlow的这个子项目里找到该文件。


你可能感兴趣的:(树莓派)