3.3 自适应学习率
-
实际训练中会发生在鞍点或局部最小值附近的“震荡”,很难顺利地走到这一点上。用一般的梯度下降来训练,往往梯度还很大时,损失就已经降下去了,这意味着训练过程不稳定,需要更精细地调整参数,从而确保稳定收敛。所以引入自适应学习率(adaptive learning rate),为每一个参数定制学习率,而不是所有参数用同样的学习率。
- 如果在某一个方向上,梯度的值很小,非常平坦,把学习率调大一点;
- 如果在某一个方向上非常陡峭,坡度很大,把学习率调小一点。
-
让学习率变得参数相关,即从 η \eta η 变为 η σ i i \frac{\eta}{\sigma_i^i} σiiη,其中 σ \sigma σ 与 i i i 相关,从而实现“自适应”
- AdaGrad(Adaptive Gradient)
- 使用梯度的均方根作为参数相关的方法
- σ 0 i = ( g 0 i ) 2 = ∣ g 0 i ∣ {\sigma }^{i}_{0}=\sqrt {{({g}^{i}_{0})}^{2}}=\left | {{g}^{i}_{0}} \right | σ0i=(g0i)2= g0i , σ t i = 1 t + 1 ∑ i = 0 t ( g t i ) 2 {\sigma }^{i}_{t}=\sqrt {\frac {1} {t+1}\sum ^{t}_{i=0} {{({g}^{i}_{t})}^{2}}} σti=t+11∑i=0t(gti)2
- RMSprop(Root Mean Squared propagation)
- σ 0 i = ∣ g 0 i ∣ {\sigma }^{i}_{0}=\left | {{g}^{i}_{0}} \right | σ0i= g0i , σ t i = α ( σ t − 1 i ) 2 + ( 1 − α ) ( g t i ) 2 {\sigma }^{i}_{t}=\sqrt {{\alpha {({\sigma }^{i}_{t-1})}^{2}+}{{(1-\alpha )({g}^{i}_{t})}^{2}}} σti=α(σt−1i)2+(1−α)(gti)2
- 相较于AdaGrad,RMSprop使用超参数 α \alpha α 调整梯度的重要性,反应更快。 α \alpha α 越小代表当前的 g 0 i g^i_0 g0i 越重要,实现对 σ i i \sigma_i^i σii 的动态调整。
- Adam(Adaptive moment estimation)
- 可以看作动量加上 RMSprop ,既使得梯度更新更加平滑,避免震荡,加速收敛,又自适应地调整学习率,防止学习率过大导致的训练不稳定。
- 使用梯度的一阶动量(平均值) m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t mt=β1⋅mt−1+(1−β1)⋅gt 和二阶动量(平方的指数加权平均) v t = β 2 ⋅ v t − 1 + ( 1 − β 2 ) ⋅ g t 2 v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 vt=β2⋅vt−1+(1−β2)⋅gt2,其中, β 1 \beta_1 β1 是控制动量的衰减率的超参数,通常取值为 0.9, β 2 \beta_2 β2 是控制二阶动量衰减率的超参数,通常取值为 0.999。
- AdaGrad(Adaptive Gradient)
3.4 学习率调度
- 自适应学习率存在“爆炸”的情况,即步伐过大,可以通过学习率调度(learning rate scheduling)解决。
- 常见方法
- 学习率衰减(learning rate decay),也称为学习率退火(learning rateannealing),让 η \eta η 随着参数更新越来越小
- 预热,让学习率先变大后变小,用超参数控制变大的程度、变大的速度、变小的速度。可参考Adam进阶版RAdam。
3.5 优化总结
- 经过前面的优化,梯度更新的公式优化为 θ t + 1 i ← θ t i − η t σ t i m t i {\theta }^{i}_{t+1}\gets {\theta }^{i}_{t}-\frac {{\eta }_{t}} {{\sigma }^{i}_{t}}{m}^{i}_{t} θt+1i←θti−σtiηtmti
- 这个优化器把过去所有算出梯度的方向做一个加权总和当作更新的方向,其中 m t i m^i_t mti 直接把所有的梯度都加起来,考虑了方向,均方根不考虑梯度的方向,只考虑梯度的大小。
- 它的各种变形是使用不同的方式来计算 m t i m^i_t mti 或 σ t i \sigma^i_t σti,或者是使用不同的学习率调度的方式。
3.6 分类
- 分类类似回归,输入一个
x
x
x 值,希望输出的
y
y
y 值跟正确答案越近越好。
- y y y 的值代表分类,如果用数字表示,会预设值相近的类有更近的关系,所以用独热向量来表示类,避免这种预设。
- 分类计算得到的向量值是任意的,而目标只有 0 0 0 和 1 1 1 ,所以要使用 s o f t m a x softmax softmax 函数把它归化到 [ 0 , 1 ] [0,1] [0,1],以便和标签计算相似度。归化后大值跟小值的差距会变得更大。
- 分类损失的计算常用交叉熵,因为它的优化难度低于均方误差。如下图所示,如果初始点离目标很远,损失又很大:
- 使用均方误差时,所在点周围非常平坦,梯度趋近于0,用梯度下降很难走到右下角。
- 使用交叉熵时,所在点有斜率,可以通过梯度一直往右下走。
HW3 CNN图像分类
-
实验使用包含卷积层和全连接层的分类器对图像进行分类。
-
设置了第三章里介绍的各种优化参数:
# 根据GPU是否可用选择设备类型 device = "cuda" if torch.cuda.is_available() else "cpu" # 初始化模型,并将其放置在指定的设备上 model = Classifier().to(device) # 定义批量大小 batch_size = 64 # 定义训练轮数 n_epochs = 8 # 如果在'patience'轮中没有改进,则提前停止 patience = 5 # 对于分类任务,我们使用交叉熵作为性能衡量标准 criterion = nn.CrossEntropyLoss() # 初始化优化器,您可以自行调整一些超参数,如学习率 optimizer = torch.optim.Adam(model.parameters(), lr=0.0003, weight_decay=1e-5)
-
代码里提到可做图像增强(Data Augmentation)
- 它指的是对训练数据进行转换、修改或扩展来生成更多样本,以便于在不增加实际数据的情况下,扩充训练集规模,来达到提高模型的泛化能力、减少过拟合、模拟现实世界中的图像变化来增强模型的鲁棒性的目的。
- 常见操作包括随机裁剪(transforms.RandomCrop),随机水平翻转(transforms.RandomHorizontalFlip),颜色抖动(transforms.ColorJitter),旋转(transforms.RandomRotation)
-
实验最后使用t-SNE(t-Distributed Stochastic Neighbor Embedding)降维技术可视化第19层的输出,让实验结果更直观。
-
t-SNE将高维数据映射到二维,同时保持数据点之间的局部邻近关系。
-
所有类别的 t-SNE 可视化:不同类别的数据点没有相互分离,说明模型的第19层特征不具有较好的区分性,不能有效地分离不同类别的样本。
-
特定类别(Class 5)的 t-SNE 可视化:样本散布较广,表明模型在Class 5上的区分性较弱
-