如何单元测试机器学习代码调试?|译]调试

[翻译] 调试神经网络的清单

训练深度学习模型是一项非常耗时的工作,没有什么比花费数天的训练结果不佳更令人沮丧的了。因此,我翻译了这篇文章:调试神经网络的Checklist,希望能给大家一点启发,尽快发现模型中的问题。原地址:forwardsdatascience.com/checklist-f…,略删。点击阅读原文跳转本文,需翻墙!

众所周知,机器学习代码很难调试。即使使用简单的前馈神经网络,您也经常需要围绕网络架构、权值初始化和网络优化做出决策——所有这些都可能导致机器学习代码中的隐藏错误。

正如 Chase Roberts 在一篇关于“如何对机器学习代码进行单元测试”的优秀文章中所写的那样,他的挫败感源于常见的陷阱:

代码永远不会崩溃、抛出异常,甚至会变慢。网络继续训练,损失仍在减少。它在几个小时后收敛神经网络 参数初始化,但结果很糟糕。

那么应该怎么做呢?

本文将提供一个框架来帮助您调试神经网络:

只需开始验证您的模型损失 检查中间输出并连接诊断参数 跟踪您的工作

随意跳到特定部分或按顺序阅读以下内容!请注意:我们不包括数据预处理或特定模型算法选择。关于这些主题有很多很好的在线资源(例如,阅读“选择正确的机器学习算法”)。

1.从简单开始

具有正则化和学习率调度器的复杂架构的神经网络将比简单的网络更难调试。第一点可能有点投机取巧,因为它与调试您已经建立的网络无关,但仍然强烈推荐!

开始简单:

建立一个更简单的模型

作为起点,构建一个具有单个隐藏层的小型网络并验证一切正常,然后逐渐增加模型复杂性,同时检查模型结构的各个方面(层、参数等)是否有效。

在单个数据点上训练模型

作为快速检查,您可以使用一组或两组训练数据点来确认模型是否过度拟合。神经网络应立即以 100% 的训练准确度和验证准确度过拟合,与您的随机猜测模型相当。如果模型无法在这些数据点上过拟合,则说明数据集太小或存在错误。

即使您已经确认模型有效,也请尝试在实际训练之前训练一个(或几个)时期。

2.确认你的模型损失

模型的损失是评估模型性能的主要方式,模型在评估过程中设置了重要的参数,所以需要保证:

注意初始损失也很重要。如果您的模型从随机猜测开始,请检查初始损失是否接近您的预期损失。在斯坦福 CS231n 课程中,Andrej Karpathy 提出以下建议:

出于性能原因找到正确的损失。用小参数初始化时,确保得到预期的损失。最好先检查数据丢失(因此将正则化强度设置为零)。例如,对于带有 Softmax 分类器的 CIFAR-10,我们预计初始损失为 2.302,因为我们预计每个类的扩散概率为 0.1(因为有 10 个类),而 Softmax 的损失是正确类的负对数概率,所以:-ln(0.1) = 2.302.

对于二元分类示例,您只需对每个类执行类似的计算。假设您的数据是 20% 0 类别和 80% 1 类别。预期的初始损失将是 -0.2ln(0.5)-0.8ln(0.5) = 0.693147。如果您的初始损失远大于 1,则可能表明神经网络的权重不平衡(即初始化不佳)或您的数据未正则化。

3.检查中间输出和连接

为了调试神经网络,了解神经网络内部的动态以及各种中间层的作用以及这些层的连接方式通常很有用。您可能会遇到以下错误:

如果你的梯度值为零,可能意味着优化器中的学习率太小,或者你遇到了上面的错误#1:不正确的梯度更新算法。

除了查看梯度更新的绝对值外,还要确保监控每一层的激活幅度、权重和更新。例如,参数更新的幅度(权重和偏差)应该是 1-e3。

有一种现象称为“dead ReLU”或“梯度消失问题”,其中 ReLU 神经元在为其权重学习一个大的负偏置项后将输出零。这些神经元再也不会在任何数据点上触发。

