卷积神经网络的工程技巧总结

要成功地使用深度学习算法,仅仅知道存在哪些算法和解释它们为什么有效的原理是不够的。一个优秀的机器学习实践者还需知道如何针对具体应用挑选一个合适的算法以及如何监控,并根据实验反馈改进机器学习系统。在机器学习系统的平常开发中,实践者须要决定是否收集更多的数据、增长或减小模型容量、添加或删除正则化项、改进模型的优化、改进模型的近似推断或调试模型的软件实现。尝试这些操做都须要大量时间,所以肯定正确的作法,而不盲目猜想尤其重要。在实践中,正确使用一个普通算法一般比草率地使用了一个不清楚的算法效果更好。正确应用一个算法须要掌握一些至关简单的方法论。算法

建议参考如下几个实践设计流程:数据库

  • 肯定目标------使用什么样的偏差度量,并为此偏差度量指定目标值。这些目标和偏差度量决定于该应用旨在解决的问题。
  • 尽快创建一个端到端的工做流程,包括估计合适的性能度量。
  • 搭建系统,并肯定性能瓶颈。检查哪一个部分的性能差于预期,以及是不是由于过拟合、欠拟合,或者数据或软件缺陷形成的。
  • 根据具体观察反复地进行增量式的改动,如收集新数据、调整超参数或改进算法。

将使用街景地址号码转录系统做为一个运行示例。该应用的目标是将建筑物添加到谷歌地图。街景车拍摄建筑物,并记录与每张建筑照片相关的GPS坐标。卷积网络识别每张图片上的地址号码,由谷歌地图数据库在正确的位置添加该地址。这个商业应用是一个很好的示例,它的开发流程遵循上述方法。编程

1.性能度量

肯定目标,即便使用上面偏差度量,是必要的第一步,由于偏差度量将指导接下来的全部工做。同时也应该了解大概能获得什么级别的目标性能。安全

值得注意的是,对于大多数应用而言,不可能实现绝对零偏差。即便你有无限的训练数据,而且恢复了真正的几率,贝叶斯偏差仍定义了能达到的最小错误率。这是由于输入特征可能没法包含输出变量的完整信息,或者由于系统可能本质上是随机的。固然咱们还会受限于有限的训练数据。网络

训练数据的数量会由于各类缘由受到限制,当目标是打造显示世界中的产品或服务时,咱们一般须要手机更多的数据,但必须肯定进一步减小偏差的价值,并与收集更多数据的成本作权衡。数据收集会耗费时间、金钱、或带来人体痛苦(例如,收集人体医疗测试数据)。科研中,目标一般是在某个肯定基准下探讨哪一个算法更好,通常会固定训练集,不容许收集更多的数据、架构

如何肯定合理的性能指望呢?在学术界,一般咱们能够根据先前公布的基准结果来估计预期错误率。在现实世界中,一个应用的错误率有必要是安全的。具备成本效益或者吸引消费者的。一旦你肯定了想要达到的错误率,那么你的设计将由如何表达这个错误率来指导。app

除了须要考虑性能度量以外,另外一个须要考虑的是度量的悬着。咱们有几种不一样的性能度量,能够用来度量一个含有机器学习组件的完整应用的有效性。这些性能度量一般不一样于训练模型的代价函数。然而,许多应用须要更高级的度量。框架

有时,一种错误可能会比另外一种错误更加验证。例如,垃圾邮件检测系统会有两种错误:将正常邮件错误地归为垃圾邮件,将垃圾邮件错误地归为正常邮件。阻止正常消息比容许可疑消息经过糟糕的多。咱们但愿度量某种形式的总代价,其中拦截正常邮件比容许垃圾邮件经过的代价更高,而不是度量垃圾邮件分类的错误率。机器学习

