查看原文
其他

百度:深度学习模型设计的经验分享

刘凡平 IT大咖说 2022-07-14



内容来源:2018 年 05 月 18 日,百度资深研发工程师刘凡平在“百度深度学习公开课·杭州站:AI工程师的快速进阶之路”进行的《深度学习模型设计经验分享》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:3633 | 10分钟阅读


摘要

本次演讲将从数据准备、模型结构、优化方法、计算性能这四个方面,来探讨深度学习模型设计的一些经验。


获取嘉宾演讲视频及PPT,扫一扫下方二维码即可。



研发流程简述


以个人经验来看,一般性的研发流程大致可分为8步。


  1. 问题分析,确定需求

  2. 数据分析,确定现有数据的价值(主要依据特征及分布)

  3. 特征抽取,根据数据的价值和需要解决的问题,确定特征

  4. 数据准备,在前三步都完成的情况下,准备训练集、测试集合、验证集合

  5. 模型分析,根据问题的输入和输出,确定选择的模型

  6. 参数训练,不断迭代模型直至收敛

  7. 验证调优,验证模型的各项指标,使模型达到最佳状态

  8. 应用上线,以离线或在线的方式对外提供服务


整个流程中,模型设计的动机和目标非常重要。其中包括需求与问题的定义、建立问题的数学模型、确定数据与求解问题之间的关系、探索问题解的可能性、目标的可实现性与可评估性。


经验之数据准备


充分的数据


对于模型设计首先要有充分的数据,分为两个层面。第一是数据特征,用于确定能否达成模型设计的目标,特征应当具备一定的“因果关系”,分布要有“导向性”。第二数据集应当尽可能多,DNN需要大量的数据,而且模型在小的数据集上容易过拟合。建议如果条件允许可以尝试扩展原始的数据集合。


数据预处理


数据预处理对很多业内人员来说是个令人头疼的问题,针对不同场景有不同的解决方案。


简单介绍几种常见的方式。首先是去均值处理,即用原始数据减去全部数据的均值,把输入数据各个维度的数据都中心化为0。去均值处理后,特征虽然明显了,但是特征之间的相互比较性尚未明确,因此要用到归一化处理,把每个维度上的数据都除以这个维度上的数据的标准。另外还有一种适使用于图像处理的方式PCA/Whiteing(白化),图像中相邻像素点之间的特征极为相似,无法轻易做到收敛。而PCA可以去除这些相邻特征的相关性,达到快速收敛的目的。


数据的shuffle


每次epoch的时候都会有很多的batch,一般情况下这些batch都是相同的,但理想状态是每次epoch都有不同的batch。因此如果条件允许就应该在每次epoch的时候shuffle(随机化)一次,以获取不同的batch。


经验之模型结构


隐藏层神经元估算


BP神经网络对于单层的感知器网络新增了隐藏层,隐藏层数量的选择目前还不具备理论支持。


在多层感知器中,确定的是输入和输出层中的节点数量,隐藏层节点数量是不确定的,并对神经网络的性能有影响。对此我们可以使用经验公式来计算

h表示隐藏层数量,m是输入层,n是输出层,a为取值1~10的范围值。最后h的结果也在一个范围值内,一般建议取该范围中为2的n次方的值。


权重初始化策略


权重合理初始化能够提升性能并加快训练速度,对于权重而言,建议统一到一定区间内。


线性模型区间建议为[-v, v],v=1/sqrt(输入层尺寸),sprt表示开根号。卷积神经网络的区间和公式同样类似,不过最后的输入层尺寸要改为卷积核的宽度*卷积核的高度*输入深度。


有效调整激活函数


Sigmoid以及Tanh函数的代价非常昂贵,容易饱和从而导致梯度消失,并且可能会停止方向传播。实际上,网络模型的层级结构越深,就越应避免使用Sigmoid和Tanh函数。可以使用更简单而且更高效的ReLU和PReLU的激活函数。


ReLU是非常有用的非线性函数,可以解决很多问题。不过由于ReLU阻碍反向传播,初始化不好,所以用它微调模型的时候,没法得到任何微调效果。建议使用PReLU以及一个非常小的乘数(通常为0.1),这样收敛会更快,而且不会像ReLU那样在初始化阶段被卡住。此外ELU也很好,但成本较高。


实际上ReLU是Maxout的一种特例。Maxout是一个可以学习的激活函数,主要工作方式是选择每组中最大的数作为输出值。如下图,以两个元素为一组,5和7,-1和1,最终得到7和1。



模型拟合能力验证