您可以使用梯度检查通过数值近似梯度来检查这些错误。如果它接近计算的梯度,则反向传播实现是正确的。要实施梯度检查,请在此处和此处查看 CS231 中的这些优秀资源和 Andrew Ng 的相关课程。

Faizan Shaikh 写了关于可视化神经网络的三种主要方法:

有许多有用的工具可用于可视化各个层的激活和连接,例如 ConX 和 Tensorboard。

使用 ConX 的动态渲染可视化示例

使用图像数据?Erik Rippel 发表了一篇优秀的文章“Visualizing Partial Convolutional Neural Networks with Keras and Cats”。

4.诊断参数

神经网络具有大量相互交互的参数,使得优化变得困难。请注意,这是一个积极研究的领域神经网络 参数初始化,因此以下建议只是起点。

在实践中已经观察到,当使用较大的批次时,通过泛化能力衡量的模型质量会降低。我们调查了大批量方案中泛化下降的原因,并提供数据证据支持大批量方法倾向于收敛到训练和测试函数的局部最小值的观点——已知局部最小值会导致较差的泛化。相比之下,小批量方法始终收敛到平面最小化,我们的实验支持一个普遍的信念,即这是由于梯度估计中的固有噪声。

Keras、Tensorflow、PyTorch、MXNet 等机器学习框架现在有关于使用学习率调度程序/递减的文档或示例:

Keras – keras.io/callbacks/#…

张量流-…

PyTorch – pytorch.org/docs/stable…

MXNet – mxnet.incubator.apache.org/versions/ma…

Dishank Bansal 的文章“TensorFlow 中的批量规范的陷阱和训练网络的健全性检查”是批量规范化中常见错误的一个很好的参考资源。

通常,损失函数是数据损失和正则化损失的总和(例如,权重的 L2 惩罚)。需要注意的一个危险是正则化损失可能会压倒数据损失,在这种情况下,梯度将主要来自正则化(通常使用更简单的梯度表达式)。这可以掩盖数据丢失梯度的错误实现。

要查看这一点,您应该关闭正则化并独立检查数据丢失梯度。

这里有一个重要说明:如果您同时使用 dropout 和 batch norm,请注意这些操作的顺序,甚至一起使用它们。这仍然是一个活跃的研究领域,但你可以看到最新的讨论:

来自 Stackoverflow 用户 MiloMinderBinder:“Dropout 意味着完全阻止来自某些神经元的信息,以确保神经元不会共存。因此批量标准化必须在 dropout 之后进行,否则您将通过标准化统计传递信息。”

来自 arXiv:通过方差变换理解 Dropout 和 Batch Normalization 的不一致性(Xiang Li、Shuo Chen、Xiaolin Hu、Jian Yang)——“理论上,我们发现当网络从训练到测试时,Dropout 会改变特定神经元的方差。但是,BN在测试阶段会保持其在整个学习过程中积累的统计方差,这种方差的不一致(我们称这种方案为“variance shift”)导致推理中的数值行为不稳定,当在BN之前应用Dropout时,最终导致更多错误的预测。

5.跟踪你的工作

很容易忽略记录实验的重要性,直到您忘记使用的学习率或类别权重。通过更好的跟踪,您可以轻松查看和重现以前的实验,以减少重复工作(也就是遇到相同的错误)。

然而,手动记录信息可能很难做到,并且可以扩展到多个实验。Comet.ml 等工具可以帮助自动跟踪数据集、代码更改、实验历史和生产模型(这包括关键模型信息,例如超参数、模型性能指标和环境细节)。

您的神经网络对数据、参数甚至包版本的微小变化非常敏感 – 导致模型性能下降,并且会累积。跟踪您的工作是标准化环境和建模工作流程的第一步。

快速复审

我们希望这篇文章为调试神经网络提供一个坚实的起点。总结其要点,您应该:

参考:K Code Farmer-

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论