概述:DL调参
[TOC]
1.参数初始化(加快收敛速度)
1.1 uniform均匀分布初始化
1 | w = np.random.uniform(low=-scale, high=scale, size=[n_in,n_out]) |
Xavier Glorot初始化
1 | 适用于普通激活函数(tanh,sigmoid):scale = np.sqrt(3/n) |
Kaiming He初始化
1 | 适用于ReLU:scale = np.sqrt(6/n) |
1.2 normal高斯分布初始化:
1 | w = np.random.randn(n_in,n_out) * stdev # stdev为高斯分布的标准差,均值设为0 |
Xavier Glorot初始化
1 | 适用于普通激活函数 (tanh,sigmoid):stdev = np.sqrt(n) |
Kaiming He初始化
1 | 适用于ReLU:stdev = np.sqrt(2/n) |
参考文献:
Xavier Glorot: http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf
Kaiming He:https://arxiv.org/abs/1502.01852
Andrew M. Saxe(适用于RNN):https://arxiv.org/abs/1312.6120
2.数据预处理
2.1 去中心化
1 | X -= np.mean(X, axis = 0) # zero-center |
2.2 归一化
1 | X /= np.std(X, axis = 0) # normalize(最值归一化、标准归一化) |
3.训练技巧
3.1 梯度裁剪:限制最大梯度
value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15,不然容易导致训练一段时间以后 loss 突然变成 Nan
3.2 Dropout:防止过拟合
一般设为0.5,小数据使用dropout+sgd效果提升明显,dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置
RNN如何用dropout参考文献:https://arxiv.org/abs/1409.2329
3.3 优化器
sgd适用于小数据集,收敛速度慢而效果较好,建议从1.0或者0.1的学习率开始,若验证集cost没有下降则减半学习率;
adadelta一般在分类问题上效果比较好;
adam在生成问题上效果比较好;
3.4 RNN的神经元数量和batchSize
建议均从128开始上下调整
3.5 LSTM的遗忘门的偏置用1.0或更大值初始化
参考文献:http://proceedings.mlr.press/v37/jozefowicz15.pdf
4.推荐路线
(1)ReLu+BatchNormalization
(2)DropOut一般在softmax前使用即可,提升效果不大
(3)降低学习率
(4)tensorboard监控网络状态,调整网络参数
(5)随时存档,保存参数,分析过拟合时间点
(6)在不降低网络性能下尽可能减少层数
(7)输入去中心化与BN效果等同
(8)学习率一般要随着训练进行衰减。衰减系数设0.1,0.3,0.5均可
(9)Datashuffle
(10)L1/L2正则化
(11)Ensemble
5.自动调参方法:
5.1 Grid Search:网格搜索
在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果。其原理就像是在数组里找最大值。缺点是太费时间了,特别像神经网络,一般尝试不了太多的参数组合。
5.2 Random Search
经验上,Random Search比Gird Search更有效。实际操作的时候,一般也是先用Gird Search的方法,得到所有候选参数,然后每次从中随机选择进行训练。另外Random Search往往会和由粗到细的调参策略结合使用,即在效果比较好的参数附近进行更加精细的搜索。
5.3 Bayesian Optimization:贝叶斯优化
考虑到了不同参数对应的 实验结果值,因此更节省时间,贝叶斯调参比Grid Search迭代次数少, 速度快;而且其针对非凸问题依然稳健。
6.罗列网络部分可选性
6.1 激活函数Activation
中间层的激活函数一般选择 relu 函数
二分类问题时,最后一层一般采用 sigmoid 激活函数
多分类问题时,最后一层一般采用 softmax 函数
常见的激活函数:
softmax;elu;selu;softplus;softsign;relu;tanh;sigmoid;hard_sigmoid;linear
6.2优化器Optimizer
Adam:结合RMSProp与动量 momentum
- lr: float >= 0. 学习率。
- beta_1: float, 0 < beta < 1. 通常接近于 1。
- beta_2: float, 0 < beta < 1. 通常接近于 1。
- epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
- decay: float >= 0. 每次参数更新后学习率衰减值。
- amsgrad: boolean. 是否应用此算法的 AMSGrad 变种,来自论文 “On the Convergence of Adam and Beyond”。
Adadelta:不是累积所有过去的梯度,而是根据渐变更新的移动窗口调整学习速率
- lr: float >= 0. 学习率,建议保留默认值。
- rho: float >= 0. Adadelta梯度平方移动均值的衰减率。
- epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
- decay: float >= 0. 每次参数更新后学习率衰减值。
Adagrad:采取了累积平方梯度
- lr: float >= 0. 学习率.
- epsilon: float >= 0. 若为 None, 默认为 K.epsilon().
- decay: float >= 0. 每次参数更新后学习率衰减值.
RMSprop:适合于RNN时序
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)
- lr: float >= 0. 学习率。
- rho: float >= 0. RMSProp梯度平方的移动均值的衰减率.
- epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
- decay: float >= 0. 每次参数更新后学习率衰减值。
SGD:随机梯度下降优化器
- lr: float >= 0. 学习率。
- momentum: float >= 0. 参数,用于加速 SGD 在相关方向上前进,并抑制震荡。
- decay: float >= 0. 每次参数更新后学习率衰减值。
- nesterov: boolean. 是否使用 Nesterov 动量。
Admax:基于无穷范数(infinity norm)的变种
- lr: float >= 0. 学习率。
- beta_1/beta_2: floats, 0 < beta < 1. 通常接近于 1。
- epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
- decay: float >= 0. 每次参数更新后学习率衰减值。
Nadam:采用 Nesterov momentum 版本的 Adam 优化器
- lr: float >= 0. 学习率。
- beta_1/beta_2: floats, 0 < beta < 1. 通常接近于 1。
- epsilon: float >= 0. 模糊因子. 若为 None, 默认为 K.epsilon()。
6.3 损失函数/代价函数Loss
mean_squared_error(mse):均方误差
mean_absolute_error(mae):平均绝对误差
mean_absolute_percentage_error(mape):平均绝对百分误差
mean_squared_logarithmic_error(msle):平均对数平方误差
squared_hinge:平方铰链误差,主要用于SVM
hinge:铰链误差,主要用于SVM
binary_crossentropy:对数损失函数/二分类交叉熵(二分类问题)
logcosh:预测误差的双曲余弦函数的对数
categorical_crossentropy:多类的对数损失/多分类交叉熵(多分类问题)
sparse_categorical_crossentrop:接受稀疏标签的多类对数损失
kullback_leibler_divergence:相对熵,KL散度
poisson:(predictions - targets * log(predictions))的均值
cosine_proximity:预测误差的余弦距离平均值的相反数