神经网络调参指南笔记

2020年2月2日

1、神经网络调参指南笔记

  • 可视化训练过程中每个step(batch)的loss。
  • 将训练日志在打印到屏幕上的同时也写入到本地磁盘。
  • 代码中完成pytorch等训练过程可视化环境的配置,最少要可视化出训练loss曲线。
  • 初始调参阶段记得关闭L2、Dropout等用来调高模型泛化能力的超参数呐,
  • 预设值合理的batch size,一般64不错 数据集不均衡的话建议使用更大一点的值,数据集不大模型又不是太小的情况下建议使用更小一些的值
  • 初始化: 可以使用He方法[1](使用ReLU激活时)或Xavier方法[2]来进行网络参数初始化
 
阶段1:learning rate和num steps
 
  • 学习率,一般使用10倍作为学习率如 [1, 0.1, 0.01, 0.001, 0.0001, 0.00001],但是如果是GPU多卡,可以多插一些如 [0.03, 0.05, 0.003, 0.005, 0.007, 0.0005]
 
  • 可以同时跑,找一条下降最深最快的那条曲线,比如下图,选择  一个差不多已经收敛的step作为我们的训练总steps(如果数据集规模小的话也可以换算成epoch次数)
  • 如果GPU有限并且任务对显存的消耗没有太大,那么可以同时在一个GPU里挂上多组训练任务
  • 一个trick: 就是在代码里计算出来每次更新时的 梯度更新向量的模 当前参数向量的模 的比值。如果这个比值在10-3 量级附近的话说明学习率还可以,如果数量级太小,则网络更新不动,需要增大学习率 , 数量级太大则每次更新对网络的修改太大,网络很容易发生不稳定,需要降低学习率
神经网络调参指南笔记_第1张图片
 
 
阶段2:batch size和momentum
 
 
1、如果使用Adam这种考虑周全的优化器,momentum这类优化器作用不大,但是Adam找到最优的往往不如SGD找到的超参数质量高,Adam均衡,高手还是用sdg获得更好的结果。
 
2、两个参数很有用,一个是 momentum,一个是 batch size
momentum 一方面可以加速模型的收敛(减少迭代步数),另一方面还可以带领模型逃离差劲的局部最优点(没理解的快回去看看momentum SGD的公式)
batch size 数似乎也能带来类似的作用——batch size越小,噪声越大,越容易逃离局部最优点,同时这时对梯度的估计不准确,导致需要更多的迭代步数。
 
 
3、两个参数同时调的时候可以使用传统的网格搜索,也可以使用大牛们提倡的随机搜索[3]。GPU多又时间充裕的话就网格搜索,否则就随机搜索啦。 反正两个超参数时使用网格搜索也不是让人那么无法接受。还不熟悉这两种策略的同学可以去Ng在coursera开的深度学习课上补补哦,“超参数调节”这几节课讲的很清晰而且貌似是公开的。
 
4、由于这两个超参数可能涉及到模型的泛化能力,因此记得在监控loss曲线的同时也要 监控开发集准确率 哦。
 
5、这一阶段结束后,可能最优的loss曲线会发生很大的变化,可能第一阶段我们确定的num_steps在这一阶段已经变得过分冗余了,那么我们在这一阶段结束后要记得把尾巴剪短一些哦(即减少num_steps,减少的依据跟以前一样)。当然如果batch size低了很多,有可能之前的num_steps不足以充分训练了,那么要记得增加步数啦。
 
阶段3:学习率衰减策略
 
相比较前面几个超参数,学习率衰减策略就比较神奇了。有时你会发现这个超参数好像没有什么用,有时却会发现它像开了挂一样让你看似已经收敛的网络更进一层,带来更低的训练loss和更高的开发集准确率。
 
这个其实也很容易理解啦,如果你的模型在收敛时走到了“高原地带”,这时其实你衰减学习率不会带来太大改观。而如果收敛时在“峡谷边缘”来回跳跃,这时你衰减学习率就可能一步跨下峡谷,发现新大陆!当然啦,这也只能是我们的YY,在手头任务中谁也不清楚这几百万几千万维度的空间里的地形。所以不妨使用一个简单有效的学习率衰减策略简单一调,有用就继续精调,没用就算啦。
 
经典的学习率衰减策略要同时考虑4个东西:衰减开始的时机、衰减量级(线性衰减or指数衰减)、衰减速率以及衰减的周期。
 
还记得我们上个阶段得到的开发集准确率曲线吗?没错!这条曲线的低谷附近就是开始衰减的好时机!
 
 
神经网络调参指南笔记_第2张图片
衰减时机很好确定,例如上面这种状态,最高开发集准确率在3000左右,那么我们不妨从2700左右开始衰减学习率。
 
衰减量级来说,貌似大家用指数衰减更多一点。不过呢,对于指数衰减来说,衰减因子调节起来较为敏感,一旦衰减因子太小,则model往往还没有训练够呢就衰减没了。因子设置太大的话迭代好久学习率还是下不去,导致开发集的性能提升不大。考虑这些的同时还要把握好衰减的间隔(也就是每多少个steps衰减一次),如果间隔过小,则开发集准确率的波峰附近相比无衰减时更平缓,如果间隔过大,容易发现除了第一次衰减,后面的衰减都不会带来什么收益。不过,最最起码的一个设计原则是, 在到达原先的 最高开发集准确率点的那个step时,最少衰减为初始学习率的一半才行(除非你的衰减间隔真的很短)。
 
是不是感觉超级麻烦哇,为了一个学习率衰减要去考虑和计算这么多东西,感觉好麻烦哦,所以小夕个人更喜欢用下面这种懒办法。
 
这种方法是从fasttext源码里学到的,实验了一下发现还蛮好用的就一直用了下来。首先,开始衰减的点不用算, 直接从第一步起就开始线性衰减。然后假如总迭代步数为5K,学习率为0.01,那么我们就可以算一下每一步学习率的衰减量为
 
 
 
粗略算一下发现这时到达第3000步时的学习率为0.006,好像还蛮合理的诶。这样在最后一步时,学习率也恰好衰减到0。
 
在这个方案里,我们可以每个step都重新计算学习率,但是为了防止某些情况浮点下溢以及额外的计算开销(虽然可以忽略),往往还是设置一个衰减间隔,比如每100steps衰减一次。相比经典策略,这时的衰减间隔就不那么敏感啦,放心大胆的去设置。
 
使用这种懒办法基本没有引入任何难调的超参数,只要你在第二阶段的num_steps设置的合理,这一阶段的懒版学习率衰减就能往往取得不错的效果。
当然,如果在当前任务中发现这个懒办法也没带来多少收益,那这个任务可能真是地形相对平坦,对学习率衰减不太敏感,这时小夕一般不会考虑精调衰减策略。反之,如果发现这种懒办法都带来了明显的收益,那么仔细对比一下衰减策略下的开发集曲线和无衰减策略的开发集曲线,如果发现波峰后移的厉害,那可能衰减的太快了,尝试推后衰减时机。不过,既然有明显收益,那这时按照经典衰减策略再精调往往也不亏啦。
 
 
 
【1】 神经网络调参指南 https://mp.weixin.qq.com/s/ShS_1bqp0L2-eyKw5YvNmA
 
 
 
 
 
 

你可能感兴趣的:(深度学习,调参,调参)