有时须要训练检测某些罕见事件的二元分类器。例如,可能会为一种罕见疾病设计医疗测试。假设每一百万人人中只有一我的患病。咱们只须要让分类器一直报告没有患者,就能轻易地在检测任务上实现99.9999%的正确率。显然,正确率很难描述这种系统的性能。解决这个问题的方法是度量精度(precision)和召回率(recall)。精度是模型报告的检测正确的比率,而召回率是真实事件被检测到的比率。检测器永远报告没有患者,会获得一个完美的精度,而召回率则是真实事件被检测到的比率。检测器永远报告没有患者,会获得一个完美的精度,但召回率为零。而报告每一个人都是患者的检测器会获得一个完美的召回率,可是精度会等于人群中患有该病的比例(在咱们的例子中是0.0001%,即每一百万人只有一个患病)。当使用精度和召回率是,一般会画PR曲线(PR curve),y轴表示精度。x轴表示召回率。若是检测到的事件发生了,那么分类器会返回一个较高的得分。例如,咱们将前馈网络设计为检测一种疾病,估计一个医疗结果由特征x表示的人患病的几率为\hat{y}=P(y=1|x)。每当这个得分超过某个阈值时,咱们报告检测结果。经过调整阈值,咱们能权衡精度和召回率。在不少状况下,咱们但愿用一个数而不是曲线来归纳分类器的性能。要作到这一点,咱们能够将精度p和召回率r转换为F分数(F-score)函数

                                                                           F=\frac{2pr}{p+r}

另外一种方法是报告PT曲线下方的总面积。

在一些应用中,机器学习系统可能会拒绝作出判断。若是机器学习算法可以估计所做出的判断的置信度,这将会很是有用,特别是在错误判断会致使严重危害,而人工操做员可以偶尔接管的状况下。街景转录系统能够做为这种状况的一个示例。这个任务时识别照片上的地址号码,将照片拍摄地点对应到地图上的地址。若是地图是不精确的,那么地图的价值会严重降低。所以只在转录正确的状况下添加地址才十分重要。若是机器学习系统认为它不能太能像人同样正确地转录,那么最好的办法固然是让人来转录照片。固然,只有当机器学习系统可以大量下降须要人工操做处理的图片时,它才是有用的。在这种状况下,一种天然的性能度量度。一个系统能够经过拒绝处理任意样本的方式来达到100%的精度,可是覆盖降到了0%。对于街景任务,该项目的目标是达到人类级别的转录精度,同时保持95%的覆盖。在这项任务中,人类级别的性能是98%的精度。

还有许多其余的性能度量。例如,我么能够度量点击率、收集用户满意度调查等。许多专业的应用领域也有特定的标准。最重要的是首先要肯定改进哪一个性能度量,而后专心提升性能度量。若是没有明确的目标,那么咱们很难判断机器学习系统上的改动是否有所改进。

2.默认的基准模型

肯定性能度量和目标后,任何实际应用系统的下一步是尽快创建一个合理的端到端的系统。下面提供了关于不一样状况下使用哪一种算法做为第一基准方法的推荐。

根据问题的复杂性,项目开始时可能无须使用深度学习。若是只需正确地选择几个线性权重就可能解决问题,那么项目能够开始于一个简单的统计模型,如逻辑回归。

若是问题属于“AI-彻底”类的,如对象识别、语音识别、机器翻译等,那么项目开始于一个合适的深度学习模型,效果会比较好。

首先,根据数据的结构选择一类合适的模型。若是项目是以固定大小的向量做为输入的监督学习,按摩可使用全链接的前馈网络。若是输入已知的拓扑结构(例如,输入的是图像),那么可使用卷积网络。在这些状况下,刚开始可使用某些分段线性单元(ReLU或者其扩展,如Leaky ReLU、PReLU和maxout)。若是输入或输出是一个序列,可使用门控循环网络(LSTM或GRU)。

具备衰减学习率以及动量的SGD是优化算法一个合理的选择(流行的衰减方法有,衰减到固定最低学习率的线性衰减、指数衰减,或每次发生验证错误停滞时将学习率下降2~10倍,这些衰减方法在不一样问题上好坏不一)。另外一个很是合理的选择是Adam算法。批标准化对优化性能有着显著的影响,特别是对卷积网络和具备sigmoid非线性函数的网络而言。虽然在最初的基准中忽略批标准化是合理的,然而当优化彷佛出现问题时,应该当即使用批标准化。

