训练神经网络之前,不要碰任何模型,而是应该尽力检查数据。经常需要数小时的查看数据,了解数据分布,找到数据模式,我们大脑非常适合干这个,有一次,我发现数据集中有一些重复的数据,另一次,我发现了损坏的图片/标签,寻找一些数据不平衡。我通常还会注意我自己对数据进行分类的过程,能够给我们最终的架构实现一些线索。例如,
神经网络是数据集的压缩和编译,你能从predict中理解输出是怎么来的,一旦你发现输出和数据不匹配,一定是哪里错了
找到这个感觉之后,你可以code 一些你想到的 搜索/过滤/排序(标签类型,图片尺寸,标注数量等)算法,并可视化分布数来,通过一些异常值,能查看到数据集的bugs
这个阶段最好选择一些简单的模型,例如 - 线性分类器或非常小的ConvNet。训练并可视化损失和其他指标(例如,acc),模型预测,并在此途中执行一系列test
eval
。在绘制eval
损失时,在整个(大)测试集上运行评估。不要只是在batch
上绘制测试损失,然后在 Tensorboard 中平滑。loss
@ init。验证loss
从正确的loss
值开始。例如。如果正确初始化最后一层,则应在初始化时在 softmax 上计算 -log(1/n_classes)。可以为 L2 回归、Huber 损失等计算出相同的默认值。(这儿没弄明白什么意思)mean
为 50 的数据,则将最终 bias
初始化为 50。如果您有一个正负样本比为 1:10 的不平衡数据集,请在logits
层 上设置bias
,以便您的网络 在初始化时以0.1的概率预测。正确设置这些将加速收敛并消除“曲棍球”loss
曲线(loss
先低后高),在最初的几次迭代中,网络基本上只是学习bias
。logits的理解参考这儿baseline
。监控除损失之外的我们可解释和可检查的指标(例如accuracy
)。尽可能评估自己的accuracy
并与之进行比较。或者,对测试数据的预测和真实相比较。baseline
。训练与输入无关的 baseline
(例如,最简单的方法是将所有输入设置为0)。应该比有实际输入数据(不为0)的性能更差。确定模型是否从输入中提取到信息。batch
上过拟合。只包含几个样本(至少2个)的单个batch上过拟合。我们可以增加模型的容量(例如添加layers
或filters
)filter有两种理解:在有的文档中,一个filter等同于一个卷积核:只是指定了卷积核的长宽深; 而有的情况(例如tensorflow等框架中,filter参数通常指定了卷积核的长、宽、深、个数四个参数),filter包含了卷积核形状和卷积核数量的概念:即filter既指定了卷积核的长宽深,也指定了卷积核的数量。
并验证我们可以达到最低的loss
(例如0)。把标签和预测可视化在同一个图中,并确保一旦我们达到最小损失,它们就会完美对齐。如果不是这样,那就有bug,我们无法继续进行下一阶段。loss
。在这个阶段,你可能会欠拟合你的数据集,因为你正在使用一个玩具模型。尝试稍微增加其容量。您的训练loss
是否按预期减少了?y_hat = model(x)
之前(或 tf 中的 sess.run)之前。也就是说 - 要准确地可视化什么数据送入了网络,将数据和标签的原始张量解码为可视化。这是唯一的“真相来源”。我无法统计这有多少次拯救了我并揭示了数据预处理和增强方面的问题。prediction
。我喜欢在训练过程中对固定测试批次的模型预测进行可视化。这些prediction
如何“动态”变化将为告诉我们关于训练如何进行的非常好。很多时候,如果网络以某种方式抖动,不稳定,会感觉到网络“努力”取拟合你的数据。非常低或非常高的学习率很容器引起抖动。viewview
而不是transpose/permute
)并且不经意间在batch
维度上混合了信息。令人沮丧的是,网络通常仍能正常训练,因为它会忽略来自其他样本的数据。debug
这个的一种方法是将损失设置为微不足道的东西,例如样本i
的所有输出的总和,运行backward
一直到输入 ,并确保您得到一个非零梯度在第 i 个输入上。相同的策略可用于例如确保您在时间 t 的Autoregressive model
仅取决于 1…t-1。更一般地说,梯度决定了网络中什么的信息,这对调试很有用。这个阶段需要更好的理解数据集,并完全训练和评估整个代码,对于任何一个模型,我们可以计算出metric
,也掌握了与输入无关的baseline
的性能表现,尽管是糟糕的baseline
,我们对性能有了个直观的感觉,这个阶段,我们回迭代让模型更好
找到训练出好模型的方法有两步,第一,先获得一个能过拟合的足够大的模型(关注训练损失),然后适当的正则化(关注验证损失)。我喜欢这两步的原因是如果不能达到低的错误率,那就说明有bugs
paper
,并复制他们最简单的架构,实现了良好的性能。例如。如果正在图像分类,请不要成为英雄,第一次运行只需复制粘贴reset-50
。adam
是安全的。baseline
线的早期阶段,我喜欢使用adam
,3e-4
的lr
。在我的体验中,adam
是非常宽容的超参数,即使是糟糕的lr
。对于Convnets
,一个调整好的SGD
几乎总是略高于adam
,但最佳lr
区域更狭窄,具体问题。 (注意:如果使用的RNN和相关序列模型使用adam
更常见。在项目的初始阶段,再次,不要成为英雄,并遵循相关的论文。)signals
插入您的分类器,我会建议您逐一插入它们,每次确保获得您预期的性能提升。还有其他建立复杂性的方法 - 例如可以先尝试插入较小的图像,并使其更大,以后更大。learning rate decay
。learning rate decay
。不同的模型使用不同的decay schedules
,在默认的epoch
数下使用默认的schedule
会更糟,schedule
应根据数据集的大小变化。例如。 Imagenet将在epoch 30上设置decay
10,如果不是训练Imagenet,那么你肯定不需要decay
。如果不小心,代码可以偷偷的更早的将lr
调整变到零,而导致模型不收敛。在我自己的工作中,我总是禁用 learning rate decay
(我使用常数LR
)并在最后一直调整这一切。拟合了训练数据之后,我们选在需要在验证集上提升精度,同时会降低训练集的精度,一些tips
backbone
顶部使用全连接的层在ImageNet上,但这些已经用简单的平均池化代替,消除了该过程中的一大堆参数。drop
。添加dropout
。使用Dropout2d(空间丢失)weight decay
。增加weight decay
的惩罚系数。early stopping
。根据您的test,val损失停止训练,以保存模型,防止过拟合。