11. 深度学习实践:实践方法论

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/niaolianjiulin/article/details/79148500

掌握了算法和基本原理,要达到知行合一,还需要一套实践方法论:实践中如何针对应用选择算法,决定是否要收集更多数据等。正确地使用一个算法,比草率使用一个不清楚的算法效果更好。Ng提出了很多好的建议,将在以下体现。

建议的实践设计流程:

  • 确定目标:误差度量
  • 建立end-to-end的工作流程
  • 搭建系统,查明性能瓶颈
  • 根据观察反复增量式改动,如调整超参数等

1. 性能度量

度量一个模型完整应用的有效性:性能度量。不同于训练模型的代价函数(均方误差/交叉熵),通常使用准确率,错误率,以及更高级的度量。

举例:设计一个罕见疾病检测系统,该病每百万人中仅一例患者。如果分类器考虑准确率,那么让该系统一直报告没有患者,轻易的可实现99.99%的正确率。但这样做显然没有意义。解决办法:精度和召回率。组合起来用PR曲线(包含面积越大模型效果越好),或者 F-score (越大越好)。

覆盖率(coverage):ML系统能够产生响应的样本所占比例。权衡覆盖和精度。一个系统可拒绝任意样本来达到100%的精度,但覆盖降为0。对于某项任务,希望系统达到人类级别的精度,同时保持95%的覆盖。人类可达性能是98%精度。

当然还有很多其他的。2017年TSA比赛中打榜的性能度量是 logloss (越小越好)。

2. 默认的基准模型

确定性能度量和目标后,下一步工作是尽快建立一个合理的端对端系统。本节讨论:不同情况下,使用哪种算法作为第一基准方法的推荐。

(1)问题复杂性。若只需几个线性权重可解决问题,则无需使用DL,LR就行。若问题属于“AI完全”类的,如图像识别等,则开始就上DL模型,效果会比较好。

(2)根据数据结构选择合适模型。若是固定大小的向量来输入的监督学习,选择全连接FNN。若是图像,选择CNN。若是序列,选择GRU/LSTM。

(3)优化算法选择。具有衰减学习率和动量版本的SGD很合理。Adam算法也很合理。基准模型要不要上批标准化?

(4)正则化。提前终止?Dropout?上不上?

(5)有无先例可循?若和一个广泛研究的任务相似,可复制先前研究中表现良好的模型。如通常用 ImageNet 上训练好的CNN的特征来解决其他CV任务。

3. 决定是否收集更多数据?

上述5点是搭建第一个基准模型时要考虑的。然后就可搭建出第一个基准模型。然后就可度量算法性能,并决定如何改善算法。新手都忍不住尝试很多不同算法改进(我们在TSA比赛中轮上不同模型和算法),老司机却可能会去收集更多的数据。

首先确定训练集上的性能是否可接受。如果很差,则说明学习算法不能在其上学习出良好的模型,没必要搞更多数据。这时可先尝试上个更大的模型,尝试仔细调试优化算法。如果效果仍不佳,那问题可能源自训练数据的质量。这时可考虑重新收集更干净的数据。

若训练集上还可以,则度量测试集上性能。测试集上若可以,则OK。测试集上若差得远,则收集更多数据是有效途径之一。这时考虑:(1)收集的代价和可行性(2)其他方法降低误差的可行性(3)增加数据能否显著提升性能。一个替代办法是降低模型大小,或改进正则化,若如此仍有巨大的gap,则收集更多的数据吧。

确定收集多少数据?可根据训练集规模和泛化误差间的关系大致估计(见下图)。

这里写图片描述

通常加入一小部分的样本不会对泛化误差产生显著影响。建议在对数尺度上考虑训练集的大小,例如倍增样本数目。

4. 超参数

选择超参数的基本方法:

  • 手动选择:需要了解超参数到底做了什么(艺高人胆大)
  • 自动选择:不需要想,但需要更高的计算成本

4.1 手动调整超参数

目标:调整模型的有效容量以匹配任务的复杂性。

容量:模型能够表示更复杂函数的能力。

对于某些超参数,数值太大时会发生过拟合。例如中间层隐藏单元的数量。学习率可能是最重要的超参数。调整学习率外的其他参数时,需要同时监测训练误差和测试误差,以判断模型是否过拟合或者欠拟合,然后适当调整容量。

大部分超参数可通过推理其是否增加或减少模型容量来设置。如隐藏单元数量增加,模型容量会增加,同时计算代价增加。权重衰减系数降低,容量增加,因为模型此时参数可以自由变大。

手动调整超参数的目标:提升测试集性能。只要训练误差低,随时可以收集更多训练数据来减少泛化误差

4.2 自动超参数优化算法

流行的LR或者SVM,只有一到两个超参数需要调整,这还好说,NN动辄有较多的超参数。使用者如果没有几年的调参经验,那么手动调就是瞎折腾。能不能有自动算法,找到合适的超参数呢?

