Datawhale X 李宏毅苹果书 AI夏令营(第五期-深度学习进阶) Task 2 学习笔记

3.3 自适应学习率

临界点其实不一定是在训练一个网络的时候会遇到的最大的障碍。

即梯度这个向量的长度。随着迭代次数增多,虽然损失不再下降,但是梯度的范数并没有真的变得很小。所以训练一个网络,训练到后来发现损失不再下降的时候,有时候不是卡

实际上在训练的时候,要走到鞍点或局部最小值,是一件困难的事情。一般的梯度下降,其实是做不到的。用一般的梯度下降训练,往往会在梯度还很大的时候,损失就已经降了下去,这个是需要特别方法训练的。

现在我们要从黑点(初始点)来做梯度下降,最低点在叉号处。该误差表面是凸的形状,凸的误差表面的等高线是椭圆形的,椭圆的长轴非常长,短轴相比之下比较短。

学习率决定了更新参数的时候的步伐,学习率设太大,步伐太大就无法慢慢地滑到山谷里面。

事实上在 BC 段有 10 万个点(10 万次更新),但都无法靠近局部最小值,所以显然就算是一个凸的误差表面,梯度下降也很难训练。

所以应该要为每一个参数定制化学习率,即引入自适应学习率(adaptive learning rate)的方法,给每一个参数不同的学习率。

3.3.1 AdaGrad(Adaptive Gradient)

#σ it -- i为上标,t为下标。

~是典型的自适应学习率方法,其能够根据梯度大小自动调整学习率。AdaGrad 可以做到梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。

σ it 的上标为 i,这代表参数 σ 与 i 相关,不同的参数的 σ 不同。σit 的下标为 t,这代表参数 σ 与迭代相关,不同的迭代也会有不同的 σ。学习率从 η 改成 η / σit 的时候,学习率就变得参数相关(parameter dependent)。        

因为 θ1 坡度小,根据式 (3.22),θ i1 这个参数上面算出来的梯度值都比较小,因为梯度算出来的值比较小,所以算出来的 σ it 就小,σ it 小学习率就大。反过来,θ1 坡度大,所以计算出的梯度都比较大,σ it 就比较大,

3.3.2 RMSProp

同一个参数的同个方向,学习率也是需要动态调整的,于是就有了一个新的方法———RMSprop(Root Mean Squared propagation)

其中 0 < α < 1,其是一个可以调整的超参数。在算均方根的时候,每一个梯度都有同等的重要性,但在 RMSprop 里面,可以自己调整现在的这个梯度的重要性:

如果 α 设很小趋近于 0,代表 g i1 相较于之前算出来的梯度而言,比较重要;如果 α 设很大趋近于 1,代表 g i1 比较不重要,之前算出来的梯度比较重要。

RMSProp 通过 α 可以决定,g it 相较于之前存在 σ i t−1 里面的 g i1, g i2, · · · · · · , g i t−1 的重要性有多大。        使用 RMSprop可以动态调整 σ it 这一项。

3.3.3 Adam

最常用的优化的策略或者优化器(optimizer)Adam(Adaptive moment estimation)[7]。Adam 可以看作 RMSprop 加上动量,其使用动量作为参数更新方向,并且能够自适应调整学习率。PyTorch 里面已经写好了 Adam 优化器,这个优化器里面有一些超参数需要人为决定,但是往往用 PyTorch 预设的参数就足够好了。

3.4 学习率调度

问题在于走到图 3.27中红圈的地方,快走到终点的时候突然“爆炸”了。σ it 是把过去所有的梯度拿来作平均。在 AB段梯度很大,但在 BC 段,纵轴的方向梯度很小,因此纵轴方向累积了很小的

σ it,累积到一定程度以后,步伐就变很大,但有办法修正回来。因为步伐很大,其会走到梯度比较大的地方。走到梯度比较大的地方后,σ it 会慢慢变大,更新的步伐大小会慢慢变小,从而回到原来的路线。

通过学习率调度(learning rate scheduling)可以解决这个问题。之前的学习率调整方法中 η 是一个固定的值,而在学习率调度中 η 跟时间有关,如式 (3.26) 所示。

学习率调度中最常见的策略是学习率衰减(learning rate decay),也称为学习率退火(learning rateannealing)。随着参数的不断更新,让 η 越来越小,如图 3.28 所示。图 3.22b 的情况,如果加上学习率下降,可以很平顺地走到终点,如图 3.29 所示。在图 3.22b 红圈的地方,虽然步伐很大,但 η 变得非常小,步伐乘上 η 就变小了,就可以慢慢地走到终点。

有另外一个经典的学习率调度的方式———预热:让学习率先变大后变小,至于变到多大、变大的速度、变小的速度是超参数

