last time:
- activation function:sigmoid, tanh, relu, leacky relu, maxout, ELU
- weight initialization:Xavier初始化,MSRA初始化。初始化过小无法学习,过大梯度消失。
- data preprocessing:中心化,归一化。好处是让loss对参数值中的小扰动不那么敏感。
- batch normalization
- babysitting learning
- hyperparameter search
- grid search,random search, coarse to fine search(粗细粒交叉搜索)
通常学习率 > 正则化、学习率衰减、模型size。
卡在局部最优解的问题,在直观上是存在的但实际并不会。
SGD的问题:
1. very slow progress along shallow dimension, jitter along steep direction
2. 会卡在局部最小点和鞍点
3. stochastic
解决:SGD + Momentum
rho gives friction, and typically rho =0.9 or 0.99(也可以理解成最近梯度平均的平滑移动)
=> nesterov momentum, 据说在凸优化问题上效果不错。
momentum中的速度不是超参数,初始化设置为0即可。
sgd + momentum能够帮助度过sharp minima,如果遇到较宽泛的minima呢?老师说,一来这样的问题出现往往预示了过拟合,所以扩大数据集有用。二来甚至希望达到一个平缓的minima,这样能够更好地训练其泛化能力?
AdaGrad
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared += dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)
adagrad能够使x在变化率高的轴上减速,变化小的轴上加速,从而缓解jitter。
adagrad随着时间增加,步长会逐渐缩短,这在凸函数优化问题上有利于收敛,但其他问题则得不偿失。
=> RMSProp
grad_squared = 0
while True:
dx = compute_gradient(x)
grad_squared = decay_rate * grad_squared + (1 - decay_rate) * dx * dx
x -= learning_rate * dx / (np.sqrt(grad_squared) + 1e-7)
decay_rate通常取0.9之类。这样的好处是依然能够使训练在较快的方向渐缓,较慢的方向增快。并且不像adagrad那样容易被卡住。
Adam(full form)
因为效果优异,基本就是默认算法了。beta1 = 0.9, beta2 = 0.999, and learning_rate = 1e-3 or 5e-4是开始新模型时最常用的设定。
但这些算法都难以解决loss等高线如墨西哥卷形状不沿着坐标轴对齐,那么这些算法就是能够提供压缩但无法扭正。
learning rate decay over time!
带动向量的SGD很常用lr decay,但是Adam很少用。而且因为lr decay是二阶超参数,所以一开始最好不用,而是观察原来情况后再选择使用。
事实上,也有二阶优化的思路。一阶梯度带来的下降可能不如二阶函数拟合的到位
=> Newton parameter
这个算法甚至降低了对learning_rate的需要。但因为牛顿法中需要求矩阵的逆,往往不能计算,所以也有拟牛顿法,去低阶拟近hessian
L-BFGS是一个二阶逼近的求导器。二阶的思路虽好,但在深度学习中可能不太常用。
此前谈论的最优化问题只是针对train data,如果想提升泛化性能
=> Model Ensembles(虽然没有什么吊提升,但是每次提升程度都很稳)