神经网络 测试集loss不下降_一份关于神经网络训练的“秘籍”(二)

c40245ebaf2fe023671ba28566ab0406.png
上一篇文章讲到神经网络训练过程中两个令人头疼的问题以及训练前如何审视自己的数据,这次我们更进一步,看看模型训练前的准备以及训练过程中会遇到的一些问题。
Eric:一份关于神经网络训练的“秘籍”​zhuanlan.zhihu.com
c19d1a30ea3f91f4eee9315d28735760.png

建立端对端测试框架以及设定虚拟基准

现在我们对自己的数据集有了一定的理解,下一步是不是该祭出那上百层的、超酷的网络,泡一杯咖啡,在咖啡与4 TITAN夹杂的香气中假装严肃的打开youtube : ) ? 好吧,我们依然走在痛苦的训练道路上。接下里,我们需要设定一个从训练到评价的完整框架,利用这个框架做一些实验增加我们对训练过程的信心。这个阶段最好选一些不怎么容易在其中犯错的简单模型,比如说线性分类器,或者很小的卷积网络。在这些模型上,我们进行完整的训练、预测、评价,并且基于一些过于过程或结果猜想做一系列的消融实验。

一些小技巧 :)

  • 使用固定的随机种子。 如数据的随机打乱,在代码中有许多需要进行随机的地方,而使用固定的随机种子可以保证当你再次执行代码时,随机的状态与上一次相同。这有助于在进行不同实验对比时,保证相同的实验环境,并且也能消除一个可能会带来麻烦的变量。
  • 简化。确保屏蔽一些不必要的辅助功能。比如说,关掉数据扩充(data augmentation)功能。数据扩充只是为了增强模型的鲁棒性,在此阶段并不需要,相反,只是这只是新增bug的机会。
  • 确认初始loss. 确保你的初始loss值正确。举个例子,如果你正确地初始化了你的网络,那么你可以尝试计算在随机状况下loss的值应该是多少,比如softmax计算 -log(1/n_classes)对比你的初始化loss。同样的,在L2回归等不同的损失函数都适用。
  • 合理初始化。 正确地初始化最后一层的参数。比如,当你做回归时,如果你的目标结果是均值为50的数,那么你可以将最后一层的偏差(bias)设置为50。又或者你的数据集分布较不均衡,正负样本比例为1:10,那么就可以在你的logits(概率的计算)添加偏差,使得你的网络在初始化时就对正样本有10%的预测概率。正确地设置这些参数可以加速网络的收敛,因为基本上,在前期的迭代过程中,你的网络基本上就是在学习这些偏差。
  • 人类基准。监控那些除了loss外,可以被理解或检查的指标(比如准确率)。只要有可能,测试下你自己的准确率(即人类水平的准确率),并与监控的指标进行比较。或者,可以将同样的数据分给两个人进行标记,其中一个作为预测结果,另一个作为真实值,两者进行比较可以了解对于该数据人类水平的准确率的大致情况。
  • 与训练集独立的基准。训练一个与输入独立的基准,比如最简单的可以将你的所有输入全部置零。这样的基准训练出来的结果肯定比当你真正输入你的数据时要糟糕的多,真的吗 :)。从与这个基准的对比,就可以分析你的网络是否有从输入数据中获取任何信息。
  • 过拟合小批量数据。使用很少的数据(比如两个)来过拟合一个批次的数据。通过这样做,我们不断增加网络的性能(比如增加网络深度或filter数量),并确保我们可以达到最小的loss,甚至是0。同时,你也可以可视化这个小批量数据的真实值和预测值,并确认在loss达到最小时,预测和真实值几乎完全一致。如果并不一致,那么肯定有什么地方存在bug。先确保网络有能力且正确地过拟合一小批数据,可以快速有效的帮你检测是否有bug存在,或者你的网络是否有这个能力。
  • 验证训练loss的不断下降。这个阶段由于我们正使用一个较简单的模型,所以应该对你的数据是欠拟合的。试着增加一点模型的性能,看下你的训练loss(收敛时)是不是按照设想的那样,也下降了呢?
  • 可视化最终输入网络的数据。 y_hat = model(x) (或tf中的 sess.run, 或caffe自定义visual层) 这一行代码前可视化你的数据是个非常不错的选择。你可以可视化经过一系列可能的处理后,最终输入网络的数据到底是什么样的。这一步对于debug数据预处理和数据扩充等过程中的错误非常有用,比如你的输入数据和label数据不是一一对应,比如你对输入做了镜像却忘了对label做镜像,等等。在我看来,在数据真正传入网络前可视化是个非常有用的技巧,它不仅可以帮助检查数据传输过程中的错误,也能让你了解自己到底喂了什么样的数据给你的网络。
  • 动态可视化预测结果。可视化模型训练过程中的预测结果是件非常有趣的事。针对固定的测试数据,观察训练过程中预测结果的变化过程。通过观察,你会对训练的过程有个非常直观的感受。很多时候,你可以感受到你的网络正“挣扎”着拟合你的数据,比如训练过程中某个部分的预测结果不断反复地变化,暴露出网络对于这个部分预测的不稳定。同时也可以通过不稳定抖动的数量推断出学习率是否设置的太高或者太低了。
  • 使用后向传播绘制依赖关系。你的网络相关代码往往包含很多负责的,向量化的,带有广播(broadcast)的操作。
  • 设置一些特例。这是一个更加通用的编程技巧,经常有很多人希望可以一步到位,从什么都没有直接写出一个通用性强、模块化程度高的代码,从而导入bug。我喜欢首先对手头正在做的事情,先写简洁的、针对特定问题的代码,等它能够正常的完成功能时再重构成一般通用的代码。这个技巧尤其在矢量化编程是非常有效。比如在python中,使用numpy直接进行大矩阵的计算往往比完全的for循环要高效得多,但也容易出错。我喜欢在一开始用最笨最简单的方法完成目的,然后再回过头来将它进行适当的优化。

