神经网络调参心得简记+一些trick总结

马上要过年啦,祝大家新春快落!
写在前面:最近沉迷网络调参无法自拔,我就简单列举一下我遇见的情况以及对应措施记录一下,之后也会缓慢更新
TODO:

  • 学习率对收敛速度的影响
  • 学习率和BatchNormalization层之间的相互影响
  • 关于BN层:是否在每一个卷积层后都要加入一个BN层?我现在的网络结构是只在输出之前加了BN。BN层的位置有无影响?
  • SGD和Adam优化的比较
  • 规则项L1范数和L2范数的选择
  • batch_size对网络收敛的影响
  • batch_size对网络效果的影响

1、学习率对网络收敛速度的影响
我的网络结构相对简单,所以本次也是基于网络没有那么deep的情况记录的
输入为[12,12,3],结构为1层卷积+1个maxpool+2层卷积+一层MLP+softmax激活后得到两个输出,优化器为Adam函数
合适的学习率:1e-4~1e-6范围之间,这个范围的学习率能够在大部分时间保障网络以一个较为稳定的速率下降,并且一般情况下能够得到最好的优化结果(我的实验中是0.90)
学习率过大:1e-3左右,容易陷入局部最优,但是初期下降会比较快(我的实验中是0.78-0.8,基本不可能突破0.8)
学习率过小:emmmm还没尝试
其实我以前也调过一些主流CNN的网络,例如ResNet,GoogLeNet,VGG等,深度都不太相等,但是学习率基本都设置在1e-4~1e-6
基本的技巧:如果网络比较的简单,那么可以直接用小学习率闷头算,如果网络变得大了,就选用大的学习率1e-3甚至0.01量级去训练几个周期,感觉差不多到头了再按0.1的量级去减小学习率再训练

2、学习率和BN层的相辅相成相爱相杀
学习率就是learning rate,是调参一定会修改的一项参数,往往根据输入数据的不同、网络结构的不同,训练阶段的不同,都需要手动or自动的调整lr使网络进一步收敛。
BN层就是BatchNormalization层,批标准化,在这次调参过程中我才意识到我之前对BN层的理解还是不够的,错误理解划掉:我之前理解为了是对批输出数据做一个高斯分布使边缘数据(接近激活函数饱和区的输出)尽可能向0靠拢,简单来说就是做了一个数据的集中化处理
后来在这次学习过程中我学习了大佬做的可视化分析和视频,也进一步理解了BN能为网络所带来的收益,就是他能有效地解决ReLu(我本次使用的激活函数全部都是ReLu)最显著的缺点,就是造成大量dead node,把那些处于死亡边缘的节点神奇的奶住,能够让网络中有效的节点数增多。
盗一个大佬的图,这个是tanh激活函数的实例示例,可以看到把本来为0接近无效的数据变得规整
神经网络调参心得简记+一些trick总结_第1张图片
那么,具体的来举几个栗子,也是我的实验结果
总结的来说,BN层的优点如下:
(1)BN层对收敛速度的改善非常大(2)能够使用大学习率训练
(1)使用相同学习率lr=0.001,无bn层直接没有输出
神经网络调参心得简记+一些trick总结_第2张图片
在这里插入图片描述
(2)bn层lr=1e-4和无bn层lr=1e-6收敛速度对比,结果惨烈hhhh
神经网络调参心得简记+一些trick总结_第3张图片
神经网络调参心得简记+一些trick总结_第4张图片
BN层对收敛结果基本无影响,我的实验中最终结果是使用的BN层的比未使用的好0.0001,但是没有BN层的时候收敛到最好结果真的很难…………

