作者 | Russell Stewart
译者 | zhwhong(@zhwhong_shsf)
整理 | AI100(rgznai100)
以下建议主要针对神经网络的初学者。这些建议主要基于我在行业应用和斯坦福大学里为神经网络初学者提供建议所获得的经验。
神经网基本上比大多数程序更难调试,因为大多数神经网络错误不会导致类型错误或运行时错误。它们只是导致神经网络难以收敛。特别是当你刚接触这个的时候,它会让人非常沮丧!但是一个有经验的神经网络训练者将能够系统地克服这些困难,尽管存在着大量似是而非的错误消息:性能错误:你的神经网络没有训练好。对于缺乏经验的人来说,这种信息是令人生畏的。但对有经验的,这是一个非常好的错误信息。这意味着样板代码已经偏离了正确道路,是时候去深挖一下原因了!
➤如何应对NaN
到目前为止,我从学生那里得到的最常见的第一个问题是,“为什么我出现了 NaNs ?”。有时候,这个问题的答案很复杂。但大多数情况是,NaNs 在前100轮迭代中就出现了,这时候这个答案就非常简单:你的学习率(learn rate)设置的太高了。当学习率非常高时,在训练的前100轮迭代中就会出现NaNs。尝试不断的把学习率除以3,直到在前100轮迭代中不再出现NaNs。一旦这样做起作用了,你就会得到一个很好的初始学习率。根据我的经验,最好的有效学习率一般在你得到NaNs的学习率的1-10倍以下。
如果你是在超过100轮迭代之后才出现的NaNs,还有2个其他的常见原因。
➤当神经网络不再学习的时候怎么办?
当你不再碰到NaNs的时候,很可能就会遇到这样一种情况,你的网络顺利地训练了几千轮,但是训练的loss值却在前几百个回合后不再减小。如果你是初次构建代码库的话,基本上不会说需要等待超过2000轮迭代。这不是因为所有网络都能在2000次迭代内开始学习,而是因为你在编码中引入bug的几率很高,与其等待长时间的迭代,不如早早的进入调试模式。现在你应该不断缩小问题的范围,直到你的网络可以在2000次迭代内开始学习。幸运的是,有2个不错的维度来降低复杂度:
一个为新想法扩展网络的小技巧就是慢慢地缩小上述两步中所做的简化。这是坐标上升法的一种形式,而且十分有用。一开始,你可以证明这个网络可以记住少量的样本,然后可以证明它在一个简化版的子问题中可以在验证集上具有泛化能力。慢慢提升难度,稳步前进。这并不像第一次Karpathy的风格那么有趣,但至少它是有用的。有些时候你会发现有些问题本身十分困难,难以在2000次迭代内完成学习。这很棒!但是它很少需要以前那种难度级别问题迭代次数的十倍以上。如果真需要这么多次迭代,可以尝试寻找一个中间的复杂度。
➤调整超参数
现在网络已经开始学习东西了,你可能会觉得非常不错。但你可能发现它不能解决这个问题中最困难的版本。超参数的调整就是其中的关键。也许有人仅仅下载了一个CNN包然后在上面跑自己的数据集,并告诉你超参数的调整并不会带来改变。你要认识到他们在用已有的框架解决已有的问题。如果你使用新架构解决新问题,则必须调试超参数来获得一个良好的配置。最好是为你的特定问题读一些超参数教程,但为了完整性我会在这里列出一些基本的想法:
➤总结
调试神经网络可能比调试传统程序更费精力,因为几乎所有错误都被投射到整个网络表现的单一维度。尽管如此,二分查找仍然起作用。通过交替
1)调整问题的难度,和2)使用少量的训练样本,你可以快速解决最初的问题。然后超参数调整和长时间的等待就可以解决你剩下的问题了。
原文地址 http://russellsstewart.com/blog/0 译文地址 http://www.jianshu.com/p/ba2ac29810e6