原则上,我们是有可能开发出封装学习算法的超参数优化算法,让使用者不用指定学习算法的超参数。但是,遗憾的是,超参数优化算法,本身又有自己的超参数,比如你需要为每个超参数指定被探索的值的范围,仍然需要人去指定。但是,这些次级超参数通常很容易选择,还是让问题变得好办点(超参数的大循环,包含学习算法的小循环)。

4.3 网格搜索

不是初次见面,老朋友了。从2017年3月起,就在CRF求解中对超参数的选取用的是Grid Search之法。

当有3个或者更少的超参数时,对于每个超参数,选择一个较小的有限值集去探索。这些超参数笛卡尔积得到一组组超参数,然后网格搜索:使用每组值训练模型,挑选验证集误差最小的一组值为最好的超参数。

通常,网格搜索大约在对数尺度上。如学习率的取值集合是 {0.1,0.01,0.001,0.0001,0.00001} 。通常,重复进行搜索效果会最好。例如,在集合 {1,0,1} 找到的最佳值是1,说明低估了最优值所在范围,可继续在 {1,2,3} 中搜索。或者细粒度上继续搜索。

问题:计算代价随着超参数数量呈指数级增长。ps:这个有切身体会,当时CRF超参数中搜索5个参数,每个有5个左右的取值,共需要进行3000多次训练,一次需要50分钟,因为只有一台主机,跑完需要3个月!最后没办法硬把参数取值降下来,有的取3个值,这样确保3-4天跑一趟。后来想到搞个较小的验证集来测试超参数也可以,取了200张图片来做。

4.4 随机搜索

替代网格搜索的方法,简单方便:随机搜索。(2012 Bengio)。

为每个超参数定一个边缘分布,例如伯努利分布,或者对数尺度上的均匀分布,例如对学习率的指数进行均匀采样:

这里写图片描述

和网格搜索不同,这时不需要离散化超参数的值,这允许在一个更大的集合上搜索,而不产生额外的计算代价。

这里写图片描述

当有几个超参数对性能度量没有显著影响时,随机搜索比网格指数级的高效。原因:没有浪费的实验。上图左边中,给定横轴超参数值,网格会对纵轴超参数的3个不同值给出相同结果,其实造成浪费。但是右边的随机搜索中,每次超参数通常具有不同值,每次都是独立的探索。(网格设定比较死,随机搜索中人为更少的干预)

4.5 基于模型的超参数优化

简化设定下,可以计算验证集上可导误差函数关于超参数的梯度。但是,大多数下梯度不可用。可能是因为高额的计算代价和存储成本,也可能是压根儿就不可导。

为了弥补梯度的缺失,可对验证集误差建模,然后通过优化该模型来提出新的超参数猜想。大部分基于模型的超参数搜索算法,均使用贝叶斯回归模型,来估计每个超参数的验证集误差期望和该期望的不确定性,但这涉及到探索。时而表现得像人类专家,时而爆炸了,不够成熟稳定。

大部分超参数优化算法比随机搜索更复杂,且缺点是在它们能够从实验提取任何信息前,需要运行完整的训练实验。手动搜索通常很早判断出超参数是否是病态的。

5. 调试策略

当ML系统效果不好时,通常很难判断原因是来自算法本身,还是算法实现错误,总之,很难调试。我们不能提前知道算法的行为,当测试误差是5%时,不晓得这是期望值还是次优值。一些重要的调试策略:

  • 可视化计算中模型的行为:实际中很容易量化性能度量。很有用,及早做出判断。调试CRF代码时不断可视化生成图片,开始是奇奇怪怪的,想为什么会这样,然后对症下药调试。
  • 可视化最严重的的错误:实际上模型的较小概率不太可能对应着正确的标签,因此可利用这一点。比如根据置信度将图像排序,确定置信度最高的错误,可能会找到些问题的。

根据训练和测试误差找线索,训低测高,很可能训练正常,但模型过拟合了。或者测试数据和训练数据预处理方式不同。或者测试误差没有被正确度量。训高测高,有可能软件错误,或者模型欠拟合。需要下列的进一步测试。

  • 拟合极小的数据集:训高测高,有可能软件错误,或者模型欠拟合。通常即使小模型也可很好的拟合一个足够小的数据集。例如,如果不能训练一个分类器来正确标注一个单独的样本,则很有可能是软件错误。
  • 比较反向传播导数和数值导数:若软件中实现梯度计算,则常见错误是没能正确实现梯度表达。这点暂不用考虑,因为caffe,TF等框架中均有BP操作接口。
  • 监控激活函数值和梯度的直方图:激活函数值指示出某单元是否饱和,饱和频率如何。梯度快速增长或消失,将对优化不利。2015年有建议说我们希望参数在一个小批量更新中变化幅度是参数量值的1%,而非50%或者0.001%。

6. 实例:数字识别

光学字符识别,Optical Character Recognition,OCR。

本书11.6章节用一个“街景转录系统”设计与实现,来串起本章的整个过程。

猜你喜欢

转载自blog.csdn.net/niaolianjiulin/article/details/79148500