除非训练集包含数千万以及更多的样本,不然项目应该在一开始就包含一些温和的正则化,提早终止也被广泛采用。Dropout也是一个很容易实现,且兼容不少模型和训练算法的出色正则化项。批标准化有时也能下降泛化偏差,此时能够省略Dropout步骤,由于用于标准化变量的统计自己就存在噪声。

若是咱们的任务和另外一个被普遍研究的任务类似,那么经过复制先前研究中已知性能良好的模型和算法,可能会获得很好的小狗,甚至能够从该任务中复制一个训练好的模型。例如,一般会使用在ImageNet上训练好的卷积网络的特征来解决其余计算机视觉任务。

一个常见的问题是项目开始时是否使用无监督学习,在某些领域,好比自认语言处理,可以大大受益于无监督学习技术。如学习无监督词嵌入。在其余领域,如计算机视觉,除非在半监督的设定下(标注样本数量不多),五千无监督学习并无带来益处。若是应用所在环境中,无监督学习被认为是很重要的,那么将其包含在第一个端到端的基准中。不然,只有在解决无监督问题时,才会第一次尝试时使用无监督学习。在发现初始基准过拟合的时候,能够尝试加入无监督学习。

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

在创建一个端到端的系统后,就能够度量算法性能并决定如何改进算法。许多机器学习新手都忍不住尝试不少不一样的算法来进行改进。然而,收集更多的数据每每比改进学习算法要有用得多。

怎样判断是否要收集更多的数据?首先,肯定训练集上的性能是否可接受。若是模型在训练集上的性能就不好,学习算法都不能在训练集上学习出良好的模型,那么就不必收集更多的数据。反之,能够尝试增长更多的网络层或每层增长更多的隐藏单元,以增长模型的规模。此外,也能够尝试调整学习率等超参数的措施来改进学习算法。若是更大的规模和仔细调试的优化算法效果不佳,那么问题可能源自训练集数据的质量。数据可能含太多噪声,或是可能不包含预测输出所需的争取输入。这意味着咱们须要从新更新开始,收集更干净的数据或是收集特征更丰富的数据集。

若是训练集上的性能是可接受的,那么咱们开始度量测试集上的性能。若是测试集上的性能也是能够接受的,那么久顺利完成了。若是测试集上的性能比训练集的要差得多,那么收集更多的数据是最有效的解决方案之一。这时主要的考虑是收集更多数据的代价和可行性,其余方法下降测试偏差的代价和可行性,以及增长数据数量可否显著提高测试集性能。在拥有百万甚至上亿用户的大型网络公司,收集大型数据集是可行的,而且这样作的成本可能比其余方法要少不少,因此答案几乎老是收集更多的训练数据。例如,收集大型标注数据集是解决对象识别问题的主要因素之一。在其余状况下,如医疗应用,收集更多的数据可能代价很高或者不可行。一个能够替代的简单方法是下降,模型大小或者是改建正则化(调整超参数,如权重衰减系数,或是加入正则化策略,如Dropout)。若是调整正则化超参数后,训练集性能和测试集性能之间的差距仍是不可接受,那么收集更多的数据时可取的。

在决定收收集更多的数据时,也须要肯定收集多少数据。根据走势曲线,能够预测还需多少训练数据来达到必定的性能。一般,加入总数目一小部分的样本不会对泛化偏差产生显著的影响。所以,建议值对数尺度上考虑训练集的大小,例如在后续的实验中倍增样本数目。若是手机更多的数据是不可行的,那么改进泛化偏差的惟一方法是改进学习算法自己。这属于研究领域,并不是对应用实践者的建议。

4.选择超参数

大部分深度学习算法都有许多超参数来控制不一样方面的算法表现。有些超参数会影响算法运行的时间和存储成本,有些超参数会影响学习到的模型质量以及在新输入上推断正确结果的能力。有两种选择超参数的基本方法:手动选择和自动选择。手动选择超参数须要了解超参数作了些什么,以及机器学习模型如何才能取得良好的泛化。自动选择超参数算法大大减小了了解这些想法的须要,但它们每每须要更高的计算成本。

1.手动调整超参数

手动设置超参数,咱们必须了解超参数、训练偏差、泛化偏差和计算资源(内存和运行时间)之间的关系