e.g.残差网络[8] 里面是有预热的,在残差网络里面,学习率先设置成 0.01,再设置成 0.1,并且其论文还特别说明,一开始用 0.1 反而训练不好。除了残差网络,BERT 和 Transformer 的训练也都使用了预热。

Q:为什么需要预热?

A:当我们使用 Adam、RMSprop 或 AdaGrad 时,需要计算 σ。而 σ 是一个统计的结果。从 σ 可知某一个方向的陡峭程度。统计的结果需要足够多的数据才精准,一开始统计结果 σ 是不精准的。一开始学习率比较小是用来探索收集一些有关误差表面的情报,先收集有关 σ 的统计数据,等 σ 统计得比较精准以后,再让学习率慢慢爬升。如果读者想要学更多有关预热的东西可参考 Adam 的进阶版———RAdam[9]。                     ————《深度学习详解》

3.5 优化总结

这个版本里面有动量,其不是顺着某个时刻算出的梯度方向来更新参数,而是把过去所有算出梯度的方向做一个加权总和当作更新的方向。接下来的步伐大小为 m it / σ it。最后通过 ηt 来实现学习率调度。这个是目前优化的完整的版本,这种优化器除了 Adam 以外,还有各种变形。但其实各种变形是使用不同的方式来计算 m it 或 σ it,或者是使用不同的学习率调度的方式。

Q:动量 m it 考虑了过去所有的梯度,均方根 σ it 考虑了过去所有的梯度,一个放在分子,一个放在分母,并且它们都考虑过去所有的梯度,不就是正好抵消了吗?

A:m it 和 σ it 在使用过去所有梯度的方式是不一样的,动量是直接把所有的梯度都加起来,所以它有考虑方向,它有考虑梯度的正负。但是均方根不考虑梯度的方向,只考虑梯度的大小,计算 σ it 的时候,都要把梯度取一个平方项,把平方的结果加起来,所以只考虑梯度的大小,不考虑它的方向,所以动量跟 σit 计算出来的结果并不会互相抵消。

                                                                                                       ————《深度学习详解》

3.6 分类

分类与回归是深度学习最常见的两种问题,第一章的观看次数预测属于回归问题,本节将介绍分类问题。

3.6.1 分类与回归的关系

分类可当作回归来看,输入 x 后,输出仍然是一个标量 yˆ,要让它跟正确答案的那个类越接近越好。yˆ 是一个数字,我们可以把类也变成数字。

但该方法在某些状况下会有问题,假设类 1、2、3 有某种关系。用数字来表示类会预设 1 和 2 有比较近的关系,1 和 3 有比较远的关系 ;  但假设三个类本身没有特定的关系,这种情况,需要引入独热向量来表示类。实际上,在做分类的问题的时候,比较常见的做法也是用独热向量表示类。

e.g.

1、如果有三个类,标签 y 就是一个三维的向量,比如类 1 是 [1, 0, 0]T,类 2 是 [0, 1, 0]T,类3 是 [0, 0, 1]T。如果每个类都用一个独热向量来表示,就没有类 1 跟类 2 比较接近,类 1 跟类 3 比较远的问题。如果用独热向量计算距离的话,类两两之间的距离都是一样的。

2、如果目标 y 是一个向量,比如 y 是有三个元素的向量,网络也要输出三个数字才行。如图 3.31 所示,输出三个数值就是把本来输出一个数值的方法,重复三次。把 a1、a2 和 a3 乘上三个不同的权重,加上偏置,得到 yˆ1;再把 a1、a2 和 a3 乘上另外三个权重,再加上另外一个偏置得到 yˆ2;把 a1、a2 和 a3 再乘上另外一组权重,再加上另外一个偏置得到 yˆ3。输入一个特征向量,产生 yˆ1、yˆ2、yˆ3,希望 yˆ1、yˆ2、yˆ3 跟目标越接近越好。

3.6.2 带有 softmax 的分类

激活函数-- 相关简介词条

Q:为什么分类过程中要加上 softmax 函数?

A:一个比较简单的解释是,y 是独热向量,所以其里面的值只有 0 跟 1,但是 yˆ 里面有任何值。既然目标只有 0 跟 1,但 yˆ 有任何值,可以先把它归一化到 0 到 1 之间,这样才能计算跟标签的相似度。

图 3.33 考虑了三个类的状况,两个类也可以直接套 softmax 函数。但一般有两个类的时候,我们不套 softmax,而是直接取 sigmoid。当只有两个类的时候,sigmoid 和 softmax 是等价的。

3.6.3 分类损失

相较于均方误差,交叉熵更常用于分类上。

图 3.36 是分别在 e 为均方误差和交叉熵时,y1、y2 的变化对损失的影响,对误差表面的影响,红色代表损失大,蓝色代表损失小。如果 y1 很大,y2 很小,代表 y′1 会很接近 1,y′2会很接近 0。所以不管 e 取均方误差或交叉熵,如果 y1 大、y2 小,损失都是小的;如果 y1小,y2 大,y′1 是 0,y′2 是 1,这个时候损失会比较大。

