当前位置: 首页 > 科技观察

给卷积神经网络“修理工”的一份“说明书”

时间:2023-03-18 12:53:03 科技观察

卷积神经网络“修理工”斯坦福大学CS231n课程讲义的“手册”,关于如何调整卷积神经网络以提高其性能。文章主要关注深度神经网络架构下的监督学习方法。尽管本指南基于在Python3.6环境中使用tensorflow(TF)进行编程,但它仍然可以用作与语言无关的指南。假设我们有一个卷积神经网络来训练和评估,假设评估结果比预期的要差。以下是逐步排除故障和提高性能的步骤,第一部分是排除故障前的先决条件和良好做法。随后的每个章节标题都对应于该节专门研究的一个问题。我们会先抛出“比较常见”的问题,在每个标题下,我们会优先考虑“最容易实施”的解决方案。在您排除故障之前...以下是编写深度学习算法时应遵循的最佳实践,有关此主题的良好资源来自CS231n课程讲义以及Bengio的评论论文。Stanford的CS231n课程讲义:http://cs231n.github.io/Bengio的评论论文:https://arxiv.org/pdf/1206.5533v2.pdf1.使用正确的日志记录和有意义的变量名。在TF中,可以通过名称跟踪不同的变量,计算图可以显示在TF的可视化工具TensorBoard中。最重要的是,每隔几个训练步骤确保记录相关值,例如:step_number、accuracy、loss、learning_rate。如果适用,加上更具体的指标(例如,在图像分割任务中使用mean_intersection_over_unionakamean_iou)。之后,可以根据训练步骤绘制损失曲线。译者注:IoU,预测窗口与标记窗口的交集比。2.确保您的网络连接正确。使用TensorBoard或其他调试技术确保计算图中每个操作的输入和输出都是正确的,并确保在将数据和标签输入网络之前对其进行适当的预处理和匹配。3.实施数据扩充技术。虽然并非所有情况都如此,但应用简单的数据增强技术(例如镜像、旋转、随机裁剪和缩放、添加噪声、弹性变形等)可以提高性能。而TF对这些操作大部分都内置了函数,非常良心。4.对所有层使用权重初始化和正则化。不要将权重初始化为相同的值,或者更糟的是初始化为0。这样做会引入对称性和潜在的梯度分散问题,在大多数情况下会导致可怕的结果。一般来说,如果你在权重初始化方面有问题,你可以考虑在网络中添加一个BatchNormalization层。BN论文链接:https://arxiv.org/abs/1502.03167。5.确保正则项不会“压倒”损失函数中的其他项。关闭正则化,找出“损失”的大小,并适当调整正则化器的大小。确保随着正则化强度的增加,损失也会增加。6.尝试拟合一个小数据集。关闭正则化/dropout/数据增强,让神经网络使用一小部分训练集训练几个epoch。确保您可以实现零损失,如果没有,则可能有问题。在某些情况下,将损失减少到0尤其具有挑战性。例如,在图像语义分割中,如果你的损失涉及每像素softmax-edlogits和真实标签之间的交叉熵,可能真的很难将其降低到0。但是,你应该寻求接近100%accuracy,通过获取softmax-edlogits的argmax并将其与地面实况标签进行比较来计算。译者注:在机器学习中,术语“groundtruth”指的是监督学习技术中训练集分类的准确性,简单地说,正确标记的数据。7.在对上述小数据集进行过拟合的同时找到合适的学习率。下面直接引用Bengio的论文:最优学习率通常接近不增加训练误差的最大学习率。可以指导学习率启发式设置的一种观察是,例如,从较大的学习率开始,如果训练误差发散,则将最大学习率除以3,然后重试,直到观察不到发散。8.执行梯度检查。如果您在计算图中使用自定义操作(即非内置TF操作),则梯度检查尤为重要。下面的链接有一些实现梯度检查的技巧。梯度检查:http://cs231n.github.io/neural-networks-3/如果损失(LossValue)没有改善...如果你训练了几个周期,损失仍然没有改善,甚至变大,你应该考虑以下步骤:1.确保使用合理的损失函数并优化正确的张量。此处提供了常见损失函数的列表。https://en.wikipedia.org/wiki/Loss_functions_for_classification2。使用适当的优化器,此处提供了常用优化器列表。https://keras.io/optimizers/3。确保变量实际上正在训练。要检查这一点,您可以查看TensorBoard的直方图,或编写一个脚本来计算几个不同训练实例上每个张量的范数(L1或L∞)并打印出这些张量的名称。如果您的变量未按预期训练,请参考以下文章:https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#variable-not-training4。调整初始学习率并实施适当的学习率计划),这可能是最有影响力的“修复”。如果损失越来越大,可能是初始学习率太大了。另一方面,如果损失几乎恒定,则初始学习率可能太小。无论如何,一旦确定了有效的初始学习率,学习率就会衰减。像ADAM这样的优化器会在内部实现学习率衰减,但是,对这些学习率的更新通常会很慢,最好在优化器之上实施您自己的学习率计划。5.确保没有过度拟合。有实现过度拟合的方法和避免过度拟合的方法。绘制损失与训练时期。如果曲线看起来像抛物线,则可能是过度拟合。看这篇文章:https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#overfitting如果变量不是training...如上所述,使用TensorBoard的直方图,或者写一个脚本,在几个不同的training实例上运行计算每个张量的范数并打印出这些张量的名称。如果变量未按预期进行训练:1.确保TF将其视为可训练变量。查看TFGraphKeys了解更多详情。https://www.tensorflow.org/api_docs/python/tf/GraphKeys2。确保没有梯度分散发生。如果下游变量(靠近输出的变量)训练良好但上游变量(靠近输入的变量)几乎没有变化,则可能存在梯度分散问题。请参阅以下文章:https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#vanishingexploding-gradients3。确保ReLus仍在“放电”。如果大多数神经元“电压”被“钳制”为零,则应重新设计权重初始化策略,尝试不太积极的学习率计划,并尝试减少正则化(权重衰减)。译者注:ReLu,线性整流函数,又称修正线性单元,是人工神经网络中常用的激活函数。梯度扩散/梯度爆炸...1.考虑使用更好的权重初始化策略。如果训练开始时梯度更新非常小,这一点尤其重要。2.考虑改变激活函数。如果您使用的是ReLus,请考虑将它们替换为leakyReLu或MaxOut激活函数。您应该完全避免使用sigmoid激活函数,并远离tanh。3.如果使用递归神经网络,考虑使用LSTM。详情请看这篇文章:https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b过拟合...过拟合是指网络“记住”了训练数据。如果网络在训练集和验证集上的准确率相差很大,则可能是过拟合。请参阅此处的Train/Val准确性部分:http://cs231n.github.io/neural-networks-3/1。实施数据增强技术。您可以向上滚动到本文的第一部分“故障排除之前”。2.实施随机失活(dropout)。Dropout是指在训练过程中每一步随机忽略一些神经元,这些神经元的贡献在前向传播过程中被移除,而在反向传播过程中不更新。了解更多:https://machinelearningmastery.com/dropout-regularization-deep-learning-models-keras/3.添加正则化。4.实施批量归一化。详情请见此处:https://arxiv.org/abs/1502.031675。在验证集上实施提前停止。由于网络训练了太多的epoch,可能会出现过度拟合,而提前停止有助于消除这个问题。请参阅此处:https://en.wikipedia.org/wiki/Early_stopping#Validation-based_early_stopping6.如果所有其他方法均失败,请使用较小的网络。这真的应该是你最后的选择,事实上这里的课程讲义对这种做法很谨慎。还有什么调试...1.考虑使用加权损失函数。例如,在图像语义分割中,神经网络对输入图像中的每个像素进行分类。与其他类相比,某些类可能很少见,在这种情况下,对稀有类进行权衡可能会改善mean_iou指标。2.改变网络架构。您以前的网络可能太深或太浅。3.考虑使用集成模型。4.用跨步卷积替换最大池化层和平均池化层。5.执行彻底的超参数搜索。6.更改随机数种子。7.如果以上方法都失败了,再去找更多的资料。相关报道:https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc【本文为栏目组织大数据文摘原文翻译,微信公众号“大数据文摘(id:BigDataDigest)”】点此查看作者的更多多么好的文章