手动搜索超参数的目标一般是最小化受限于运动时间和内存预算的泛化偏差。咱们不去探讨如何肯定各类超参数对运行时间和内存的影响,由于这高度依赖于平台。

手动搜索超参数的主要目标是调整模型的有效容量以匹配任务的复杂性。有效容量受限于3个因素:模型的表示容量、学习算法成功最小化训练模型代价函数的能力,以及代价函数和训练过程正则化模型的程度。具备更多网络层、每层有更多的隐藏单元的模型具备较高的表示能力------可以表示更复杂的函数。然而,若是训练算法不能找到某个合适的函数来最小化训练代价,或是正则化项(如权重衰减)排除了这些合适的函数,那么即便模型的表达能力较高,也不能学习处合适的函数。

当泛化偏差以某个超参数为变量,做为函数绘制出来时,一般会表现为U形曲线。在某个极端状况下,超参数对应着低容量,而且泛化偏差因为训练偏差较大而很高。这即是欠拟合的状况。另外一种极端状况,超参数对应着高容量,而且泛化偏差因为训练偏差和测试偏差之间的差距较大而很高。最优的模型容量位于曲线中间的某个位置,可以达到最低可能的泛化偏差,由某个中等的泛化偏差和某个中等的训练偏差相加构成。

对于某些超参数,当超参数数值太大时,会发生过拟合。例如中间层隐藏单元的数量,增长数量能提升模型的容量,容易发生过拟合。对于某些超参数,当超参数数值过小时,也会发生过拟合。例如,最小的权重衰减系数容许为零,此时学习算法具备最大的有效容量,反而容易发生过拟合。

并不是每一个超参数都能对应着完整的U形曲线。不少超参数是离散的,如中间层单元数目或是maxout单元中线性元件的数目,这种状况只能沿曲线探索这些点。有些超参数是二值的。一般这些超参数用来指定是否使用学习算法中的一些可选部分。如预处理步骤减去均值并除以标准差来标准化输入特征。这些超参数只能探索曲线上的亮点。其余一些超参数可能会有最小值或最大值,限制其探索曲线上的某些部分。例如,权重衰减系数最小是零。这意味着,若是权重权重衰减系数为零时模型欠拟合,那么咱们将没法经过修改权重衰减系数探索拟合区域。换言之,有些超参数只能减小模型容量。

学习率多是最重要的超参数。若是你只有时间调整一个超参数,那就调整学习率。相比于其余超参数,它以一种更复杂的方式控制着模型的有效容量------当学习率适合优化问题时,模型的有效容量最高,此时学习率是正确的,既不是特别大也不是特别小。学习率关于训练偏差具备U形曲线。当学习率过大时,梯度降低可能会不经意地增长而非减小训练偏差。在理想情下,若是学习率是最佳值的两倍大时,则会发生这种状况。当学习率过小,训练不只慢,还有可能永久停留在一个很高的训练偏差上。关于这种效应,咱们只是甚少(不会发生于一个凸损失函数中)。

调整学习率外的其余参数时,须要同时监控训练偏差和测试偏差,以判断模型是否过拟合或欠拟合,而后适当调整其容量。若是训练集错误率大于目标错误率,那么只能增长模型容量以改进模型。若是没有使用正则化,而且确信优化算法正确运行,那么有必要添加更多的网络层或隐藏单元。然而,使人遗憾的是,这增长了模型的计算代建。

若是测试集错误率大于目标错误率,那么能够采起两个方法。测试偏差是训练偏差和测试偏差之间差距与训练偏差的总和。寻找最佳的测试偏差须要权衡这些数值。当训练偏差较小(所以容量较大),测试偏差主要取决于训练偏差和测试偏差之间的差距时,一般神经网络效果最好。此时目标是缩小这一差距,使训练数据的增加速率不快于差距减少的速率。要减小这个差距,咱们能够改变正则化超参数,以减小有效的模型容量,如添加Dropout或权重衰减策略。一般,最佳性能来自正则化得很好的大规模模型,好比使用Dropout的神经网络。大部分超参数能够经过推理其是否增长或减小模型容量来设置。

