未阅读: https://www.zhihu.com/question/29641737 http://blog.csdn.net/han_xiaoyang/article/details/50521064
A Good Start:
- 将各个参数的设置部分集中在一起。如果参数的设置分布在代码的各个地方,那么修改的过程想必会非常痛苦。
- 可以输出模型的损失函数值以及训练集和验证集上的准确率。
- 可以考虑设计一个子程序,可以根据给定的参数,启动训练并监控和周期性保存评估结果。再由一个主程序,分配参数以及并行启动一系列子程序。
- 画图:一般是训练数据遍历一轮以后,就输出一下训练集和验证集准确率。这样训练一段时间以后,如果模型一直没有收敛,那么就可以停止训练,尝试其他参数了,以节省时间。
如果训练到最后,训练集,测试集准确率都很低,那么说明模型有可能欠拟合。那么后续调节参数方向,就是增强模型的拟合能力。例如增加网络层数,增加节点数,减少dropout值,减少L2正则值等等。
如果训练集准确率较高,测试集准确率比较低,那么模型有可能过拟合,这个时候就需要向提高模型泛化能力的方向,调节参数。 -
分阶段调参:实践中,一般先进行初步范围搜索,然后根据好结果出现的地方,再缩小范围进行更精细的搜索。
建议先参考相关论文,以论文中给出的参数作为初始参数。至少论文中的参数,是个不差的结果。如果找不到参考,那么只能自己尝试了。可以先从比较重要,对实验结果影响比较大的参数开始,同时固定其他参数,得到一个差不多的结果以后,在这个结果的基础上,再调其他参数。例如学习率一般就比正则值,dropout值重要的话,学习率设置的不合适,不仅结果可能变差,模型甚至会无法收敛。如果实在找不到一组参数,可以让模型收敛。那么就需要检查,是不是其他地方出了问题,例如模型实现,数据等等。可以参考我写的深度学习网络调试技巧
样本数据:
zero-center ,这个挺常用的.
X -= np.mean(X, axis = 0) # zero-center
X /= np.std(X, axis = 0) # normalize
PCA whitening,这个用的比较少.
初始化
1、初始化参数尽量小一些,这样 softmax 的回归输出更加接近均匀分布,使得刚开始网络并不确信数据属于哪一类 ;另一方面从数值优化上看我们希望我们的参数具有一致的方差(一致的数量级),这样我们的梯度下降法下降也 会更快。同时为了使每一层的激励值保持一定的方差,我们在初始化参数(不包括偏置项)的方差可以与输入神经 元的平方根成反比 2、权值初始化(Weight Initialization):可用高斯分布乘上一个很小的数。如果想偷懒,不妨试试0.02*randn(num_params)。这个范围的值在许多不同的问题 上工作得很好。当然,更小(或更大)的值也值得一试。如果它工作得不好,那么使用 init_scale/sqrt(layer_width)*randn来初始化每个权值矩阵。这种情况下,init_scale应该设置为0.1或者1,或者类似的值 |
eg:
uniform
W = np.random.uniform(low=-scale, high=scale, size=shape)
glorot_uniform
scale = np.sqrt(6. / (shape[0] + shape[1]))
np.random.uniform(low=-scale, high=scale, size=shape)
高斯初始化:
w = np.random.randn(n) / sqrt(n),n为参数数目
激活函数为relu的话,推荐
w = np.random.randn(n) * sqrt(2.0/n)
svd ,对RNN效果比较好,可以有效提高收敛速度.
自动调参
自动调参当前也有不少研究。下面介绍几种比较实用的办法:
- Gird Search. 这个是最常见的。具体说,就是每种参数确定好几个要尝试的值,然后像一个网格一样,把所有参数值的组合遍历一下。优点是实现简单暴力,如果能全部遍历的话,结果比较可靠。缺点是太费时间了,特别像神经网络,一般尝试不了太多的参数组合。
- Random Search。Bengio在Random Search for Hyper-Parameter Optimization中指出,Random Search比Gird Search更有效。实际操作的时候,一般也是先用Gird Search的方法,得到所有候选参数,然后每次从中随机选择进行训练。
- Bayesian Optimization. 贝叶斯优化,考虑到了不同参数对应的实验结果值,因此更节省时间。具体原理可以参考这个论文: Practical Bayesian Optimization of Machine Learning Algorithms ,这里同时推荐两个实现了贝叶斯调参的Python库,可以上手即用:
- jaberg/hyperopt, 比较简单。
- fmfn/BayesianOptimization, 比较复杂,支持并行调参。
batchsize:
目的:在内存效率和内存容量之间寻找最佳平衡
1、决定一次训练的样本数目。
2、影响到模型的优化程度和速度。
batch = n
如果数据集比较小我们就采用全数据集。全数据集确定的方向能够更好地代表样本总体,从而更准确地朝向极值所在
的方向。
注:对于大的数据集我们不能使用全批次,因为会得到更差的结果。
batch=k(1<k<n)
选择一个适中的 Batch_Size 值,将会以batch的大小将数据输入深度学习的网络中,然后计算这个batch的所有样本的平均
损失,即代价函数是所有样
本的平均。
batch=1
每次修正方向以各自样本的梯度方向修正,横冲直撞各自为政,难以达到收敛。
适当的增加Batchsize的优点:
1.通过并行化提高内存利用率。
2.单次epoch的迭代次数减少,提高运行速度。(单次epoch=(全部训练样本/batchsize)/ iteration =1)
3.适当的增加Batch_Size,梯度下降方向准确度增加,训练震动的幅度减小。
经验总结:
相对于正常数据集,如果Batch_Size过小,训练数据就会非常难收敛,从而导致underfitting。
增大Batch_Size,相对处理速度加快。
增大Batch_Size,所需内存容量增加(epoch的次数需要增加以达到最好结果)。
这里我们发现上面两个矛盾的问题,因为当epoch增加以后同样也会导致耗时增加从而速度下降。因此我们需要寻找最好的batch_size。
clip c(梯度裁剪):
限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15
Iterator
1、神经网络中我们希望通过迭代进行多次的训练以到达所需的目标或结果。每一次迭代得到的结果都会被作为下一次迭代的初始值。
2、一个迭代 = 一个正向通过+一个反向通过
epoch
激活函数:
1、激活函数要视样本输入选择
2、激活函数我们现在基本上都是采用Relu,我们在初始化偏置项时,为了避免过多的死亡节点(激活值为0)一般可以初始化为一个较
小的正值。
3、隐藏层的激活函数,tanh往往比sigmoid表现更好
学习率(Leraning Rate)
momentum
1、滑动平均模型,在训练的过程中不断的对参数求滑动平均这样能够更有效的保持稳定性,使其对当前参数更新不敏
感。例如加动量项的随机梯度下降法就是在学习率上应用滑动平均模型。
2、一般我们会选择0.9-0.95之间
weight decay
我们一般会选择0.005,
filter
个数为奇数
dropout
1、现在也是标配的存在,在测试时不要忘记关闭dropout,然后对权值求乘积(也就是1-dropout率)。当然,要确保将
网络训练得更久一点。不同于普通训练,在进入深入训练之后,验证错误通常会有所增加。dropout网络会随着时间推
移而工作得越来越好,所以耐心是关键。
2、dropout: 0.5
改进优化算法:
- 要做梯度归一化,即算出来的梯度除以minibatch size
- clip c(梯度裁剪): 限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15
- dropout对小数据防止过拟合有很好的效果,值一般设为0.5,小数据上dropout+sgd效果更好. dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置.关于RNN如何用dropout,可以参考这篇论文:arxiv.org/abs/1409.2329
- adam,adadelta等,在小数据上,我这里实验的效果不如sgd,如果使用sgd的话,可以选择从1.0或者0.1的学习率开始,隔一段时间,在验证集上检查一下,如果cost没有下降,就对学习率减半. 我看过很多论文都这么搞,我自己实验的结果也很好. 当然,也可以先用ada系列先跑,最后快收敛的时候,更换成sgd继续训练.同样也会有提升.
- 除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数.
- rnn的dim和embdding size,一般从128上下开始调整. batch size,一般从128左右开始调整.batch size合适最重要,并不是越大越好.
- word2vec初始化,在小数据上,不仅可以有效提高收敛速度,也可以可以提高结果.
- 尽量对数据做shuffle
- LSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的结果。
微调fintuning:
fine-tuning的时候,可以把新加层的学习率调高,重用层的学习率可以设置的相对较低
*--------------------------------------------------------------------------------------------------------------------------------------
Q1、检测自己的数据是否存在可以学习的信息
Q2、数据集中的数值是否泛化(防止过大或过小的数值破坏学习)。
如果是错误的数据则你需要去再次获得正确的数据,如果是数据的数值异常我们可以使用zscore函数来解决这个问题,如果是网络的错误,则希望调
整网络,包括:网络深度,非线性程度,分类器的种类等等。
underfitting:
增加网络的复杂度(深度),
降低learning rate,
优化数据集,
增加网络的非线性度(ReLu),
采用batch normalization,
overfitting:
丰富数据,
增加网络的稀疏度,
降低网络的复杂度(深度),
L1 regularization,
L2 regulariztion,:1.0,超过10的很少见
添加Dropout,
Early stopping--看到我们在验证集的上的正确率开始下降就停止训练
适当降低Learning rate,
适当减少epoch的次数,
调整方法就是保持其他参数不变,只调整一个参数。
learning rate,
minibatch size,
epoch,
filter size,
number of filter
4、其他
梯度检验:当我们的算法在训练出现问题而进行debug时,可以考虑使用近似的数值梯度和计算的梯度作比较检验梯度是否计算正确。
*------------------------------------------------------------------------------------------------------------------------------------
1. 完全不收敛:
2. 部分收敛:
3. 全部收敛:
CNN中的独有技巧:
- CNN中将一个大尺寸的卷积核可以分解为多层的小尺寸卷积核或者分成多层的一维卷积。这样能够减少参数增加非线性
- CNN中的网络设计应该是逐渐减小图像尺寸,同时增加通道数,让空间信息转化为高阶抽象的特征信息。
- CNN中可以利用Inception方法来提取不同抽象程度的高阶特征,用ResNet的思想来加深网络的层数。
- CNN处理图像时,常常会对原图进行旋转、裁剪、亮度、色度、饱和度等变化以增大数据集增加鲁棒性。
Ensemble:深度学习中一般有以下几种方式
- 同样的参数,不同的初始化方式
- 不同的参数,通过cross-validation,选取最好的几组
- 同样的参数,模型训练的不同阶段
- 不同的模型,进行线性融合. 例如RNN和传统模型
batch=64 每batch个样本更新一次参数。
subdivisions=8 如果内存不够大,将batch分割为subdivisions个子batch,每个子batch的大小
momentum=0.9 动量
decay=0.0005 权重衰减正则项,防止过拟合
angle=0 通过旋转角度来生成更多训练样本
saturation = 1.5 通过调整饱和度来生成更多训练样本
exposure = 1.5 通过调整曝光量来生成更多训练样本
hue=.1 通过调整色调来生成更多训练样本
learning_rate=0.0001 初始学习率
max_batches = 45000 训练达到max_batches后停止学习
policy=steps 调整学习率的policy,有如下policy:CONSTANT, STEP, EXP, POLY, STEPS,
SIG, RANDOM
steps=100,25000,35000 根据batch_num调整学习率
scales=10,.1,.1 学习率变化的比例,累计相乘
batch_normalize=1 是否做BN
filters=32 输出多少个特征图
size=3 卷积核的尺寸
stride=1 做卷积运算的步长
pad=1 如果pad为0,padding由 padding参数指定。如果pad为1,padding大小为size/2
activation=leaky 激活函数:logistic,loggy,relu,elu,relie,plse,hardtan,lhtan,linear,ramp,leaky,tanh,stair
[maxpool]
size=2 池化层尺寸
stride=2 池化步进
......
#######
[route] 从网络的前几层获取细粒度特征
layers=-9
[reorg] passthrougth layer: 使得这些特征和后面特征图的大小匹配r
stride=2
[route]
layers=-1,-3 route层起连接作用,reorg层来match特征图尺寸。
...
[convolutional]
size=1
stride=1
pad=1
filters=125 region前最后一个卷积层的filters数是特定的,计算公式为filter=num*(classes+5)
5的意义是5个坐标,论文中的tx,ty,tw,th,to
activation=linear
[region]
anchors = 1.08,1.19, 3.42,4.41, 6.63,11.38, 9.42,5.11, 16.62,10.52 预选框,可以手工挑选,也可以通过k means 从训练样本中学出
bias_match=1
classes=20 网络需要识别的物体种类数
coords=4 每个box的4个坐标tx,ty,tw,th
num=5 每个grid cell预测几个box,和anchors的数量一致。当想要使用更多anchors时需要调大num,且如果调大num后训练时Obj趋近0的话可以尝试调大object_scale
softmax=1 使用softmax做激活函数
jitter=.2 通过抖动增加噪声来抑制过拟合
rescore=1 暂理解为一个开关,非0时通过重打分来调整l.delta(预测值与真实值的差)
object_scale=5 栅格中有物体时,bbox的confidence loss对总loss计算贡献的权重
noobject_scale=1 栅格中没有物体时,bbox的confidence loss对总loss计算贡献的权重
class_scale=1 类别loss对总loss计算贡献的权重
coord_scale=1 bbox坐标预测loss对总loss计算贡献的权重
absolute=1
thresh = .6
random=0 random为1时会启用Multi-Scale Training,随机使用不同尺寸的图片进行训练。
小
momentum=0.9 动量
decay=0.0005 权重衰减正则项,防止过拟合
angle=0 通过旋转角度来生成更多训练样本
saturation = 1.5 通过调整饱和度来生成更多训练样本
exposure = 1.5 通过调整曝光量来生成更多训练样本
hue=.1 通过调整色调来生成更多训练样本
learning_rate=0.0001 初始学习率
max_batches = 45000 训练达到max_batches后停止学习
policy=steps 调整学习率的policy,有如下policy:CONSTANT, STEP, EXP, POLY, STEPS,
SIG, RANDOM
steps=100,25000,35000 根据batch_num调整学习率
scales=10,.1,.1 学习率变化的比例,累计相乘
batch_normalize=1 是否做BN
filters=32 输出多少个特征图
size=3 卷积核的尺寸
stride=1 做卷积运算的步长
pad=1 如果pad为0,padding由 padding参数指定。如果pad为1,padding大小为size/2
activation=leaky 激活函数:logistic,loggy,relu,elu,relie,plse,hardtan,lhtan,linear,ramp,leaky,tanh,stair
[maxpool]
size=2 池化层尺寸
stride=2 池化步进
......
#######
[route] 从网络的前几层获取细粒度特征
layers=-9
[reorg] passthrougth layer: 使得这些特征和后面特征图的大小匹配r
stride=2
[route]
layers=-1,-3 route层起连接作用,reorg层来match特征图尺寸。
...
[convolutional]
size=1
stride=1
pad=1
filters=125 region前最后一个卷积层的filters数是特定的,计算公式为filter=num*(classes+5)
5的意义是5个坐标,论文中的tx,ty,tw,th,to
activation=linear
[region]
anchors = 1.08,1.19, 3.42,4.41, 6.63,11.38, 9.42,5.11, 16.62,10.52 预选框,可以手工挑选,也可以通过k means 从训练样本中学出
bias_match=1
classes=20 网络需要识别的物体种类数
coords=4 每个box的4个坐标tx,ty,tw,th
num=5 每个grid cell预测几个box,和anchors的数量一致。当想要使用更多anchors时需要调大num,且如果调大num后训练时Obj趋近0的话可以尝试调大object_scale
softmax=1 使用softmax做激活函数
jitter=.2 通过抖动增加噪声来抑制过拟合
rescore=1 暂理解为一个开关,非0时通过重打分来调整l.delta(预测值与真实值的差)
object_scale=5 栅格中有物体时,bbox的confidence loss对总loss计算贡献的权重
noobject_scale=1 栅格中没有物体时,bbox的confidence loss对总loss计算贡献的权重
class_scale=1 类别loss对总loss计算贡献的权重
coord_scale=1 bbox坐标预测loss对总loss计算贡献的权重
absolute=1
thresh = .6
random=0 random为1时会启用Multi-Scale Training,随机使用不同尺寸的图片进行训练。
总结
参考:
https://zhuanlan.zhihu.com/p/24720954#!
[DeepLearning]深度学习之五常见tricks | 听见下雨的声音
深度学习大牛 Bengio 的paper:《Dropout: A Simple Way to Prevent Neural Networks from Overfitting》
Yoshua Bengio 《Practical Recommendations for Gradient-Based Training of Deep Architectures》总结了很多tricks.
Efficient BackProp, by Yann LeCun, Léon Bottou, Genevieve Orr and Klaus-Robert Müller
Neural Networks: Tricks of the Trade, edited by Grégoire Montavon, Geneviève Orr, and Klaus-Robert Müller.