3、神经网络优化函数的L1和L2正则化的选择
今天在别人的讨论中又学习到了新知识啦!特此记录:)
在之前的学习中,我自己对这两个方法的使用还是非常浅显的,只是单纯的知道在计算损失函数的时候加入这种正则化方法能够防止过拟合,加速收敛啥的,却不知道其真正的含义以及该如何选择。
首先理解一下这两种正则化方式的数学表达式,例举最简单的loss function: w = ∑ n ∣ X i − Y ∣ w=\sum_{n}|X_{i}-Y| w=nXiY,优化目标就是使 w w w最小。但是呢有时候数据的分布并不如意,直接最小化这个 w w w并不能达到有效的收敛效果,于是就引入了规则项 Ω \Omega Ω w w w就改为了 w = ∑ n ∣ X n − Y ∣ + Ω w=\sum_{n}|X_{n}-Y|+\Omega w=nXnY+Ω。神经网络中常用的就是L1范数和L2范数:
∣ ∣ Ω ∣ ∣ 1 = ∑ i = 0 n ∣ x i ∣ ||\Omega||_{1} = \sum_{i=0}^{n}|x_{i}| Ω1=i=0nxi
∣ ∣ Ω ∣ ∣ 2 = ∑ i = 0 n x i 2 ||\Omega||_{2} = \sqrt{\sum_{i=0}^{n}x_{i}^{2}} Ω2=i=0nxi2
相信大家都能倒背如流哈~
L1范数的优点:(1)使参数稀疏化:就是尽可能以0来表示参数,使得网络计算起来能够更加的简单(2)进行参数选择:使网络注意于少量参数非0的特征上
L2范数的优点:(1)解决过拟合问题:使网络参数都尽可能小,接近于0而不等于0,减少影响网络性能的大权重多项式参数个数(这里说起来有点绕,总之就是参数尽可能小了之后就算输出值变大,对结果影响也是很小的)(2)提升收敛速度和稳定性
(哈,以上都是应付面试7788背下来的,有需要的朋友面试上也能叭叭说两段哈hhhhh)
那么这两种范数的使用时该如何选择呢?以上说的都是复习用的,这里就是今天学习到的新知识点了!
L1和L2范数实际上在使用的时候已经对数据分布做了一定的假设了,L2范数假设数据服从高斯分布,那么如果你的数据是符合高斯分布的,那么就应该选择L2范数;那么如果数据服从的是指数分布等,就应该选用L1范数
当然,两者一起用也是完全OK的,但是具体的效果对比我暂时还没有做
关于L1和L2范数的数学意义更为详细的介绍和补充可以参考这篇博文,溜了溜了

4、Batch_size对网络收敛的影响
首先在内存允许的情况下尽可能选择大batch这一点大家应该都知道了
可能在大家遇到loss为NaN值时检索原因就会出现“减小batch_size”的tips,这里我为大家现身说法看看具体情况。
首先我以小batch,大学习率完成了第一阶段的训练,准确率达到了0.89
在这里插入图片描述
之后因为要开启二阶段小学习率的继续训练,我调大了batch(其实也是follow别人的README哈哈),学习率也设置为1e-6,结果就爆出loss问题,我以为是学习率过小,于是又把学习率调回去,发现错误没有解决,且第一个epoch结束准确率下降到了0.788
神经网络调参心得简记+一些trick总结_第5张图片
之后在比对过程中发现batch被一下加到非常大,于是改小了,并下调学习率,顺利解决,准确率也升高至0.927
神经网络调参心得简记+一些trick总结_第6张图片
原因我也搜索了一下,大致原因就是当一个batch数据量过大,会导致数据结构过多,各种结构下梯度下降方向不一致,导致各次梯度修正值相互抵消,无法修正。详细可参考这里

5、Batch_size对网络效果的影响
这里主要是对比在调大batch size后,训练同样步数(相当于增大了数据量)的情况下网络最终的测试效果会有提升吗?
答案是没有,可能也是和模型有关。
我首先是在batch size=64下进行试验,40w步指标能达到2.03%,且100步训练时长2-3秒
之后加大batch size到256,40w步指标下降到1.6%左右,且100步训练时长10+秒
之后折中选择batch size到128,45w步指标到1.95%,且100步训练时长7秒左右
注意,我在过程中是相应的调整了学习率衰减倍数的
所以在batch size的选择上还是要慎重,绝对不是越大越好。

MxNet和TensorFlow
这里是一个混入其中的part
本来我之前一直用的tensorflow开发,想着背靠谷歌好乘凉,但是众所周知,TensorFlow对于显存的霸占简直令人发指,直接默认占满全部显存,哇,特别是当你和别人资源共享的时候………………我仍记得我苦口婆心的告诉同事一定记得标记GPU号的痛苦
但是这次尝试了一下MxNet框架,哇塞!这种幸福感是真实的吗!
神经网络调参心得简记+一些trick总结_第7张图片

你可能感兴趣的:(原创,神经网络参数调节,神经网络,批标准化,学习率,调参)