超参数 容量合适增长 缘由 注意事项
隐藏层单元数 增长 增长隐藏单元数量会增长模型的表示能力

几乎模型每一个操做所需的时间和内存代价都会

随隐藏单元数量的增长而增长

学习率 调至最优

不正确的学习率,无论是过高仍是过低都

会因为优化失败而致使低有效容量的模型

 
卷积核宽度 增长 增长卷积核宽度会增长模型的参数数量

较宽的卷积核致使较窄的输出尺寸,除非使用隐式

零填充较少此影响,不然会下降模型容量。较宽的

卷积核须要更多的内存存储参数,并会增长运行时

间,但较窄的输出会下降内存代价

隐式零填充 增长

在卷积以前隐式添加零能保持较大尺寸的

表示

大多数操做的时间和内存代价会增长
权重衰减系数 下降

下降权重衰减系数使得模型参数能够自由

地变大

 
Dropout 比率 下降

较少地丢弃单元能够更多地让单元彼此“合力”

来适应训练集

 

手动调整参数时,不要忘记最终目标:提高测试集性能。加入正则化只是实现这个目标的一种方法。只要训练偏差低,随时均可以经过收集更多的训练数据来减小泛化偏差。实践中能确保学习有效的暴力方法就是不断提升模型容量和训练集的大小,直到解决问题。这种作法增长了训练和推断的计算代价,因此只有在拥有足够资源时才是可行。原则上,这种作法可能会由于优化难度提升而失败,但对于许多问题而言,优化彷佛并无成为一个显著的障碍,固然,前提是选择了合适的参数。

2.自动超参数优化算法

理想的学习算法应该是只须要输入一个数据集,就能够输出学习的函数,而不须要手动调整超参数。一些流行的学习方法,如逻辑回归和支持向量机,流行的部分缘由是这类算法只有一到两个超参数须要调整,它们也能表现出不错的性能。有些状况下,有些状况下,所需调整的超参数数量较少时,神经网络能够表现出不错的性能;但超参数数量有几十甚至更多时,效果会提高得更加明显。当使用者有一个很好的初始值,例如由在相同类型的应用和架构上具备经验的人肯定初始值,或者使用者在类似问题上具备几个月甚至几年的神经网络朝参数调整经验,那么手动调整超参数能有很好的效果。然而,对于不少应用而言,这些七点都不可用。在这些状况下,自动算法能够找到合适的超参数。

若是仔细详想一想使用搜索学习算法合适超参数的方式,咱们会意识到这实际上是一种优化:咱们在试图寻找超参数来优化目标函数,例如验证偏差,有时还会有一些约束(如训练时间、内存或识别时间的预算)。所以,原则上有可能开发出封装学习算法的超参数优化算法,并选择其超参数,从而使用者不须要指定学习算法的超参数。使人遗憾的是,超参数优化算法每每有本身的超参数,如学习算法的每一个超参数应该被探索的值的范围。然而,这些次超参数一般很容易选择,这就是说,相同的次超参数可以在不少不一样的问题上具备良好的性能。

3.网格搜索

当有3个或更少的超参数时,常见的超参数搜索方法是网格搜索(grid search)。对于每一个超参数,使用者选择一个较小的有限值集去探索。而后,这些超参数笛卡尔乘积获得一组组超参数,网格搜索使用每组超参数训练模型。挑选验证集偏差最小的超参数做为最好的超参数。

应该如何选择搜索集合的范围呢?在超参数时数值(有序)的状况下,每一个列表的最小和最大的元素能够基于先前类似实验的经验保守地挑选出来,以确保最优解很是可能在所选范围内。一般,网格搜索大约会在对数尺度下挑选合适的值,例如,一个学习率的取值集合是{0.1, 0.01, 10^-3, 10^-4, 10^-5},或者隐藏单元数目的取值集合{50, 100, 200, 500, 1000, 2000}。

一般重复进行网格搜索时,效果会最好。例如,假设咱们在集合{-1,0,1}上网格搜索超参数a。若是找到的最佳值是1,那么说明咱们低估了最优值a所在的范围,应该改变搜索格点,例如在集合{1,2,3}中搜索。若是最佳值是0,那么咱们不妨经过细化搜索范围改进估计,在集合{-0.1, 0 ,0.1}上进行网格搜索。

