在树莓派上安装PyTorch 1.0

在树莓派上安装PyTorch 1.0

学了深度学习,对神经网络有所些了解的你,是否也有一种把知识应用到现实世界的冲动?喜欢DIY,擅长捣鼓单片机的心灵手巧的你,这几年听到这几年越炒越火的人工智能的概念,是否也想为自己的作品附魔?想做能识别猫狗的智能饲喂器吗?想做可以跟着人走的智能小车吗?想做能识别女神的容颜,见了女神就能替你表白的机器人吗?

本文将为大家介绍如何在树莓派3 B+的Raspbian系统上,python3.5的环境中编译、安装和运行PyTorch 1.0。本文最后会提供一个简单的图片分类小程序。新手科普向。假设读者有一定的linux和python经验。转载请注明作者ID和出处。

一、超简洁的预备知识

1.什么是树莓派?

答:树莓派是一个香烟盒大小的电脑,价格不贵。本文说的树莓派3B+约$40,国内在线商城也很容易买到,不到三百块。如下图所示:

树莓派3B+

2.树莓派3B+能干什么?

答:能运行window和linux系统。有四个USB口可以外接键盘、鼠标、摄像头、游戏手柄等外设,有HDMI接口可以接显示器,也有音频接口接耳机或音响。可以当做一台普通的电脑用来办公上网和游戏但是会很卡,因为配置太低。(三百块就想获得流畅的办公和上网体验?别做梦啦!)还有裸露的针脚可以用来控制你自己设计的电路。比如读取各种(温度,重力,加速度)传感器信息,也可以驱动马达和蜂鸣器什么的。买个电池盒,就可以整合到自己的DIY作品里,将更多的想象力化为可能了。

3.什么是PyTorch?

PyTorch是个开源的Python库,用户可以很方便地用其搭建、训练和测试神经网络。


二、超简洁的系统安装步骤

  1. 首先准备好Micro SD卡(也就是民间俗称的手机内存卡)和读卡器。如果你的电脑(下文如无特殊说明,“电脑”指代你平时用的普通电脑,而非树莓派。)上没有的读卡器,也不能把你的手机当做读卡器来使用,那么可以考虑向朋友借或者买一个。
  2. 去树莓派官网阅读系统安装指南
  3. 去下载Raspbian操作系统镜像。
  4. 下载一个叫做Etcher的工具。并安装到你的电脑里
  5. 把Micro SD卡插进读卡器,把读卡器插进电脑。
  6. 确定Micro SD卡上的重要文件都已备份好。Micro SD卡上面的文件在刷系统的过程中被删除。
  7. 用Etcher选择Raspbian系统镜像文件和Micro SD卡,单击"Flash"按钮将系统烧录至卡中。
  8. 将树莓派接好电源、键盘、鼠标和显示器,插入刚刚烧好的Micro SD卡。
  9. 打开电源开关,等待半分钟,哇我看到桌面了~!


三、编译和安装PyTorch 1.0

这一部分为本文重点。需要在终端Terminal中进行。

1.首先,更新软件包列表

sudo apt-get update

安装必要的软件包

sudo apt-get install libopenblas-dev cython3 libatlas-dev \
    m4 libblas-dev cmake

2.树莓派3B+只有1GB的内存容量,在编译PyTorch的过程中可能会爆内存。因此我们需要划分一些SWAP空间出来。其基本原理就是当内存吃紧的时候,用一部分硬盘(对于本文来说就是Micro SD卡)空间来减轻内存的负担。

下面介绍一个简单的方法,有经验的用户可酌情跳过:

sudo apt-get install vim
sudo vi /etc/dphys-swapfile

然后将CONF_SWAPSIZE和CONF_MAXSWAP那两行的注释去掉,把后面的数字改成你想要的SWAP大小。建议至少设到2048(代表2GB大小)。我的Micro SD卡容量比较充裕,是64GB的,所以我设成了4096(代表4GB大小)。不会用vim的同学可以自行选择文本编辑工具来修改设置。

使新设置的SWAP空间生效:

sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start

3.(可选)安装和设置虚拟环境。

sudo pip3 install -U virtualenv
virtualenv -p python3 ~/my_envs/pytorch1.0
source ~/my_envs/pytorch1.0/bin/activate

4.再安装两个包。

pip3 install numpy pyyaml

