机器学习软件产品的代码通常很复杂并且相当混乱。 检测并消除其中的错误是一项资源密集型任务。 即使是最简单的
技能箱推荐: 实践课程
从零开始的Python开发者 .我们提醒: 对于“Habr”的所有读者 - 使用“Habr”促销代码注册任何 Skillbox 课程可享受 10 卢布的折扣。
该算法由五个阶段组成:
- 轻松开始;
- 确认损失;
- 检查中间结果和连接;
- 参数诊断;
- 对工作的控制。
如果您觉得某些内容比其他内容更有趣,您可以立即跳到这些部分。
轻松开始
具有复杂架构、正则化和学习率调度器的神经网络比常规网络更难调试。 我们在这里有点棘手,因为这一点本身与调试间接相关,但这仍然是一个重要的建议。
一个简单的开始是创建一个简化的模型并在一组(点)数据上对其进行训练。
首先我们创建一个简化的模型
为了快速开始,我们创建一个具有单个隐藏层的小型网络,并检查一切是否正常工作。 然后我们逐渐使模型复杂化,检查其结构的每个新方面(附加层、参数等),然后继续。
我们在一组(点)数据上训练模型
作为对项目的快速健全性检查,您可以使用一两个数据点进行训练,以确认系统是否正常工作。 神经网络必须在训练和测试中表现出 100% 的准确性。 如果情况并非如此,则要么模型太小,要么您已经存在错误。
即使一切顺利,也要在继续之前为一个或多个时期准备好模型。
损失评估
损失估计是完善模型性能的主要方法。 您需要确保损失适合问题,并且损失函数按照正确的尺度进行评级。 如果您使用多种损失类型,请确保它们的阶数相同并且比例正确。
注意初始损失很重要。 如果模型以随机猜测开始,请检查实际结果与预期结果的接近程度。 在
对于二进制示例,只需对每个类进行类似的计算。 例如,这里的数据是:20% 为 0,80% 为 1。 预期初始损失将高达 –0,2ln (0,5) –0,8ln (0,5) = 0,693147。 如果结果大于1,则可能表明神经网络权重未适当平衡或数据未标准化。
检查中间结果和连接
要调试神经网络,有必要了解网络内过程的动态以及各个中间层连接时的作用。 以下是您可能遇到的常见错误:
- gradle 更新的表达式不正确;
- 不应用权重更新;
- 梯度爆炸。
如果梯度值为零,这意味着优化器中的学习速率太慢,或者您遇到更新梯度的不正确表达式。
此外,还需要监控每一层的激活函数、权重和更新的值。 例如,参数更新的幅度(权重和偏差)
有一种现象称为“Dying ReLU”或
您可以使用梯度检查来通过使用数值方法近似梯度来识别这些错误。 如果它接近计算的梯度,则反向传播已正确实现。 要创建梯度检查,请查看 CS231 中的这些优秀资源
- 预备部分是简单的方法,向我们展示训练模型的一般结构。 其中包括神经网络各层的形状或滤波器的输出以及每层内的参数。
- 基于激活。 在其中,我们破译单个神经元或神经元组的激活以了解它们的功能。
- 基于梯度。 这些方法倾向于操纵由模型训练的前向和后向传递形成的梯度(包括显着性图和类激活图)。
有几种有用的工具可用于可视化各个层的激活和连接,例如
参数诊断
神经网络有很多相互影响的参数,这使得优化变得复杂。 实际上,本节是专家们积极研究的主题,因此以下建议仅应被视为建议和构建的起点。
包装尺寸 (批量大小)- 如果您希望批量大小足够大以获得准确的误差梯度估计,但又足够小以便随机梯度下降 (SGD) 能够正则化您的网络。 小批量会由于训练过程中的噪声而导致快速收敛,从而导致优化困难。 这有更详细的描述
学习率 - 太低将导致收敛缓慢或陷入局部最小值的风险。 同时,高学习率会导致优化发散,因为你可能会跳过损失函数深而窄的部分。 在训练神经网络时尝试使用速度调度来减少它。 已更新至 CS231n
渐变剪裁 — 在反向传播期间以最大值或边际范数修剪参数梯度。 对于解决第三点中可能遇到的任何梯度爆炸问题很有用。
批量归一化 - 用于对每一层的输入数据进行归一化,这使我们能够解决内部协变量偏移的问题。 如果您同时使用 Dropout 和 Batch Norma,
随机梯度下降 (SGD) — SGD 有多种使用动量、自适应学习率和 Nesterov 方法的变体。 然而,它们在学习效率和泛化能力方面都没有明显的优势(
正则化 - 对于构建可推广的模型至关重要,因为它会增加模型复杂性或极端参数值的惩罚。 这是一种减少模型方差而不显着增加其偏差的方法。 更多的
要自己评估一切,您需要禁用正则化并自己检查数据丢失梯度。
辍学 是简化网络以防止拥塞的另一种方法。 在训练期间,仅通过以一定概率p(超参数)维持神经元的活动或在相反情况下将其设置为零来进行dropout。 因此,网络必须为每个训练批次使用不同的参数子集,从而减少某些成为主导参数的变化。
重要提示:如果您同时使用 dropout 和批量归一化,请注意这些操作的顺序,甚至将它们一起使用。 这一切仍在积极讨论和补充中。 以下是关于该主题的两个重要讨论
工作控制
这是关于记录工作流程和实验。 如果您不记录任何内容,您可能会忘记例如使用的学习率或类别权重。 通过控制,您可以轻松查看和重现以前的实验。 这可以让您减少重复实验的数量。
然而,在工作量很大的情况下,手动记录可能会成为一项艰巨的任务。 这就是像 Comet.ml 这样的工具可以帮助您自动记录数据集、代码更改、实验历史记录和生产模型的地方,包括有关模型的关键信息(超参数、模型性能指标和环境信息)。
神经网络可能对微小的变化非常敏感,这将导致模型性能下降。 跟踪和记录您的工作是标准化您的环境和建模的第一步。
我希望这篇文章可以成为您开始调试神经网络的起点。
技能箱推荐:
- 两年实践课程
“我是一名专业网络开发人员” .- 在线课程
《C#开发从0开始》 .- 实践年课程
《PHP 开发者从 0 到 PRO》 .
来源: habr.com