Come on ! 手把手教你玩转谷歌TensorFlow
AI并不是一门简单的学科,AI算法的开发和调试并没有一个统一的、集成了大量API方便调用的平台和语言,目前的人工智能开发平台仍然处于一种半蛮荒的状态。许多功能需要自己亲自去搭建和实现。
不过幸运的是,这个领域受到了足够多的重视,因此许多巨头都针对它开发了自己的平台,这其中就包括谷歌的Tensorflow。谷歌DeepMind在AI领域的造诣已经人尽皆知,其推出的这款开发语言平台也不禁引人遐想,那么,Tensorflow到底适合如何拿来做开发?能不能为你的研究或者产品带来更好的机会?
本期公开课我们邀请到了科技公司Nielsen的机器学习实验室的负责人李加波博士,他带领的团队利用基于Tensorflow自己改进的算法成功运用在了公司的精准广告推送业务中。在产业界的十多年中,李博士始终坚持学术研究与产业应用相结合,长期保持与学术界的紧密合作,并将学术成果引入到软件创新中。
嘉宾介绍,李加波, 目前任职于美国科技公司Nielsen的 Machine Learning Lab, 负责领导基于深度学习智能产品的研发,主要利用Tensorflow框架搭建新型的深度 神经网络 ,利用GPU训练各种用户分类模型,并将这些模型运用于精准广告推送中。在去年加入Nielsen之前曾任职于生物,制药和金融等科技软件公司,包括Accelrys, 薛定谔(Schrödinger)及TD Ameritrade。
李博士在工业界的十多年中始终坚持学术研究与工业应用相结合,长期保持与学术界的紧密合作,并将学术成果引入直接到软件创新中。目前任中山大学药学院客座教授,指导博士生的研究课题,并开设了Advanced Lectures on Algorithms and High Performance Computing (算法与高性能计算编程) 高级研讨班。另外在国际期刊发表科学论文六十多篇。李博士对各种复杂科学计算算法问题有极致的追求,并发明了一系列不同学科的优秀算法。
▎ 为什么一开始选择Tensorflow作为首选平台?
最开始对于选取何种深度学习平台并不确定,而且那时Tensorflow还尚未问世。当时的考虑主要是该平台的成熟程度,支持的编程语言,GPU的支持和效率,搭建神经网络的使用的方便程度,上手难易,平台的后续发展,开发的生态环境,平台的效率等因素。尽管我们收集了一些评比资料,要在诸多因素的权衡之中做出选择并非易事,而且逐个去试也不现实。不久之后,Tensorflow从Google开源,我们毫不犹豫地选定了它。
其一,TF有我们要求的所有功能(C++/Python语言支持,GPU,等)。 更重要的是我们相信由Google推出的平台会很快为大家接受并迅速形成对应的开发生态圈和活跃的后续更新发展。后来的事实也证实了我们的料想。 下面表格比较了几种流行的平台,数据来源于今年二月份在arXiv发布的论文。
那时候, Caffe和Theano还是最活跃的开源开发社区,但到目前Tensorflow已有最多的开发者 。见下表:
总体来讲,TF给我的感觉不错,我相信Google产品的后发优势。
▎Tensorflow的优点和缺点是什么?
总的来说,Tensorflow提供的API对搭建神经网络有了足够的自由度。对于损失函数的构造也很直接,TF框架能自动计算任意构建的损失函数的导数。对模型参数的训练也提供了最新的一些算法可供选择。TF用户论坛也很活跃,有疑难问题也很快能从中得到帮助。
当然也有一些不足之处。例如如果要构造任意连接的神经网络,TF没有提高直接的工具,但有一个通过矢量转置的变通的办法来实现,但代价是训练和打分都十分的缓慢。
另一个不足之处是,对于实时的应用(需要对单个输入一个个单独计算打分),效率很低。例如,将一千个输入记录作为一个批处理交给TF打分要比分一千次每次计算一个记录要快100倍。这意味着后者(实时应用)比其前者的效率低了两个数量级。
▎它和ResNet的区别? 两个版本差别在哪里?
何恺明去年底提出的152层超深度的残差网络赢得了2015年度ImageNet竞赛的冠军,随后论文发表在arXiv上( "Deep Residual Learning for Image Recognition", by Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. (Dec. 10 2015) http://arxiv.org/abs/1512.03385 )。
今年七月同样在arXiv 上发表续集( "Identity Mappings in Deep Residual Networks", by Kaiming He, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. (July, 2016) http://arxiv.org/abs/1603.05027v3 )。 这里姑且叫前者ResNet I, 后者 ResNet II。 残差网络的出发点很简单,简洁性正是大受欢迎的原因。
起核心思想包含三个要素: 信息通路捷径,残差单元,残差单元输出与信息通路的合并 。数学表达为:
其中F为残差单元的操作,h(x) = x. ResNet I 与 ResNet II的差异在于其中的f 函数。如f是非线性变换,则为ResNet I, 如果f 为恒等变换则为ResNet II,见下图:
Figure 2a. The tensor flow chart of ResNet I.
Figure 2b. The tensor flow chart of ResNet II.
总结:ResNet I在信息合并后紧接非线性变换,而ResNet II则数非线性变换后在合并。
▎为何要在Tensorflow上搭建一个自己的基于 ResNet思想的网络?
首先,没有一个现成的网络构架能完全合乎我们问题的解决方案,这是实际需要。同时,要得到最好结果,必须对最新的研究成果广泛吸收,加以创新。对于为何在应用中要采用ResNet的思想我们得从理解ResNet为何能有效开始。尽管恺明有一点解释,但这里我给出不同角度的一个理解。 一个神经网络模型的精确度受两个竞争因素的影响:网络复杂度越高,模型的表达力越强,逼近最佳结果的潜力也越高 。
另一面,复杂度越高,从高维参数空间通过SGD方法寻求最佳解的困难也越大。可以将SGD优化类比从山上沿着山路下到山底谷的过程, 如图(图片来自网上):
Figure 3. Stochastic Gradient Descendent (SGD) method
可以这样理解:可以将优化问题理解为从山上凹凸不平的山路中寻找一条到达山谷的途径,山路崎岖,充满陷阱。只是相对于神经网络模型而言是在一个超高维(数百万维对于三维)的山上,而山路的崎岖复杂和陷阱的数量远超三维空间的情形。要成功下到山谷(或接近山谷),下山途中要尽量避免误入歧途,掉入陷阱,万一掉入也有机会逃去陷阱。ResNet的结构是在原有的网络基础上添加了一个信息通路捷径,从而可以向前跨越数层网络在一些特定层与原来的输出汇合,并作为下一个残差单元的输入。从数学直觉上看,这应该是势能面变得平坦一些,即使下山掉入陷阱,从中逃逸的机会也大些。
一旦理解了ResNet的思想就可以在其它网络构架中利用,而这个在Tensorflow上很容易实现 。
Tensorflow提供的Python API可直接用于网络的搭建。这些API非常直观,可以将网络结构的数学表达直接翻译成对应tf函数的调用(例如tf.nn.matmul, tf.nn.relu, tn.nn.l2_loss for L2 regularization,and tf.reduce_sum for L1 regularization)。由于TF能对任意损失函数自动计算导数,因此可以设计任何形式的损失函数和任意的网络结构,非常灵活。
ResNet 的引入,让我们可以建立超深度的神经网络而不必太担心训练模型中的收敛性的问题。即使对于不太深的网络,ResNet 仍可以改进收敛和改善精度。
▎Tensorflow使用中需注意的问题?
在使用Tensorflow上与其它框架没有特别的地方。不过有些问题对于神经网络的训练带有普遍性。
首先,训练神经网络往往有许多宏观控制参数,包括网络结构的深度,宽度,学习速率的选择及动态调节,正则化(Regularization)的类型和强度,迭代次数等。这些没有一个简单的标准怎样选区,通常只能通过不断试错才能找到最佳答案。模型中的参数初始化也很关键, 如选择不当,迭代会停滞不前。例如,如果优化陷入停滞不前,简单的解决办法就是对全体起始参数进行缩放。
Figure 4. Convergence is very sensitive to both learning rate and model initialization.
前一个图开始学习速率为0.002,模型训练收敛正常。第二个图开始学习速率为0.02,完全不收敛(欲速则不达)。
▎如何基于Tensorflow搭建新的神经网络架构?
在Tensorflow上搭建神经网络还是比较直接的,因为Tensorflow 提供了十分丰富的API (Python和C++),和搭建神经网络的各个组件,包括卷积网络构件,各种优化方法,各种损失函数的组合,正则化控制等。因此许多软件开发都可以基于Tensorflow提供的Python应用接口进行,因此在研发中可以快速实验不同的构架。
然而,也正是因为使用Python接口,对于特定应用这有可能成为效率的瓶颈。我目前还没有深入到C++底层修改Tensorflow。但从长远看进入底层的扩展是必要的,特别是对特定应用进行效率优化。 例如,对于一个实时应用来说,要求能够对于每一个单独的输入快速响应,返回结果。我们发现,虽然Tensorflow GPU版本能够高速批处理打分(batch scoring),如果同样的数量单独一个个处理,效率可能会慢两个数量级,这对于实时应用是个问题。解决之道可以单独编写一个高效率的打分函数,而不必依赖Tensorflow。
▎之前你提到你们搭建的网络架构不同于卷积神经网络,所以采用了ResNet的思想。ReNet思想是指?
这个问题要这样看:残差网络(ResNet) 和卷积神经网络( ConvNet) 之间是平行概念,互不排斥。
ResNet的基本思想可以和卷积神经网络结合,也可和其它任何类型的神经网络结合。ResNet的核心思想是在不改变网络表达力和复杂度的情形下改变损失函数势能面的状况,从而使优化到最佳点的途径变得顺利些。
▎如何根据自己需求开发深度学习产品?
这个问题很大,有些笼统。总的来说,并非所有应用都需要用深度学习。能用简单模型解决的问题绝不用复杂的深度模型。例如如果问题能用线性模型就能得到很好的结果,那么用深度神经网络就没必要,因为简单模型的效率要高很多。但如果问题是高度非线性,而且各个变量之间存在强烈耦合,那么这时用神经网络可能是一个好的选择。但即使如此,也要从简单的网络开始入手,例如3-6层网络,然后逐渐增加层数,仔细观察是否有改进空间。由于SGD优化结果带有一定的误差和不确定性,每次Tensorflow优化的结果会有g一定的差别,因此观测增加层数是否改进模型精度时要小心,要重复多次运算,取平均值,然后做比较。这样做对于样本数较少时尤为重要。
▎如何 根据自己需求在深度学习中做算法创新?
这个问题很大,应该问Jeff Hinton 或Yan LeCun 等大牛。但一些通常的创新思维方式还是值得借鉴的。我认为,首先要对问题有透彻的理解。例如我门希望对卷积神经网络是怎样工作的,近几年不断改进的算法是如何提高模型精度的有深入的认识,不仅如此,我们还要对反方向的研究结果有所理解。例如,Szegedy 等人的研究表明,在一个能被DNN模型完全正确识别的图片(如狮子)加入人眼难以擦觉的噪声,然后再让计算机识别,会认为是一个完全不同的类别。
还有最近Yoshinski 的研究表明利用一训练好的DNN模型可以从完全无规的电视机雪花噪声图片(完全没有任何意义),通过对图象优化使得DNN以很高的置信度(99.99%)认为是某个特定动物(如熊猫或啄木鸟等)而得到的图像仍然如同一片噪声,完全看不出任何有意义的模样。
如果我们能从数学上理解这些现象那么我们必将产生更新的思想,引导我们尝试新的网络结构,从而发现更有效,更精确,更鲁棒的算法来。但是,对于这些问题我们目前还了解得不透,而恰恰是因为这样,还有许多创新空间等待我们发现。另外, 目前关于图像识别的大多数算法几乎都是基于卷积神经网络。是否有其它途径,使得我们即使利用较少的样本也可以训练出很好的模型,如同人类认知能力一样? 这值得我们深思!
▎怎么根据自己的需求改进神经网络?
怎样跟据自己需求改进网络架构这个问题比较泛。大致讲要根据自身应用问题的特殊性调整。例如,卷积神经网络主要用于图像识别,因为图像中的每个像素都与其邻近像素关连,而全部的这种关联,空间关系决定了一个图像的表征。卷积神经网络的设计就是为了提取这些特征,并通过大量例子训练模型。
而有些问题,其变量之间的相互作用关系不明确,无法套用卷积神经网络。这时可以采用全连接网络,或根据已知或猜测到的相互作用关系建立网络连接(这样可大大减少参数量)。实际应用中还涉及模型的效率(速度)问题。 如果一个神经网络过大,无论是训练还是用于打分都会较慢,如需提速,必须减少模型的大小。
▎如何利用GPU加速?请举例说明。
对于Tensorflow,其GPU加速已在其核心构架的底层已经实现了。对于所有关神经网络运算都有对应的GPU版本,因此从开发者的角度看,Tensorflow 实际上已将开发者从GPU编程的痛苦中解救出来了。因此,利用GPU加速变成了仅仅是一个安装的问题。
如果你有GPU机器,装载支持GPU的Tensorflow版本即可。CPU/GPU版本从API的角度是透明的,同样的PYTHON代码可以在CPU/GPU两个版本上运行。
不过安装GPU版本时有一点要注意:Tensorflow默认要求GPU卡的运算能力为3.5或以上。如果你的GPU的运算能力为3.0(相当普遍),那么默认安装会有问题。这时要从源代码进行编译安装,并且要在编译时的计算能力选项参数设为3.0。目前Amazon云计算提供的GPU还是3.0,所以在Amazon 上安装Tensorflow 要从源代码开始编译安装。Tensorflow支持多GPU,但相应的代码要修改,因为要对任务的分配进行编程。 我们比较了一个32核CPU与一个单片GPU机上Tensorflow 运行的速度做个比较。GPU机器大约是32核CPU机器速度的4倍。
▎你是如何多年坚持科研并将成果引入到软件创新中的?
多年坚持将学术成果引入到软件创新中需要有很大的热情。
我一直保持着学术研究的兴趣,尤其是与实际应用相关的问题, 其目的就是要将突破性研究成果融入到新产品的开发之中。 例如,2006获得了公司奖励的学术休假,使得我有几个月自由科研的机会,也正是在此期间发明了恺撒(CAESAR)算法,提高了三维分子结构模拟的效率达十倍以上,并作为药物分子设计的一个核心模块广泛应用于各大制药公司的药物研发中。从2008年以来开始与中山大学,除了给国内的研究生远程授课外,每年也回国一两次讲学,并指导研究生的课题。
另一成功案例:WEGA(三维几何形状比较的高斯权重)算法。
工业应用:药物分子的计算机辅助设计
问题痛点:超大规模分子库三维数十亿个分子形状的比较计算量巨大而费时。
合作研究:与中山大学药学院合作,组建了一个攻关团度,包括博导和其学生。
解决方案:分三步:1)新算法,2)GPU加速, 3)GPU集群的大规模并行。
研究成果:
1)算法方面,提出了比较分子三维形状的WEGA(高斯权重)算法,大大提高了计算精度同时保留了计算的简洁性和高效率。
2)指导中大博士生开发了利用GPU加速的GWEGA,使得单片GPU即可提高近100倍的加速。
3 )利用广州超算中心的GPU集群实现了大规模GPU并行,将TB数量级的超大规模分子库的三维结构检索移植到GPU集群中,实现了1亿次/秒的高通量药物分子虚拟筛选,比国际竞争对手快了近两个数量级。这一成果我们申请了中国和国际专利。
难点:这个项目的难点是GPU编程。GPU编程的门槛较高,尤其是要达到高效率,特别是要达到近100倍的加速,对编程技巧有苛刻的要求。为此,外特地为中东研究生开设了GPU编程课,让学生很快入门,进而对GPU架构有深入的理解,关键地方和学生一同探讨,对每行代码逐条分析优化,将效率推行极致。这个过程不仅培养了学生,同时也使难题得以解决。
▎群友提问:除了图像之外,对于其它有一定相互关联性的信号,是否都可以借鉴卷积网络,比如一些时间上有一定关联的信号的机器学习?
可以,但比较麻烦,因为你不知道怎样归类,对于音频完全可以,时间和频率构成二维图像。