网格搜索带来的一个明显问题时,计算代价会随着超参数数量呈指数级增加。若是有m个超参数,每一个最多取n个值,那么训练和估计所需的实验数将是O(n^m)。咱们能够并行地进行实验,而且并行要求十分款算(进行不一样搜索的机器之间几乎没有必要进行通讯)。使人遗憾的是,因为网络搜索指数级增加计算代价,即便是并行,咱们也没法提供使人满意的搜索规模。

4.随机搜索

幸运的是,有一个替代网格搜索的方法,而且编程简单,使用更方便,能更快地收敛到超参数的良好取值------随机搜索。随机搜索过程以下,首先为每一个超参数定义一个边缘分布,例如,Bernoulli分布或范畴分布(分别对应着二元超参数或离散朝参数),或者对数尺度上的均匀分布(对应着实值超参数)。例如,

                                                            log\_learning \sim u(-1,-5)\\ learning\_rate = 10^{log\_learning\_rate}

其中,u(a,b)表示区间(a,b)上均匀采样的样本。相似地,log_number_of_hidden_units能够从u(log(50),log(2000))上采样。

与网格搜索不一样,咱们不须要离散化超参数的值。这容许咱们在一个更大的集合上进行搜索,而不产生额外的计算代价。实际上,当有集合超参数对性能度量没有影响时,随机搜索相比于网络搜索指数级地高效。

与网格搜索同样,一般会重复运行不一样版本的随机搜索,以基于前一次运行的结果改进下一次搜索。随机搜索能比网格搜索更快地找到良好超参数的缘由是,没有浪费实验,不像网格搜索有时会对一个超参数的两个不一样值(给定其余超参数值不变)给出相同结果。在网格搜索中,其余超参数将在这两次实验中拥有相同的值,而在随机搜索中,它们一般会具备不一样的值。所以,若是这两个值的变化所对应的验证集偏差没有明显区别的话,网格搜索没有必要重复两个等价的实验,而随机搜索仍然会对其余超参数进行两次独立的探索。

5.基于模型的超参数优化

超参数搜索问题能够转化为一个优化问题,决策变量是超参数,优化的代价是超参数训练出来的模型在验证集上的偏差。在简化的设定下,能够计算验证集上可导偏差函数关于超参数的梯度,而后咱们遵循这个梯度更新。使人遗憾的是,在大多数实际设定中,这个梯度是不可用的。这多是由于其高额的计算代价和存储成本,也多是由于验证集偏差上本质上不可导,例如超参数是离散值的状况。

为了弥补梯度的缺失,咱们能够对验证集偏差建模,而后经过优化该模型来提出新的超参数猜测。大部分基于模型的超参数搜索算法,都是使用贝叶斯模型来估计每一个超参数的验证集偏差指望和该指望的不肯定性。所以,优化涉及探索(探索高度不肯定的超参数,可能带来显著的效果提高,也可能效果不好)和使用(使用已经确信效果不错的超参数------一般是先前见过的很是熟悉的超参数)之间的权衡。关于超参数优化的最前沿方法还包括Spearmint、TPE和SMAC。

目前,没法明确肯定,贝叶斯超参数优化是不是一个可以实现更好深度学习结果或是可以事半功倍的更熟工具。贝叶斯超参数优化有时表现得很像人类专家,可以在有些问题上取得很好的效果,可是有时又会在某些问题上发生灾难性的失误。看看它是否使用于一个特定的问题是值得尝试的,但目前该方法还不够成熟或可靠。就像所说的那样,超参数优化是一个重要的研究领域,一般主要受深度学习所需驱动,可是它不只能贡献于整个机器学习领域,还能贡献于一遍的工程学。

大部分超参数优化算法比随机搜索更复杂,而且具备一个共同的缺点,在它们可以从实验中提取任何信息以前,它们须要运行完整的训练实验。相比于人类实践者动手搜索,考虑实验早期能够收集的信息量,这种方法是至关低效,由于手动搜索一般能够很早判断出某组超参数是否彻底病态。