没有numpy的话也能成功编译,但是编译出来的PyTorch不支持numpy。

5.下载PyTorch的官方Repository

git clone https://github.com/pytorch/pytorch.git
cd pytorch

查看有哪些分支

git branch -a

本文中选择的是v1.01,未来的读者可酌情选择更新的分支

git checkout v1.0.1
git submodule update --init

按照我的理解,树莓派3B+不支持CUDA和MKLDNN,本文也不探究分布式所以按如下方式设置临时环境变量:

export NO_CUDA=1
export NO_DISTRIBUTED=1
export NO_MKLDNN=1

树莓派3B+虽然有四个核,但是内存太小了。在编译的时候如果四核全开会爆内存,变得很卡。亲测将编译的jobs数量减小反而会编译得更快。可将v1.0的编译耗时从十几个小时减少至七八个小时。(v0.4的pytorch编译不用那么久。)

5.现在一切就绪可以编译了。你有多种选择:

a) 如果想要自动编译,那么用如下命令

python3 setup.py install

b) 如果想要在日后再次安装或在另一台树莓派上安装时不必花时间再次编译,那么可以先生成一个wheel文件:

python3 setup.py bdist_wheel

然后去dist文件夹去安装你生成的wheel文件,其文件名取决于你用了pytorch的哪个分支。

cd dist
pip3 install ./torch-1.0.0a0+8322165-cp35-cp35m-linux_armv7l.whl

c) 你也可以直接下载我编译好的wheel文件来安装,地址是:tomorrow.ai/shared/pyto

文件校验码如下:

md5sum: 9b845ff3fcf9337acb3f20b271e685b9
sha256sum: 89cedc6bac9c48d05bb77de010633411f6fdce49616b11e3c135b727ef43e382

6.(可选)下文中还会用到的一些其他工具:

pip3 install torchvision
pip3 install opencv-python #可以用来读取摄像头捕获的画面,本文中没有涉及
pip3 install matplotlib
pip3 install ipython jupyter

至此,大功告成。


四、一个简单的图片分类程序

最近我女朋友不知从哪儿弄到了一个3D打印的“请等待”图标。我感到很神奇。我想找个AI试试它认不认识这个东西:

“请耐心等待”3D图标

一个用imagenet数据集的一百万张图片训练过的卷积神经网络能不能识别它呢?我于是写了如下的python代码:

import torch
import torch.nn.functional as F
import torchvision.models as models
import torchvision.transforms as transforms
import PIL.Image as Image
import numpy as np
import json

import matplotlib.pyplot as plt

image_path = './IMG_7085.jpg'

# Download the file from https://s3.amazonaws.com/deep-learning-models/image-models/imagenet_class_index.json
# which contains the name for each class of imagenet.
class_idx = json.load(open("imagenet_class_index.json"))
idx2label = np.array([class_idx[str(k)][1] for k in range(len(class_idx))])

normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                 std=[0.229, 0.224, 0.225])
preprocess = transforms.Compose([
                 transforms.Resize(224),
                 transforms.ToTensor(),
                 normalize
             ])
             
model = models.resnet18(pretrained=True)
model.eval()
print('Model was loaded.')

image = Image.open(image_path)

with torch.no_grad():
    input = preprocess(image)
    input = input.unsqueeze(dim=0)
    output = model(input)
    scores = F.softmax(output, dim=1)[0]
    scores = scores.numpy()
    top_inds = scores.argsort()[::-1][:5]
    
for i, ind in enumerate(top_inds):
    print('{} : {:.05f}'.format(idx2label[ind], scores[ind]))

plt.imshow(image)
plt.show()          

眨眼的功夫,屏幕上就冒出了结果:

ResNet18觉得有99.698%可能性图片中是一种叫做hourglass(沙漏)的物体。

“什么,原来不是3D图标啊?”

(屋子里充满了快活的空气)




晚些时候我会加入一段通过读取摄像头来给物体做分类的代码。所以未完待续~

参考资料:


Installing operating system imageswww.raspberrypi.org
Pytorch on RaspberryPiwormtooth.com图标https://medium.com/hardware-interfacing/how-to-install-pytorch-v4-0-on-raspberry-pi-3b-odroids-and-other-arm-based-devices-91d62f2933c7medium.com

编辑于 2019-02-28