感受Nvidia Jetson TX1的洪荒之力!
从机器学习说起
从2015年起国内外就掀起了机器学习、深度学习的热潮。以google、facebook、BAT等互联网巨头广泛研究应用机器学习以及深度学习技术并在业务方面显现出了良好的效果,尤其是在语音识别和图像识别等领域,而AlphaGo战胜李世石又将大家对机器学习、深度学习的关注推向了新的高峰。现在,在人脸识别、手写识别、语音识别、语意理解、机器翻译、无人驾驶骑车,无人机和智能机器人等代表未来技术的各个领域都有机器学习、深度学习的身影。
“机器学习是研究让计算机无需显式编程即可具有学习能力的学科”(Arthur Samuel,1959)。机器学习以统计学,概率论,组合学和优化理论等为基础,开发并利用算法来识别数据中的模式,由此来指引决策。以机器学习的分支神经网络为例,训练人工神经网络可以看作寻找并确定最优网络参数(例如内部网络权重与倾向),以减小初始数据集上的误差的函数优化问题。但使用数据来拟合模型是一个时间代价高昂的计算过程,它需要使用不同的参数组合反复地调用目标函数,计算训练数据中的每个样本,其算法的时间复杂度约为O(N^2)或者更高(N表示数据的规模),如此一来反复计算目标函数占据了大量执行时间,在这种情况下,可以利用并行计算来缩减运行时间,而并行计算正是GPU的优势,通过将目标函数的计算等过程映射到能执行上百个并行线程的GPU上,往往可以在不需要配置维护大规模服务器机群或多机环境的情况下带来数倍甚至数十倍的性能提升。
根据前文的介绍,Jetson TX1凭借其Teraflops级的浮点计算能力和强大的软件堆栈以及超低得能耗 和娇小的身躯足以负载特定场合下的中小规模的机器学习的应用和开发,本文将运用神经网络实现一个经典的异或逻辑来一探Jetson TX1在机器学习领域的洪荒之力。
异或逻辑的神经网络实现
神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。神经网络中最基本的成分是神经元模型(Neural Model)(又称Logistic unit)。对于人类而言,我们的视觉听觉是由大脑的神经中枢产生。而神经中枢是由大量的神经元相互连接而成。一个神经元通过树突接受其他神经元传来的化学物质(信息),从而改变该神经元的电位,当电位到达某一阙值(threshold)时,该神经元被激活,即“兴奋”起来,从而通过轴突向其他神经元发送化学物质,如图1所示。
生物神经系统中的神经元模型
人工神经元模型便是模拟上述的神经元接受信息并传递信息的过程。如图2所示,人工神经元接收来自n个其他人工神经元传递过来的输入信号,这些输入信号通过带权重的连接进行传递,人工神经元将接收到的总输入值与人工神经元的阙值进行比较,再通过激活函数(activation function)处理以产生神经元的输出。
人工神经网络中的神经元模型
由于我们需要实现的异或逻辑并不是线性可分的问题,所以为了实现异或逻辑,我们需要使用神经元搭建含有隐藏层的神经网络,其由三部分组成,分别是输入层(input layer),隐藏层(hide layer)和输出层(output layer),如图3所示。
一个含有隐藏层的神经网络示意
如上图所示,除了需要大量彼此连接的节点 (即神经元),神经网络还需要具备以下特性:
1.激活函数,每个神经元根据激活函数,通过计算处理来自其它相邻神经元的加权输入值。
2.连接权重,它定义神经元之间的信息传递的强度,算法会依靠大量的数据来训练,不断自我调整连接权重。
3.成本函数,用来定量评估计算出来的输出结果于真实值的偏离程度。
4.学习的算法,这是根据成本函数的结果, 自学, 纠错, 最快地找到神经元之间最优化的加权值。
在学习算法方面,目前,有许多流行的库、工具和算法可以用来计算针对多变量函数的最优拟合,同时互联网上也有很多免费许可的数值工具和代码供我们使用,本文将选择使用Nelder-Mead方法,NM方法是一种常见的直接搜索型非线性优化方法,我们可以在互联网上找到John Burkhardt创建的一个免费的C语言实现,在这里,我们只需要进行一些细微的调整,就可以用在本次的代码中。
编写完代码后,我们可以选择直接在HOST电脑中编译生成可执行文件,如下图所示。
在HOST电脑上直接编译生成可执行文件
或可以将源码文件直接同步到Jetson TX1,然后在其命令行中通过命令编译生成可执行文件,如下图所示。
在Jetson TX1上直接编译生成可执行文件
这里需要注意的是,用户开发的一些项目可能会用到第三方的库或者工具,如Lapack和Levmar等,如果选择在HOST电脑上完成编译,只需要在HOST电脑上安装配置所需的库和工具,如果用户需要在Jetson TX1上直接编译生成项目,那么同时也需要在Jetson TX1上安装配置对应的库和工具。
程序执行结果和性能
项目成功生成之后,使用“./”在Jetson TX1命令行中运行,得到如下结果:
Jetson TX1异或逻辑单精度运行结果
Jetson TX1异或逻辑双精度运行结果
GeForce GT650M异或逻辑单精度运行结果
GeForce GT650M异或逻辑双精度运行结果
Core i7-3630QM异或逻辑双精度运行结果
Jetson TX1运行异或逻辑单精度共用时174.12秒,处理完成0.48GB数据;双精度共用时636.05秒,处理完成0.96GB数据,而与此同时,笔者在笔记本电脑上使用GeForce GT650M运行异或逻辑处理相同数据量单精度共用时201.02秒,双精度共用时435.69秒,而在Core i7-3630QM CPU上运行类似双精度代码共用时5204.50秒,由此也可以看出Jetson TX1与笔记本电脑相比带来的性能的提升尤其是GPU与CPU相比带来的性能提升;同时在这里引用其他人在单路至强E5630上运行类似算法时的平均目标函数运行时间数据:单精度 0.45秒,双精度 0.54秒;而对应的Jetson TX1的数据则为0.03秒和0.18秒,与单路至强E5630相比,分别由15倍和3倍的加速。仅使用一个嵌入式开发板就能达到这样的性能水平还是十分令人惊讶。
异或逻辑总运行时间对比(单位:秒)
平均目标函数运行时间对比(单位:秒)
本次开发的一些体验
Jetson TX1的性能令人惊讶
在本次的项目示例中,峰值功耗仅10W的Jetson TX1在性能上完胜了笔者搭载core i7处理器的笔记本电脑,并在类比的数据中,领先于单路E5630,令笔者更深刻的体会到了其1Teraflops计算能力带来的时间效率提升。作为一块嵌入式开发板,确实令人映像深刻。
NVIDIA CUDA提供的示例代码对实际项目的开发帮助很大
由于本次项目中使用了OpenMP中的部分函数,所以在编译时需要配置专门的参数,如-fopenmp等,而NVIDIA CUDA 示例代码cudaOpenMP中的Makefile示例给笔者提供了极大的帮助,参考其修改本次项目中的Makefile以完成项目的成功编译生成。■