1 前言
在传统软件工程中,程序问题(即Bugs)会导致程序崩溃,但开发人员可以通过检查错误来了解原因。
然而,在深度学习中,代码可能会在没有明确原因的情况下崩溃。虽然这些问题可以手动调试,但深度学习模型通常会因为输出预测不佳而失败。更糟糕的是,当模型性能较低时,通常没有任何信号表明模型失败的原因或时间。
开发过程中我们很经常要花80-90%的时间在数据处理及调试模型,而只花费10-20%的时间推导数学方程和实现功能。
2 为什么模型的问题排查困难
• 很难判断是否有错误
• 造成相同性能下降的原因有很多
• 结果可能对超参数和数据集构成的微小变化很敏感
2.1 存在隐藏bugs
在深度学习中,大部分错误并不会被轻易察觉到,比如标签顺序错误。
2.2 超参数选择
深度学习模型对超参数的选择非常敏感。即使是微妙的调整,如学习率和权重的初始化,也会对结果产生显著的影响。
2.3 数据/模型拟合
我们可以在ImageNet数据集上预训练模型,然后将其应用到更为复杂的自动驾驶汽车图像数据集上进行拟合。
2.4 数据集构造
在此过程中,常见的问题包括:样本数量不足、处理带有噪声的标签和类别不平衡、以及在构建训练集和测试集时未能确保数据的分布一致性。
3 深度学习故障排除指南
深度学习(DL)故障排除的关键思想:由于很难定位bugs的来源,因此最好从简单开始,逐渐增加复杂性。
3.1 从简单开始
架构选择。深度学习架构选择可遵循简单规则:图像数据,从类似LeNet开始,成熟时考虑ResNet;序列数据,从LSTM开始,问题成熟时转向注意力模型或WaveNet;其他任务,从全连接神经网络开始,再根据问题使用更高级网络。
使用合理的超参数默认值。推荐的网络/优化器默认值:Adam 优化器使用 3e-4 学习率; ReLU 激活用于全连接和卷积模型以及 Tanh 激活用于 LSTM 模型;ReLU 激活函数采用 He 初始化,Tanh 激活函数采用 Glorot 初始化;模型未使用正则化或数据标准化。
归一化输入。对输入数据进行归一化,减去均值并除以方差;对于图像,将值缩放为 [0, 1] 或 [-0.5, 0.5](例如除以 255)。
简化问题。使用小型训练集(约10,000个示例),固定对象、类、输入大小等,构建简单的综合训练集,可以提高模型解决问题的信心和迭代速度。
3.2 运行和调试
五个最常见的DL错误:
关于实施模型的一般建议:
运行模型常见问题及原因:
过度拟合单批数据常见问题及原因:
与已知结果进行比较(不断迭代,直到模型执行得达到预期为止):
• 在相似数据集上评估的官方模型实施;
• 根据基准评估官方模型实施(例如 MNIST);
• 非官方模型实施;
• 论文结果(无代码);
• 基准数据集(例如 MNIST)上的模型结果;
• 类似数据集上的类似模型的结果;
• 超级简单的基线(例如,输出平均值或线性回归)。
3.3 评估
偏差-方差分解
测试误差 = 不可约误差 + 偏差 + 方差 + 验证集过拟合
不可约误差是基线误差,可通过强有力的基线来估计。可避免偏差是欠拟合的衡量标准,是训练误差与不可约误差之间的差异。方差是过拟合的度量,是验证错误和训练错误之间的差值。验证集过拟合是测试误差与验证错误之间的差异。
随分布变化的偏差-方差
在实际的ML应用中,训练、验证和测试样本可能来自不同的分布。为了解决这个问题,可以创建两个验证集,分别来自训练分布和测试分布。通过比较测试验证错误和测试错误,可以估计分布偏移,这对于ML实际应用非常有用。
测试误差 = 不可约误差 + 偏差 + 方差 + 分布偏移 + 验证集过拟合
3.4 改进模型和数据
解决欠拟合问题(即减少偏差):优先级别递减
解决过拟合问题(即减少差异):优先级别递减
解决分布转换
误差分析示例如下:
领域适配:仅使用未标记数据或有限标记数据来训练“源”分布并推广到另一个“目标”的技术。当对测试分发中的标记数据的访问受到限制及可以获得大量相对相似的数据时要考虑领域适配。包括自监督领域适配和无监督领域适配。
重新平衡数据集
3.5 超参数优化
超参数优化面临如下问题:
网络:ResNet——多少层?如何参数初始化?卷积核大小?
优化器:Adam——batch size?学习率?beta1,beta 2?
正则化:用哪种正则化方式?
应该调整哪些超参数? 首选模型更敏感的参数;与选择的模型相关;经验法则;灵敏度与默认值相关。有关超参数及其对模型的影响如下:
方法1 手动超参数优化
步骤:了解算法(例如,更高的学习率意味着更快、更不稳定的训练);训练和评估模型;猜测更好的超参数值并重新评估;可以与其他方法结合使用(例如,手动选择要优化的参数范围)。
优点:对于经验丰富的人,只需要最少的计算就能获得良好的结果。
缺点:需要对算法有深刻的见解且费时。
方法2 网格搜索
优点:实施起来超级简单;可以产生好的效果
缺点:效率不高(需要对超参数的所有交叉组合进行训练);可能需要有关参数的先验知识才能获得良好的结果
方法3 随机搜索
优点:易于实施;通常会产生比网格搜索更好的结果
缺点:不太好解释;可能需要有关参数的先验知识才能获得良好的结果
方法4 由粗到细搜索
步骤:定义一个大范围进行随机搜索,然后在结果池中找到N个最佳结果,并重复这个过程。
优点:可以缩小性能非常高的超参数范围;实践中最常用的方法
缺点:有点手动过程
方法5 贝叶斯超参数优化
步骤:从参数分布的预先估计开始;维护超参数值与模型性能之间关系的概率模型;交替使用最大化预期改进的超参数值进行训练并根据训练结果来更新概率模型。
优点:选择超参数最有效的 hands-of 方式。
缺点:很难从头开始实施;可能很难与现成的工具集成。
总之,超参数方面应该从粗到细的随机搜索,随着项目代码完备后,再考虑贝叶斯等方法做更细致的超参数优化。