7a05c656aa2abf9dad96e9852917e12f.png

过拟合

到了这个阶段,我们应该对我们的数据有了一个很好的理解,并且有了一个完整的从训练模型到模型评估的流程。对于任何模型,我们可以放入这个流程进行训练,并计算那些我们需要的评价指标。同时,我们也有了与训练集独立的基准,以及在一些虚拟基准上的所达到的效果。同时,我们也对人类水平(对于数据的识别)有了很粗略的了解,这个水平可以被设置为我们的模型所期望达到的水平。那么现在就可以踏上开始不断迭代、寻找一个优秀模型的旅途了。

我喜欢通过两步来完成这个阶段。首先,拿一个足够大而能够过拟合的模型训练(即关注训练loss),然后正确地正则化模型(牺牲一些训练loss从而提升验证集中的loss)。之所以这么做的原因是,如果没有任何模型可以过拟合而达到非常小的loss的话,那么很有可能存在一些其它的问题,比如哪里有bug,哪里不小心设置错误了。

再次一些小技巧 :)

  • 模型选择。为了达到非常低的训练损失,你需要为你的数据选择一个合适的网络结构。而对于这一点有个很重要建议:不要总想着当英雄。可能这是神经网络的魅力和缺点吧,见过不少人(包括我)在这个时候就开始发挥自己天马行空的想象力,像乐高积木一样构建出一堆自己认为非常有创造性的网络,并迫不及待的开始训练,期待着能得到"state of the art"的结果。但往往在旁人看来,总觉得像是牛鬼蛇神。在项目早期阶段你需要努力的克制这种诱惑。建议你可以首先找一下与项目相关的论文,然后直接复制他们的网络结构来达到不错的效果。比如,如果你相对你的图片进行分类,你可以简单的先复制粘贴ResNet-50来进行训练而达到一个不错的效果。你可以在项目后期发挥你的创造力,然后打败它也不迟。
  • Adam 很方便。在设立基准的早起阶段,非常推荐用Adam,并建议 lr=3e-4。在我的使用感受来看,Adam在早期可以为你免去很多问题,比如糟糕的学习率。通过阅读论文你可以发现,对于卷积神经网络来说,一个经过精心“调教”后的SGD往往会比Adam要好一些。但是最佳的学习率范围比较小,且不能适用于不同问题,需要花费大量时间来寻找。(注: 如果你使用RNN或者相关序列模型,那么在项目初始阶段使用Adam就更常见了)
  • 一次只复杂化一个内容。如果你有一堆的内容想加到你的分类模型中,建议你一个一个地加入,并且每一次确认模型达到了你所期待的性能增强。不要一开始就把所有东西一股脑儿的都塞给你的模型。还有其它的办法,比如,你可以试着先输入较小的图片,然后尝试更大的图片,等等。
  • 不要相信学习率衰减默认设置。如果你想要使用别的领域的模型,那你就要对学习率衰减非常小心了。不仅是针对不同问题你需要使用不同的衰减策略,而且更糟糕的是,典型的衰减策略会基于epoch进行设置,那么将会根据你的数据集的大小而发生巨大的变化。比如,ImageNet每隔30个epoch,lr会除以10。如果你没有在ImageNet上训练,那么你应该肯定不想要这样。要是不小心,你的代码很可能会过早的使你的学习率缩减为零,使你的模型无法收敛。建议可以试着关闭学习率衰减(使用fixed lr)并在最后再来调整这一点。
先到这为止吧,下次接着聊模型的正则化以及其它有趣的事情吧~

b6466946ac2c728349d1358de2efe9e5.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值