秘籍:如何用廉价硬件玩转深度学习,成本不到1000美元
作者Lukas Biewald,是CrowdFlower创始人。
量子位编译整理。
问:搭建一个深度学习系统拢共要花多少钱?
答:在树莓派上运行TensorFlow成本是39美元;在GPU驱动的亚马逊EC2节点上运行TensorFlow的成本是1美元,每小时。这些都是可行的方案。
当然要想玩得过瘾,可以自己搭建一个快速的深度学习系统,成本不到1000美元。
这也不是小数目,但这么做的好处是,一旦你有了自己的机器设备,可以运行数百个深度学习应用程序,比方增强的机器人大脑,或者搞点艺术创作。这套系统至少比Macbook Pro要强(除了功耗),而且可以实时升级一直用上好多年。
搭建这么一套设备非常有意思,而且做推理和学习比笔记本至少快20倍。
准备好了么?咱们先从需要采购的清单说起。
硬件清单
主板
主板的规格挺多,我不想搞多GPU系统,所以最便宜、最小的mini-ITX标准主板就可以了。最低要求是得有一个PCIe插槽,用以连接GPU,两个DDR4的内存插槽。最后我选的是华硕Mini ITX DDR4 LGA 1151 B150I PRO GAMING/WIFI/AURA主板,在亚马逊上售价125美元。这主板带WiFi天线,在我的地下室超级有用。
机箱
机箱无所谓,而且很便宜。DIY市场主要是游戏玩家,所以机箱往往五颜六色各种形状。为了匹配主板,我在亚马逊上花50美元买了这个:Tt Core V1 Mini ITX Cube。
内存
没想到内存这么便宜了……咱么要买DDR4内存查到主板上,价格都差不多,我花129美元买了两条8GB容量的海盗船复仇者。
我还多花了5美元,搞了带LED灯光的内存条。嗯。
CPU
我在网上看了一下CPU评测,感觉慢一点的CPU也够用,因为我要做的事情很少受制于CPU,除了训练神经网络,其他都用GPU。但是CPU也不能太差吧,所以最后选了英特尔i5-6600,花了214美元。
硬盘
硬盘也蛮便宜了。我花50美元买了一个1TB容量的SATA硬盘。没选SSD固态硬盘,是因为比较贵也用不着,深度学习的程序不受硬盘I/O接口限制,因为数据会批量加载到内存里然后处理很长时间。
显卡/GPU
怎么选显卡是最棘手的问题,玩深度学习,肯定得选NVIDIA,因为N记有CUDA框架和CuDNN库,所有的机器学习框架,包括TensorFlow,都有赖于它们。
然后,最重要的是属性可能是显存,如果TensorFlow不能把模型和当前批次的数据装入GPU的显存,就会错误的送到CPU里去。
另一个关键因素是显卡的架构。NVIDIA最新的几个架构,按照次序是:Kepler、Maxwell、Pascal。架构之间的差异影响着速度,Pascal Titan X的速度是Maxwell Titan X的两倍。
大多数机器学习的论文都是基于TITAN X显卡,但是这种显卡最便宜也得1000美元。大多数人预算都有限,所以最后用了NVIDIA GTX 900 series (Maxwell)或者NVIDIA GTX 1000 series (Pascal)。我最后选的GeForce GTX 1060 3GB,195美元。
电源
我花85美元买了一个650W的电源,电源还是买个放心的把。不过我这套系统,峰值功耗也没有超过250W。
散热片
我花35美元买了一个Cooler Master Hyper 212 EVO,用来让CPU冷静一下。
小结
除了上述种种,还得买显示器、键盘鼠标什么的。所以,最后总共花费883美元。
组装
装硬件
各种快递到齐之后,我开始装机,然而这里面坑还是挺多……搞了一个小时装好,却开不了机,不得已又给拆了。第二次我索性先把所有东西放在一个纸箱上。最后,搞定。
装系统
安装最新版的Ubuntu吧(下载地址:ubuntu.com),可以支持几乎所有的深度学习软件。可以把镜像拷在一个U盘上,然后参考这个简单的教程安装。Ubuntu现在挺好用的。(图解:6步安装Ubuntu,地址:ubuntu.com/download/desktop/create-a-usb-stick-on-ubuntu)
安装CUDA、OpenCV和TensorFlow
为了使用这台全新的设备进行深度学习,首先得安装CUDA和CudNN。目前最新的版本是CUDA 8.0,CudNN 5.1。CUDA是一个API,也是一个编译器,允许其他程序将CPU用于通用应用程序,CudNN是一个旨在使神经网络在GPU上运行更快的库。
(CUDA和CudNN的下载地址:developer.nvidia.com/cuda-toolkit)
OpenCV是大多数应用程序使用的图像处理开源库。最新版本的OpenCV 3.1不适用于EC2上最新版本的CUDA 8.0。我们可以通过把CUDA_GENERATION标志显式设置为Kepler、Maxwell或Pascal来使其工作,这取决于您购买的GPU的类型。
这里是下载OpenCV并设置它运行的命令序列:
git clone https://github.com/opencv/opencv.git
&& cd opencv
&& mkdir build
&& cd build
&& cmake ..
&& make -j3
&& make install
最后,结果TensorFlow是这里面最容易安装的。(这里是安装指南的传送门:tensorflow.org/get_started/os_setup)。
想检查是否启用了GPU支持,可以运营TensorFlow的测试程序,也可以用如下命令:
python -m tensorflow.models.image.mnist.convolutional
好玩的部分来了
截止到目前,已经花了大概1000美元,也花了无数个小时安装软件。现在是时候证明这一切物有所值了!有好多好玩的事情可以做~
对邻居进行实时对象识别
在房子外面按一个便宜USB摄像头或者带摄像头的树莓派,利用RPi摄像头模块(传送门:elinux.org/Rpi_Camera_Module),可以很容易的生成一个视频流。
YOLO
YOLO软件包也能对输入的图像进行实时识别。以前用Macbook,识别响应大概3-4秒,使用GPU,可以很准确的实时运行。
想用YOLO模型很简单,从github下载YOLO_tensorflow项目(地址:github.com/gliese581gg/YOLO_tensorflow)。安装Darknet也挺有意思,这是另外一种深度学习框架,YOLO原本是为这个框架设计的:
git clone https://github.com/pjreddie/darknet
cd darknet
make
一旦Darknet安装完毕,你可以用如下命令来探测图片:
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg
由于Pi相机只是将文件放在网络服务器上,你可以直接链接到这个文件,并在流上进行实时图像识别。下面这段视频是我做的测试:
给树莓派一个更强的大脑
我之前发过一篇100美元做TensorFlow机器人的文章,机器人可以在一个30美元的硬件上做深度学习。不过,在那个环境下机器人要耗时数秒才能进行对象识别,而使用这次全新搭建的系统,不仅可以实时进行图像识别,还能在每秒12-20帧的速度上计算边框。
按照我在GitHub上的说明,你也可以搭建一个机器人,这个机器人通过摄像头看到的一切,都可以简单、快速的解析。
我和我的朋友各自搭建了一个树莓派机器人,然后进行了一场啤酒瓶之战。当时他的电脑上的GeForce 980对两个机器人进行实时馈送。
艺术创作!
搭建神经网络最好玩的事情之一,就是复制Google旗下Deep Dream的工作,不过如果没有GPU的加持这个工作永远也干不完。基本上,这涉及修改输入图像以驱动神经网络中最高响应,这需要很做的工作。实现这一点有很多变体,结果也往往非常奇怪。
对我而言,Google放出的Deep Dream代码是史上最棒的教程。(地址:github.com/google/deepdream/blob/master/dream.ipynb)
这得需要安装Jupyter笔记本服务器(传送门:jupyter.readthedocs.io/en/latest/install.html)和Caffe(又一个传送门:caffe.berkeleyvision.org/installation.html)。然后把朋友或者什么人的图片输入进去,只需要等待几分钟,一个艺术图片就出现了~
如果你想更疯狂一点,这里还有一个神经风格的TensorFlow实现(地址:https://github.com/anishathalye/neural-style),也是基于Deep Dream的工作。这个可以产生更多惊人的图片。
结论
咱们不需要花费数千美元,来搞一个比笔记本快很多的深度学习系统。动手DIY一套深度学习设备也是很宝贵的经验,而且DIY的东西还能升级。其实,我现在把显卡换成Titan X了,所有运行的程序并不需要重新编译。
总之这个方法还不错,机器的运行速度与用使用K80 GPU的亚马逊P2实例大致相同,后者的价格是1美元/小时。
- 并发与实例上下文模式: WCF服务在不同实例上下文模式下具有怎样的并发表现
- 区块链将变革的五个行业
- WCF技术剖析之二十三:服务实例(Service Instance)生命周期如何控制[上篇]
- AngularJS in Action读书笔记3——走近Services
- 有了这些无人驾驶的汽车,未来还需要考驾照吗?
- 并发与实例上下文模式: WCF服务在不同实例上下文模式下具有怎样的并发表现
- AngularJS in Action读书笔记4(实战篇)——创建Statistic模块
- Effective Deep Memory Networks for Relation Extraction
- ConcurrencyMode.Multiple模式下的WCF服务就一定是并发执行的吗:探讨同步上下文对并发的影响[上篇]
- WCF技术剖析之二十一:WCF基本异常处理模式[下篇]
- AngularJS in Action读书笔记5(实战篇)——在directive中引入D3饼状图显示
- WCF中并发(Concurrency)与限流(Throttling)体系深入解析系列[共7篇]
- AngularJS in Action读书笔记6(实战篇)——bug hunting
- FreeMarker模板开发指南知识点梳理
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Kubernetes 1.19.0——deployment(3)
- Selenium-01-测试环境搭建使用
- Selenium-02-常用元素定位
- SpringBoot + Vue 前后端分离项目下载视频文件踩坑记录
- Selenium-03-常用方法
- 用Python里面的Xpath完成一个在线汇率转换器
- 详解请求消息 resquest
- Android中窗口Input事件接收
- Linux下常用命令
- Cypress系列(53)- as() 命令详解
- Educational Codeforces Round 81 (Rated for Div. 2) A. Display The Number
- Cypress系列(55)- 设置全局 URL
- Linux不同共享库中同名函数的处理
- Cypress系列(56)- 避免访问多个站点
- Cypress系列(57)- 删除等待代码