5.调试策略

当一个机器学习系统效果很差时,一般很难判断效果很差的缘由是算法自己,仍是算法实现错误。因为各类缘由,机器学习系统很难调试。

在大多数状况下,不能提早知道算法的行为。事实上,使用机器学习的整个出发应是,它会发现一些咱们本身没法发现的有用行为。若是咱们在一个新的分类任务上训练一个神经网络,它达到5%的测试偏差,咱们没法直接知道这是指望的结果,仍是次优的结果。

另外一个难点是,大部分机器学习模型有多个自适应的部分。若是一个部分失效了,其余部分仍然能够自使用,并得到大体可接受的性能。例如,假设咱们正在训练多层神经网络,其中参数为权重W和偏置b,进一步假设,咱们单独动手实现了每一个参数的梯度降低规则。而咱们在偏置更新时犯了个错误:

                                                                      b\leftarrow b-\alpha

其中\alpha是学习率。这个错误更新设置没有使用梯度。它会致使偏置在整个学习中不断变为负值,对于一个学习算法来讲这显然是错误的。然而只是检查模型输出的话,该错误可能并非显而易见的。根据输入的分布,权重可能能够自适应地补偿负的偏置。

大部分神经网络的调试策略都是解决这两个难题中的一个或两个。咱们能够设计一种足够简单的状况,可以提早获得正确结果,判断模型预测是否与之相符;咱们也能够设计一个测试,独立检查神经网络实现的各个部分。

一些重要的调试检测以下述。

可视化计算种模型的行为:当训练模型检测图像中的对象时,查看一些模型检测到部分重叠的图像。在训练语音生成模型时,试听一些生成的语音样本。这彷佛是显而易见的,但在实际中很容易只注意量化性能度量,如准确率或对数似然。直接观察机器学习模型运行其任务,有助于肯定其达到的量化性能数据是否看上去合理。错误评估模型性能多是最具破坏性的错误之一,由于它们会使你在系统出问题时误觉得系统运行良好。

可视化最严重到的错误:大多数模型可以输出运行任务时的某种置信度量。例如,基于softmax函数输出层的分类器给每一个类分配一个几率。所以,分配给最有可能的类的几率给出了模型在其分类决定上的置信估计值。一般,相比于正确预测的几率最大似然函数训练会略有高估。可是因为实际上模型的较小几率不大可能对应着正确的标签,所以它们在必定意义上仍是有些用的。经过查看训练集中很难正确建模的样本,一般能够发现该数据预处理或者标记方式的问题。例如,街景转录系统中本来有个问题是,地址号码检测系统会将图像裁剪得过于紧密,而省略了一些数字。而后转录网络会给这些图像的正确答案分配很是低的几率。将图像排序,肯定置信度最高的错误,显示系统的裁剪有问题。修改检测系统裁剪更宽的图像,从而使整个系统得到更好的性能,可是转录网络须要可以处理地址号码中位置和范围更大变化的状况。

根据训练和测试偏差检测软件:咱们每每很难肯定底层软件是否正确实现。训练和测试偏差可以提供一些线索。若是训练偏差较低,可是测试偏差较高那么极可能训练过程时在正常运行,但模型因为算法缘由过你喝了。另外一种多是,测试偏差没有被正确的度量,多是因为训练后保存模型再重载去度量测试集时出现问题,或者是由于测试数据和训练数据预处理的方法不一样。若是训练和测试偏差都很高,那么很难肯定是软件错误,仍是因为算法缘由模型欠拟合。这种状况须要进一步的测试,以下面所述。

集合极小的数据集:当训练集上有很大的偏差时,咱们须要肯定问题时真正的欠拟合,仍是软件错误。一般,即便是小模型能够保证很好地拟合一个足够小的数据集。例如,只有一个样本的分类数据能够经过正确设置输出层的偏置来拟合。一般,即便是小模型也能够保证很好地拟合一个足够小的数据集。例如,只有一个样本的分类数据能够经过正确设置输出层的偏置来拟合。一般,若是不能训练一个分类器来正确标注一个单独的样本,或不能训练一个自编码器来成功地精确再现一个单独的样本,那么极可能是因为软件错误阻止训练集上的成功优化。此测试能够扩展到只有少许样本的小数据集上。