模型过拟合相信很多人都遇到过,也由此引出了很多问题,不过从另一个及角度来看过拟合是有必要存在的——可以用它来做模型的验证。因为复杂模型下大规模样本的训练需要耗费大量的时间,从而导致开发成本上升。


我们可以在使用全量数据集上训练之前,先在随机抽样的子集上进行过拟合验证,如果过拟合现象发生,则可以推断网络模型收敛的可能性较高。


注重Loss的设计


Loss的设计要注重其合理性,简单直接的体现模型的终极目标,有合理的梯度,能够被求解。另外不要过于关注Accuracy(评测指标),而忽视了训练过程中Loss的设计。


经验之优化方法

学习速率优化方法



已知调节学习速率也能带来效果的提升,上图是不同速率下Loss曲线的情况,很明显最优的速率应该是让Loss曲线平滑向前(红色曲线)。在对学习速率进行调参的时候可以参考这张图。


卷积核大小优化


几个小的卷积核叠加在一起,相比一个大的卷积核,与原图的连通性不变,但却大大降低了参数的个数以及计算复杂度。因此我们推荐“小而深”的模型,避免“大而短”。小的卷积核还能代替大的卷积核,比如一个5*5的卷积核可以用两个3*3的卷积核代替,一个7*7的卷积核可以用三个3*3的卷积核代替。


一般优化方法选择


学习率与训练步骤、batch大小和优化方法都有耦合关系,常见的优化方案是自适应学习速率(RMSProb、Momentum、Adam等),使用自适应优化算法,自动更新学习速率。也可以使用SGD手动选择学习率和动量参数,此时随着时间的推移学习率会降低。实际使用中,自适应优化倾向于比SGD更快收敛,最终表现通常相对较差。


一般而言,对于高性能训练较好的做法是从Adam切换到SGD。不过由于训练的早期阶段是SGD对参数调整和初始化非常敏感的时候,因此可以使用Adam进行最初的训练,这样不仅节约时间,且不必担心初始化和参数调整。当Adam运行一段时间后,再切换到SGD加动量优化,以达到最佳性能。


当然对于稀疏数据,建议应尽量使用学习可自适应的优化方法。


效果可视化


通常卷积神经网络的卷积层的weight可视化出来会具备smooth的特性。下面两者图都是将一个神经网络的第一层卷积层的filter weight可视化出来的效果。如果出现左边的这种情况,可能就需要考虑下模型有哪些地方设计的有问题。



经验之计算性能


计算性能分析方法


计算平台有两个重要的指标,算力和带宽。算力表示计算平台的性能上限,指的是一个计算平台倾尽全力每秒钟所能完成的浮点运算数,单位是FLOP/s。带宽指的是计算平台倾尽全力每秒钟所能完成的内存交换量,单位是Byte/s。算力除以带宽可得到计算平台的强度上限,即单位内存交换最多用来进行多少次计算,单位是FLOP/Byte。


模型同样有两个重要指标,计算量和访存量。计算量指的是输入单个样本,模型进行一次完整的前向传播所发生的浮点运算个数,也即模型的时间复杂度,单位是FLOPS。访问量指的是输入单个样本,完成一次前向传播过程中发生的内存交换量,即模型的空间复杂度,数据类型通常为float32。


我们来看一个模型计算性能示例。假设有两个矩阵A、B,它们均是1000*1000,数据类型为float32,计算C=A*B。则该计算会进行1000*1000*1000的浮点乘、加,约2G FLOPS的计算量。该过程中会读A、B两个矩阵,写C矩阵,至少要访问三次存储器,约12MB。


这样简单的1000*1000的矩阵就要花费12MB,可以想象更复杂的模型会耗费多少资源。正是基于这种对计算性能的考虑,在选择模型的时候不一定非要选深度学习的,空间和时间的复杂度对模型也有很大的影响。在模型选择上,可以先尝试线性模型、树相关的模型,不适合的话再使用传统机器学习中的经典模型,最后才是神经网络模型。


Dropout & 分布式训练


根据我们的经验,在单层节点数量大于256个时,无论是全连接层或卷积层都建议使用Dropout。


以个人接触过的开发者来看,很多人并不是特别重视分布式训练,大部分情况都是单机运行高性能显卡,但分布式的训练效率可能会更高些,可以考虑向这方面靠拢。


以上为全部分享内容,谢谢大家!


 IT大咖说  |  关于版权 

本文由“IT大咖说(ID:itdakashuo)”原创,转载时请注明作者、出处及微信公众号。投稿、约稿、转载请加微信:ITDKS10(备注:投稿),茉莉小姐姐会及时与您联系!

感谢您对IT大咖说的热心支持!


相关推荐


推荐文章


点击【阅读原文】 打开干货通道

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存