http://blog.csdn.net/pipisorry/article/details/52902797
调参经验
好的实验环境是成功的一半
由于深度学习实验超参众多,代码风格良好的实验环境,可以让你的人工或者自动调参更加省力,有以下几点可能需要注意:
- 将各个参数的设置部分集中在一起。如果参数的设置分布在代码的各个地方,那么修改的过程想必会非常痛苦。
- 可以输出模型的损失函数值以及训练集和验证集上的准确率。
- 可以考虑设计一个子程序,可以根据给定的参数,启动训练并监控和周期性保存评估结果。再由一个主程序,分配参数以及并行启动一系列子程序。
画图
画图是一个很好的习惯,一般是训练数据遍历一轮以后,就输出一下训练集和验证集准确率。同时画到一张图上。这样训练一段时间以后,如果模型一直没有收敛,那么就可以停止训练,尝试其他参数了,以节省时间。
如果训练到最后,训练集,测试集准确率都很低,那么说明模型有可能欠拟合。那么后续调节参数方向,就是增强模型的拟合能力。例如增加网络层数,增加节点数,减少dropout值,减少L2正则值等等。
如果训练集准确率较高,测试集准确率比较低,那么模型有可能过拟合,这个时候就需要向提高模型泛化能力的方向,调节参数。
从粗到细分阶段调参
实践中,一般先进行初步范围搜索,然后根据好结果出现的地方,再缩小范围进行更精细的搜索。
- 建议先参考相关论文,以论文中给出的参数作为初始参数。至少论文中的参数,是个不差的结果。
- 如果找不到参考,那么只能自己尝试了。可以先从比较重要,对实验结果影响比较大的参数开始,同时固定其他参数,得到一个差不多的结果以后,在这个结果的基础上,再调其他参数。例如学习率一般就比正则值,dropout值重要的话,学习率设置的不合适,不仅结果可能变差,模型甚至会无法收敛。
- 如果实在找不到一组参数,可以让模型收敛。那么就需要检查,是不是其他地方出了问题,例如模型实现,数据等等。可以参考我写的深度学习网络调试技巧
提高速度
调参只是为了寻找合适的参数,而不是产出最终模型。一般在小数据集上合适的参数,在大数据集上效果也不会太差。因此可以尝试对数据进行精简,以提高速度,在有限的时间内可以尝试更多参数。
- 对训练数据进行采样。例如原来100W条数据,先采样成1W,进行实验看看。
- 减少训练类别。例如手写数字识别任务,原来是10个类别,那么我们可以先在2个类别上训练,看看结果如何。
调参实战
梯度下降迭代步长/学习率的选择
learning rate α的设置对cost func的影响
左图:α太小更新慢,运行时间长;α太大,走过了,可能一直到达不了极值。右图:α设置太大会导致的另外两种情形。
学习率怎么选择?
1 try running gradient descent with a range of values for α, like 0.001, 0.01,..., just plot j of theta as a function of number of iterations and then pick the value of alpha that seems to be causing j of theta to decrease rapidly.
2 trying out gradient descents with each value being about 3X bigger than the previous value.
learning rate: 1 0.1 0.01 0.001, 一般从1开始尝试。很少见learning rate大于10的。学习率一般要随着训练进行衰减。衰减系数一般是0.5。
衰减时机,可以是验证集准确率不再上升时,或固定训练多少个周期以后。
3 线性搜索
也就是将xk + 步长*梯度(只有梯度是未知参数)代入f(x)中,求解出梯度。
[统计学习方法]
4 自适应学习
自适应梯度的办法,例如adam,adadelta,rmsprop等,这些一般使用相关论文提供的默认值即可,可以避免再费劲调节学习率。
在算法迭代过程中逐步降低学习率(step_size)通常可以加快算法的收敛速度。常用的用来更新学习率的方法有三种:
- 逐步降低(Step decay),即经过一定迭代次数后将学习率乘以一个小的衰减因子。典型的做法包括经过5次迭代(epoch)后学习率乘以0.5,或者20次迭代后乘以0.1。
global_step = min(global_step, decay_steps) decayed_learning_rate = (learning_rate - end_learning_rate) * (1 - global_step / decay_steps) ^ (power) + end_learning_rate
- 指数衰减(Exponential decay),其数学表达式可以表示为:α=α0e−kt,其中,α0和k是需要设置的超参数,t是迭代次数。
指数衰减有自然指数衰减和指数衰减:
decayed_learning_rate = learning_rate * exp(-decay_rate * global_step)
或者decayed_learning_rate = learning_rate * decay_rate ^ (global_step / decay_steps)如 0.5 * 0.96 ^ (global_step / 1000)
- 倒数衰减(1/t decay),其数学表达式可以表示为:α=α0/(1+kt),其中,α0和k是需要设置的超参数,t是迭代次数。
即inverse_time_decay : decayed_learning_rate = learning_rate / (1 + decay_rate * t), 如inverse_time_decay(0.5, global_step, decay_steps=1000, decay_rate=0.5)
有人说实践中发现逐步衰减的效果优于另外两种方法,一方面在于其需要设置的超参数数量少,另一方面其可解释性也强于另两种方法。
对RNN来说,有个经验,如果RNN要处理的序列比较长,或者RNN层数比较多,那么learning rate一般小一些比较好,否则有可能出现结果不收敛,甚至Nan等问题。
gradient descent中α值的自动变化
实际上迭代步长自适应减小:在最终推导出的更新公式中,可以得出以下直观结论:如果遇到一个数据使得(y−hθ(x))比较小,这时候θ的更新也会很小,这也符合直观感觉。当一个数据使得差值比较大时,θ的更新也会比较大。
the derivative here will be even smaller than it was at the green point.
As gradient descent runs. You will automatically take smaller and smaller steps until eventually you are taking very small steps.so actually there is no need to decrease alpha overtime.[machine learning ng]
规格化参数λ选择
l2正则系数0.002, 1e-5。0.0表示不正则, -1表示0.25 / batch_size。超过10的很少见
[-1, 0.0, 5.0, 1.0, 0.1, 0.01, 0.001]
选择交叉验证集(而不是test set)上 error最小的模型及其对应的λ。
通过交叉验证集上的的函数来选择λ的值。
太大的λ对应高bias(underfit),这时训练集和交叉验证集可能都没拟合好;太小的λ对应高variance(overfit),这时across validation error也会很高。
所以我们一般选择适当大的λ,此时交叉验证集上的error最小,而训练集上的误差也不大。
深度学习网络调参技巧
[深度学习网络调参技巧]from: http://blog.csdn.net/pipisorry/article/details/52902797
ref:
来源:CSDN
作者:-柚子皮-
链接:https://blog.csdn.net/pipisorry/article/details/52902797