https://cloud.tencent.com/developer/article/1118784
亚马逊的开源深度学习引擎 Apache MXNet 除了支持多 GPU 训练和部署复杂模型外,还可以生成非常轻量级的神经网络模型。我们也可以将这些模型表征部署到有限内存和计算力的移动端中。这就令 MXNet 可以完美地在树莓派中运行深度学习模型。
在本文中,我们将使用 MXNet 在树莓派上创建计算机视觉系统。我们同样也会讨论如何使用 AWS IoT 以连接到 AWS Cloud 中,因此我们可以使用云端管理轻量卷积神经网络,并令其在树莓派中实时执行目标识别。
所需设备
为了跟随本文完成这一实现,我们需要一个 Raspberry Pi 3 Model B 设备,并且它运行 Jessie 或其他更新版的 Raspbian 操作系统,同时还需要 Raspberry Pi Camera Module v2 和一个 AWS 账号。
配置树莓派
首先,我们需要设置树莓派的相机模块为摄像机,然后再安装 MXNet。这两步允许我们对树莓派「看见」的物体执行基于深度神经网络的分析。
设置相机模块:https://www.raspberrypi.org/learning/getting-started-with-picamera/worksheet/
设置树莓派的相机模块,并通过以太网端口或 WiFi 连接设备到网络中。然后打开终端,键入以下命令以安装本文所需要的 Python 依赖库:
sudo apt-get update
sudo apt-get install python-pip python-opencv python-scipy
python-picamera
跟着安装指导在树莓派上安装 MXNet:http://mxnet.io/get_started/install.html
在本文中,我们构建的 MXNet 不需要 OpenCV 库。
如果在树莓派的终端键入如下命令行可以打开 Python 2.7 Read-Eval-Print-Loop (REPL) 环境,那么就安装成功了:
python
>>> import mxnet as mx
>>> mx.__version__
本地执行预测
如果需要对树莓派相机所捕捉到的图像执行预测,我们需要从 MXNet Model Zoo 中抽取预训练深度神经网络模型。在树莓派的根目录创建一个 Python 文件,并命名为 load_model.py,然后从 Model Zoo 下载 ImageNet 预训练模型并加载到树莓派的 MXNet 中:
源代码请见原文
下载了高精度的轻量模型后,可以尝试利用 ImageNet 预训练的 SqueezeNet V1.1 模型识别一张猫的照片,我们可以在树莓派的根目录上运行如下命令行:
wget https://upload.wikimedia.org/wikipedia/commons/b/b9/CyprusShorthair.jpg -O cat.jpg
python load_model.py --img 'cat.jpg' --prefix 'squeezenet_v1.1' --synset 'synset.txt' --params-url
'http://data.mxnet.io/models/imagenet/squeezenet/squeezenet_v1.1-0000.params' --symbol-url 'http://data.mxnet.io/models/imagenet/squeezenet/squeezenet_v1.1-symbol.json'
--synset-url 'http://data.mxnet.io/models/imagenet/synset.txt'
如下所示,输出确实将「猫」作为最佳的标签:
[(0.57816696, 'n02123045 tabby, tabby cat'), (0.19830757, 'n02124075 Egyptian cat'),
(0.16912524, 'n02325366 wood rabbit, cottontail, cottontail rabbit'),
(0.020817872, 'n02123159 tiger cat'), (0.020065691, 'n02326432 hare')]
为了对树莓派相机所捕捉到的图片进行识别,我们需要将相机指向需要分类的目标,并在树莓派的根目录中运行如下命令:
python load_model.py –img ‘cam’ –prefix ‘squeezenet_v1.1’ –synset ‘synset.txt’
然后我们会看到抓拍图片的快速预览,然后我们的模型会执行并返回预测的目标标签。
连接到 AWS IoT
在树莓派上本地运行模型只是第一步。如果我们需要可靠性集中(reliably centralize)和储存预测结果,或远程更新模型,我们就需要连接树莓派到 AWS Cloud 中。为了连接到 AWS,首先第一步就需要在树莓派中设置 AWS IoT。
在 AWS IoT 控制台中,我们可以使用 AWS IoT Connect wizard。对于平台,选择 Linux/OSX;对于 SDK 类型,选择 Python,然后就可以选择下一步了。
注册你的设备名为「MyRaspberryPi」。
选择下一步并在 connect_device_package.zip 中下载连接工具箱到树莓派中。但当我们解压缩 connect_device_package.zip 文件并抽取内容到树莓派的根目录中时,我们将看到需要确保设备和 AWS 中间的安全连接:
- myraspberrypi.cert.pem
- myraspberrypi.private.key
- myraspberrypi.public.key
- start.sh
为了在设备和 AWS Cloud 中创建安全连接,我们需要跟着下面在树莓派上运行 start.sh 脚本。该脚本会下载 Symantec Root-CA 认证到树莓派中,并安装 AWS IoT SDK,这将令 Python 和 AWS IoT 的交互更加简单。该脚本同样确保了树莓派可以和 AWS IoT 对话。现在我们可以使用 AWS IoT 在树莓派上创建服务,即可以近乎实时地进行目标识别并将结果推送到 AWS Cloud 中。它还提供了在树莓派上无缝更新模型的机制。
现在在我们的根目录下,创建一个名为 iot_service.py 的新文件,并将下面代码添加到其中:
源代码请见原文
现在可以在树莓派的根目录中键入以下命令运行该文件:
python iot_service.py -e my-device-endpoint.amazonaws.com -r root-CA.crt -c myraspberrypi.cert.pem -k myraspberrypi.private.key
在 AWS IoT 控制台选择 Test,并提交 sdk/test/monitor topic:
为了在 AWS 实时看到预测流,我们需要在 Test 页面中选择新主题的名称。即使网络连接很慢或掉线了,AWS IoT 也确保了数据包不会遗失,并且预测日志仍然会保持更新。
为了发送命令到树莓派以更新 MXNet 模型的运行,我们能发布 MQTT 主题。例如,如需要更新 SqueezeNet 模型为更大、更精确的 ResNet 模型时,我们可以在 MQTT 客户端的 Publish 部分中,发送如下 JSON 到 sdk/test/load topic 中:
{"synset": "synset.txt","prefix": "resnet-18","label_name": "softmax_label","params_url": "http://data.mxnet.io/models/imagenet/resnet/18-layers/resnet-18-0000.params","symbol_url": "http://data.mxnet.io/models/imagenet/resnet/18-layers/resnet-18-symbol.json"}
下图就是在 MQTT 客户端中的样子:
树莓派从 Model Zoo 中下载新的神经网络符号和参数文件,然后加载它们持续进行预测。我们不需要下载一个新的 synset。因为这两个模型都是用于挑战 ImageNet 任务而构建,所以我们试图识别的物体都是一样的。
下一步
通过在树莓派上运行 MXNet 以执行预测,还有利用 AWS IoT 连接它到 AWS Cloud,我们已经构建了一个近乎最好的计算机视觉系统。我们的系统不会依赖于稳定的高带宽视频流,也不会依赖用云端昂贵的 GPU 服务器来处理视频。实际上,通过在树莓派上使用 AWS 和 MXNet,我们能很容易地构建一个更加可靠和高效的智能视觉系统。通过这种方式,我们享受到了云模型监控和管理的好处,但同时也不需要每月为云端服务器和数据迁移花大价钱,我们只需要花 400 元左右买树莓派和摄像头就行了。
这种智能摄像系统只是开端,我们还可以利用 AWS Cloud 建立更多的应用,如使用迁移学习将预训练模型更好地适配到我们自己的计算机视觉任务中。
机器之心实操
机器之心 AI 新手小编在读完该篇文章后,也尝试着使用树莓派实现这一有意思的应用,但在该过程中遇到了许多困难。虽然机器之心小编暂时还没有成功,但在实现的过程中还是发现了许多有用的经验,因此希望能与读者共同玩转树莓派,并实现实时目标识别。这里也欢迎想要尝试的读者在文章下留言,分享实现这一教程的经验。最后补充一句:新手上路,老司机莫要嘲笑!
首先是系统,树莓派最常用的是系统是 Raspbian,它是一种基于 Debian 的小型操作系统,我们需要下载系统并烧录到 TF 卡中。
- Raspbian 下载地址为:https://www.raspberrypi.org/downloads/raspbian/
- Win32DiskImager 烧录工具地址为:https://sourceforge.net/projects/win32diskimager/files/latest/download
启动 Raspbian 系统并装上摄像头组件后,我们需要测试并调校摄像头。
一般我们可以键入命令:sudo raspi-config,再设置启用摄像头。或者如下直接进入 Raspberry Pi Configuration 界面设置:
下面我们可以调校和测试摄像头,如果测试摄像头静态拍照,我们可以键入 raspistill 打开拍照应用。打开后会显示很多命令,我们可以根据这些命令和后面的解释调整摄像头,比如键入 raspistill -sh 30 就表明调整锐度为 30(-100 到 100)。如果我们尝试进行拍照,可以键入 raspistill -o image.jpg -t 2000,即延迟两秒输出名为 image.jpg 的图片。或者可以键入命令 raspistill -o image%d.jpg -t 20000 -tl 1000 -v:即持续 20 秒,每一秒输出一张相片,且图片命名为 image0.jpg、image1.jpg、image2.jpg 等。
由于树莓派的内存只有 1GB,我们需要从 TF 卡分配 1GB 的存储空间作为 swap 交换空间,不然 MXNet 安装到里面会因为内存太小而报错。我们试了几种修改交换空间大小的方式(默认交换空间的大小为 100MB),最后实测可以在 root 权限下修改 dphys-swapfile 文档而实现 swap 交换空间大小的更改。即在 root 权限下键入命令 nano /etc/dphys-swapfile,然后如下图修改 CONF_SWAPSIZE=100 为 1024。最后保存文档并退出,然后重启系统。这一次重启的时间会有些增加,但只是在分配空间而已。
随后在安装 MXNet 的时候,我们遇到了更大的困难。最开始按照 MXNet 的官方教程安装,但在 mxnet 文件夹下 make 的时候,一直报错,应该是 opencv 库的路径没有添加到环境变量中。后来在 Medium 上发现有大神如是说:
然后我们又跟着这篇技术博客重新安装,不出意料的是,还是无法在 mxnet 文件夹下执行 make,总是报错。
- MXNet 官方安装教程:http://mxnet.io/get_started/install.html
- Julien Simon 安装教程:https://medium.com/@julsimon/an-introduction-to-the-mxnet-api-part-6-fcdd7521ae87
最后我们另外为依赖库运行了一句命令:sudo apt-get install -y build-essential Git libblas-dev libopencv-dev,然后真的可以 make 了,但在持续进行两小时后,还是报错了。后面再 make 也会一直有如下报错:
虽然这一次并没有成功,但我们还会继续在树莓派上实现这一实时目标识别过程。我们准备下一步再尝试各种方式,如果实在 Raspbian 不行的话,我们可能会换 Ubuntu 系统,再进行尝试。同时我们也希望读者能与我们共同交流,一起实现这一有趣的任务。