均方误差在这种损失很大的地方,它是非常平坦的,其梯度是非常小趋近于 0 的。如果初始时在圆圈的位置,离目标非常远,其梯度又很小,无法用梯度下降顺利地“走”到右下角。

因此做分类时,选均方误差的时候,如果没有好的优化器,有非常大的可能性会训练不起来。如果用 Adam,虽然图 3.36(b) 中圆圈的梯度很小,但 Adam 会自动调大学习率,还有机会走到右下角,不过训练的过程比较困难。总之,改变损失函数可以改变优化的难度。

3.7 批量归一化

如果误差表面很崎岖,它比较难训练。能不能直接改误差表面的地貌,“把山铲平”,让它变得比较好训练呢?批量归一化(Batch Normalization,BN)就是其中一个“把山铲平”的....

(PDF暂时到此为止了,dbq,若有需要请看下一篇)

HW3  (CNN)代码实践

代码详解 卷积神经网络是深度学习中的一个非常重要的分支,本作业提供了进行图像分类任务的基本范式。

准备数据- 训练模型- 应用模型

要完成一个深度神经网络训练模型的代码,大概需要完成下面的内容:

1. 导入所需要的库/工具包

2. 数据准备与预处理

3. 定义模型

4. 定义损失函数和优化器等其他配置

5. 训练模型

6. 评估模型

7. 进行预测

此范式不仅适用于图像分类任务,对于广泛的深度学习任务也是适用的。

2. 数据准备与预处理

作业中对图像的预处理操作包括调整大小和将图像转换为Tensor格式。为了增强模型的鲁棒性,可以对训练集进行数据增强。

关于数据增强,我想到的是图像增强  /  图像增广    。后者在Up主【跟李沐学AI】动手学深度学习系列视频中有涉及:

# 图像增广
transform_train = torchvision.transforms.Compose([
    torchvision.transforms.Resize(40),
    torchvision.transforms.RandomResizedCrop(32,scale=(0.64,1.0),ratio=(1.0,1.0)),
    torchvision.transforms.RandomHorizontalFlip(),
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize([0.4914,0.4822,0.4465],
                                   [0.2023,0.1994,0.2010]) ])

transform_test = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor(),
    torchvision.transforms.Normalize([0.4914,0.4822,0.4465],
                                    [0.2023,0.1994,0.2010]) ])

说是一串经常被用于图像增广的参数,图像增广的简单定义就是:

图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模。图像增广的另一种解释是,随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。————引用链接中的作者的话,侵删。

3.定义模型

这段代码定义了一个图像分类器(Classifier),继承自PyTorch的nn.Module。该分类器通过一系列卷积层、批归一化层、激活函数和池化层构建卷积神经网络(CNN),用于提取图像特征。随后,这些特征被输入到全连接层进行分类,最终输出11个类别的概率,用于图像分类任务。

卷积层详见《深度学习详解》第四章 卷积神经网络,简单来说就是“感受野加上参数共享就是卷积层(convolutional layer)”;批量归一化层,可见下一篇具体介绍Batch normalization;池化层详见链接。后面这一句涉及独热向量,常用于(图像)分类任务。

4. 定义损失函数和优化器等其他配置

这段代码实现了图像分类模型的初始化和训练配置,目的是准备好训练环境和参数。它选择合适的设备(GPU或CPU),设置模型、批量大小、训练轮数、提前停止策略,定义了损失函数和优化器,为后续的模型训练奠定了基础。

# 初始化优化器,您可以自行调整一些超参数,如学习率
optimizer = torch.optim.Adam(model.parameters(), lr=0.0003, weight_decay=1e-5)

优化器基本上涵盖了一些必要的超参数。

5. 训练模型

这段代码实现了一个图像分类模型的训练和验证循环,目的是通过多轮训练(epochs)逐步优化模型的参数,以提高其在验证集上的性能,并保存效果最好的模型。训练阶段通过前向传播、计算损失、反向传播和参数更新来优化模型,验证阶段评估模型在未见过的数据上的表现。如果验证集的准确率超过了之前的最好成绩,保存当前模型,并在连续多轮验证性能未提升时提前停止训练。

‘'前向传播(forward)简单理解就是将上一层的输出作为下一层的输入,并计算下一层的输出,一直到运算到输出层为止;   反向传播(backward)实际上,反向传播仅指用于计算梯度的方法。而另一种算法,例如随机梯度下降法,才是使用该梯度来进行学习。原则上反向传播可以计算任何函数的导数。"

(优化 建议学完 Task 3 再来看 https://linklearner.com/activity/16/15/61)

本文图文基本摘抄自————《深度学习详解》,非营利仅供学习参考,侵删。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值