调试神经网络所遵循的五项原则

电子说

1.3w人已加入

描述

很多情况下,研究人员会遇到一个问题:使用机器学习框架实现的神经网络可能与理论模型相去甚远。验证这款模型是否可靠,直接方式就是不断修正和调参。例如,在 2018 年 8 月,谷歌大脑的 Ian Goodfellow 等人,通过引入由覆盖性引导的模糊方法(coverage-guided fuzzing,CGF),推出了一款自动为神经网络 debug 的开源库 TensorFuzz。

想要调试机器学习模型其实并不容易,因为找 bug 这个过程需要付出的代价实在太高了。即便是对于相对简单的前馈神经网络,研究人员也需要经常讨论网络架构、权重初始化和网络优化等问题。

正如 Chase Robert 此前在 “如何最小化测试机器学习代码” 的一篇文章中曾描述了这类问题:“神经网络会继续训练,损失会持续减少;训练几小时后会收敛,但效果却很差……”

对此,在单一的工具之外,Cecelia Shao 通过提供一种思路以表达她对调试神经网络所遵循的五项原则:

从繁就简

确认模型损失

检查中间输出和连接

诊断参数

追踪工作

1. 从繁就简

具有正规化和学习率(learning rate)调度器的复杂架构的神经网络,将单一神经网络更难调试。

首先,构建一个相对简单的模型:构建一个具有单个隐藏层的小模型,并进行验证;然后逐渐添加模型的复杂性,同时检验模型结构的每个层面(附加层、参数等)是否有效。

其次,在单个数据节点上训练模型:可以使用一两个训练数据点(data point)以确认模型是否过度拟合。神经网络应立即过度拟合,训练准确率为 100%,这表明模型符合;如果模型无法过度拟合这些数据点,就证明太小或存在 bug。

2. 确认模型损失

模型损失是评估模型性能的主要方式,也是模型设置重要参数以进行评估的依据,因此需要确保:

模型损失适用于任务(使用分类交叉熵损失(cross-entropy los)进行多分类问题或使用 focal loss 以解决不平衡问题);

正确衡量损失函数的重要性。如果你使用多种类型的损失函数,如 MSE、对抗性、L1、feature loss,,那么请确保所有损失以正确的方式排序。

3. 检查中间输出和连接

为了调试神经网络,你需要理解神经网络内部的动态、不同中间层所起的作用,以及层与层之间是如何连接起来的。不过,你可能遇到以下问题:

不正确的梯度更新表达式

权重未得到应用

梯度消失或爆发

如果梯度值为 0,则意味着优化器中的学习率可能太小,且梯度更新的表达式不正确。

除了关注梯度的绝对值之外,还要确保监视每个层匹配的激活、权重的大小。例如,参数更新的大小(权重和偏差)应为 1-e3。

需要指出的是,一种称为 “Dying ReLU” 或“梯度消失”的现象中,ReLU 神经元在学习其权重的负偏差项后将输出为 0。这些神经元不会在任何数据点上得到激活。

你可以采用梯度检验(gradient checking)通过数值方法逼近梯度以检验这些错误。如果它接近计算梯度,则正确实施反向传播。

关于可视化神经网络的主要方法,Faizan Shaikh 举出了三个例子:

初始方法:展现训练模型的整体结构,这些方法包括展示神经网络各个层的形状或过滤器(filters)以及每个层中的参数;

基于激活的方法:破译单个神经元或一组神经元的激活函数;

基于梯度的方法:在训练模型时,操作由前向或后向通道形成的梯度。

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

4. 诊断参数

神经网络具有大量彼此相互作用的参数,使得优化也变得非常困难。

Batch size:你希望 batch size 可大到足以准确评估误差梯度,小到足以使随机梯度下降(SGD)可以规范网络。batch size 将导致学习过程在训练过程中以噪声成本快速瘦脸,并可能导致优化困难。

学习率(Learning rate):太低会导致收敛缓慢或陷入局部最小值的风险,太高则会导致优化发散。

机器学习框架,如 Keras、Tensorflow、PyTorch、MXNet 现在都有关于使用学习率收敛缓慢文档或示例:

Keras

https://keras.io/callbacks/#learningratescheduler

Tensorflow - https://www.tensorflow.org/api_docs/python/tf/train/exponential_decay

PyTorch - https://pytorch.org/docs/stable/_modules/torch/optim/lr_scheduler.html

MXNet - https://mxnet.incubator.apache.org/versions/master/tutorials/gluon/learning_rate_schedules.html

梯度剪切(Gradient clipping ):在反向传播中,用于剪切参数梯度的最大值或最大范数。

Batch 标准化(normalization ):用于标准化每层的输入,以对抗内部协变量移位问题。

随机梯度下降(Stochastic Gradient Descent ,SGD):使用动量、自适应学习率、Nesterov 更新。

正则化:对于构建可推广模型至关重要,因为它增加了对模型复杂性或极端参数值的惩罚。同时,它显著降低了模型的方差,并且不显著增加偏差。

Dropout:是另一种规范网络以防止过度拟合的技术。在训练时,以某个概率 p(超参数)保持神经元活动来实现丢失,否则将其设置为 0。结果,网络必须在每个训练 batch 中使用不同的参数子集,这减少了特定参数的变化而变得优于其他参数。

5. 全程跟踪工作

通过对工作更好地跟踪,可以轻松查看和重现之前的试验,以减少重复工作。

不过,手动记录信息可能很难做到且进行多次实验,像 comet.ml 这样的工具可以帮助自动追踪数据集、更改代码、实验历史和生产模型,包括关于模型的关键信息,如超参数、模型性能指标和环境细节。

神经网络对数据、参数,甚至 packages 的微小变化都非常敏感,这导致了模型的性能下降。工作跟踪是标准化环境和建模工作流程的第一步。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分