比较反向传播导数和数值导数:若是读者正在使用一个须要实现梯度计算的软件框架,或者在添加一个新操做到求导库中,必须定义它的bprop方法,那么常见的错误缘由是没能正确实现梯度表达。验证这些求导正确性的一种方法是比较自动求导的实现和经过有限差分(finite difference)计算的导数:

                                                                   f'(x)=lim\frac{f(x+\varepsilon )}{\varepsilon }

 咱们可使用小的、有限的\varepsilon近似导数:

                                                                 f'(x)\approx lim\frac{f(x+\varepsilon )}{\varepsilon }

 

咱们可使用中心差分(centered difference)提升近似的准确率:
                                                                f'(x)\approx lim\frac{f(x+\varepsilon/2 )-f(x-\varepsilon/2 )}{\varepsilon }

扰动大小\varepsilon必须足够大,以确保该扰动不会因为数值计算的有限精度问题产生舍入偏差。

一般,咱们会测试向量值函数g:R^m\rightarrow R^n的梯度或Jacobian次评估g的全部偏导数,也能够将该测试应用于一个新的函数(在函数g的输入输出都加上随机投影)。例如,咱们能够将导数实现的测试用于函数f(x)=u^Tg(vx),其中u和v是随机向量。正确计算f'(x)要求可以正确地经过g反向传播,可是使用有限差分可以高效地计算,由于f只有一个输入和一个输出。一般一个好的方法是在多个u的值和v的值上重复这个测试,能够减小测试忽略了垂直于随机投影饿错误的概率。

若是咱们能够在复数上进行数值计算,那么使用复数做为函数的输入会有很是搞笑的数值方法估算梯度。该方法基于以下观察:

                                                  f(x+i\varepsilon )=f(x)+i\varepsilon f'(x)+O(\varepsilon ^2)

                                            real(f(x+i\varepsilon ))=f(x)+O(\varepsilon ^2), image(\frac{f(x+i\varepsilon )}{\varepsilon })=f'(x)+O(\varepsilon ^2)

其中i=\sqrt{-1}。和上面的实值状况不一样,这里不存在消除影响,由于咱们对f在不一样点上计算差分。所以咱们可使用很小的\varepsilon,好比\varepsilon = 10^{-150},其中偏差O(\varepsilon ^2)对全部使用目标都是微不足道的。

监控激活函数值和梯度直方图:可视化神经网络在大量训练迭代后(也许是一个轮)收集到的激活函数值和梯度的统计量每每是有用的。隐藏单元的激活值能够告诉咱们该单元是否饱和,或者它们饱和的频率如何。例如,对于整流器,它们多久关一次?是否有单元一直关闭?对于双曲正切单元而言,预激活绝对值的平均值能够告诉咱们该单元的饱和程度。在深度网络中,传播梯度的快速增加或快速消失,可能会阻碍优化过程。最后,比较参数梯度和参数的量级也是有帮助的。正如所建议的,但愿参数在一个小批量更新中变化的幅度是参数值1%这样的级别,而不是50%或者0.001%(这会致使参数移动得太慢)。也有多是某些参数以良好的步长移动,而另外一些停滞。若是数据时稀疏的(好比天然语言),有些参数可能不多更新,检测它们变化时应该记住这一点。

最后,许多深度学习算法为每一步产生的结果提供了某种保证。一般,这些能够经过测试它们每一个保证来调试。某些优化算法提供的保证包括,目标函数值在算法的迭代步中不会增长,某些变量的导数在算法的每一步中都是零,全部变量的梯度在收敛时会变为零。一般,因为舍入偏差,这些条件不会在数字计算机上彻底成立,所以调试测试应该包含一些容差参数。

 


承接Matlab、Python和C++的编程,机器学习、计算机视觉的理论实现及辅导,本科和硕士的都可,咸鱼交易,专业回答请走知乎,详谈请联系QQ号757160542,非诚勿扰。

本文同步分享在 博客“于小勇”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索