【Datawhale X 李宏毅苹果书 AI夏令营】向李宏毅学深度学习(进阶) 笔记02

Task 2

学习 深度学习基础:线性模型自适应学习率(文字+视频)
学习 深度学习基础:分类(文字 + 视频)
跑通 实践任务CNN代码

Task 2.1 自适应学习率

自适应学习率(adaptive learning rate)

如下图所示,训练网络时,随着迭代次数增加,虽然损失(loss)不再下降,但是梯度的范数并没有变得很小,训练“卡住了”,但这种情况常常并不是卡在了上一节学习的临界点(局部最小值或者鞍点),只是单纯的损失无法再下降了。
训练网络迭代过程
因为在原始梯度下降中,所有的参数都是设置同样的学习率,但是训练误差表面是不均匀的,某些区域梯度变化非常小,非常平坦;某些区域坡度非常陡峭,梯度变化非常大,这就需要引入自适应学习率为每一个参数定制学习率,平坦坡度小的方向,我们设置大一点的学习率;陡峭坡度大的方向,我们设置较小的学习率,如下图所示。
不同参数需要不同的学习率
常见的自适应学习率方法有:

  • AdaGrad(Adaptive Gradient):根据梯度大小自动调整学习率,梯度比较大的时候,学习率就减小,梯度比较小的时候,学习率就放大。
  • RMSProp(Root Mean Squared propagation):考虑参数学习率随时间改变,引入一个超参数 α ∈ ( 0 , 1 ) \alpha \in (0, 1) α(0,1) 用于调整梯度更新时当前梯度的重要性:如果 α \alpha α 设很小趋近于 0,代表新算出来的梯度更重要;如果 α \alpha α 设很大趋近于 1,代表 之前算出来的梯度比较重要。
  • Adam(Adaptive moment estimation):理解为 RMSprop + 动量,其使用动量作为参数更新方向,并且能够自适应调整学习率,实践时直接使用Pytorch中预设即可。

注:RMSprop 是Geoffrey Hinton 在 Coursera 上深度学习的课程里面提出,如果要引用,需要引用对应视频:

[1] Tieleman, T., & Hinton, G. (2012). Lecture 6.5-rmsprop: Divide the gradient by a running average of its recent magnitude. COURSERA: Neural networks for machine learning, 4(2), 26-31.

学习率调节(learning rate scheduling)

在这里插入图片描述
如上图所示,自适应学习率应用后,另一个可能遇到的问题是:在训练优化到接近终点时,由于之前的梯度累计,步伐可能会变得很大,快走到终点时突然暴走了,这时就需要引入**学习率调度(learning rate scheduling)**来解决问题,最终实现下图的效果。
具体的方法有:

  • 学习率衰减(learning rate decay),也称为学习率退火(learning rateannealing):随着参数的不断更新,让学习率衰减,达到慢慢走到终点的效果。
  • 预热(warmup):让学习率先变大后变小,至于变到多大、变大的速度、变小的速度是超参数,即类似于不同的阶段手动设定相应的学习率。(RAdam 使用预热的方法来解决 Adam 容易收敛到局部最优解的问题,前期选用比较稳的SGD + Momentum来进行训练,来稳定缩小方差。)
    在这里插入图片描述

Task 2.2 分类

分类操作

深度学习两种常见问题:

  • 回归:输入一个向量 x x x,输出 y ^ \hat{y} y^,我们希望 y ^ \hat{y} y^ 跟某一个标签 y y y 越接近越好, y y y 是要学习的目标。
  • 分类:从回归理解,输入 x x x 后,输出 y ^ \hat{y} y^,我们希望它跟正确类别 y y y 越接近越好,这时候类别需要进行编码。

常用类别编码方式如独热编码(one-hot encoding):如果有三个类,标签 y y y 就是一个三维的向量,比如类 1 是 [ 1 , 0 , 0 ] ⊤ [1, 0, 0]\top [1,0,0],类 2 是 [ 0 , 1 , 0 ] ⊤ [0, 1, 0]\top [0,1,0],类3 是 [ 0 , 0 , 1 ] ⊤ [0, 0, 1]\top [0,0,1],用独热向量计算距离的话,类两两之间的距离都是一样的。

实际做分类时,在得到最终输出前会做一个softmax操作,简单理解: y y y 是独热向量,考虑到目标只有 0 跟 1,但 y ^ \hat{y} y^ 有任何值,可以先把它归一化到 0 到 1 之间,这样才能跟标签的计算相似度。

另外,一般有两个类时,可以直接取sigmoid,此时sigmoid和softmax是等价的。

分类损失

分类损失即我们计算 y ^ \hat{y} y^ y y y 的距离 e e e,常见计算方式:

  • 均方误差(mean square error, MSE):把 y y y 里每一个元素拿出来,计算它们的平方和当作误差:
    e = ∑ i ( y i − y ^ i ) 2 e = \sum_i(y_i - \hat{y}_i)^2 e=i(yiy^i)2
  • 交叉熵(cross entropy):当 y ^ \hat{y} y^ y y y 相同时,可以最小化交叉熵的值,此时均方误差也是最小的。最小化交叉熵其实就是最大化似然(maximize likelihood):
    e = − ∑ i y i ln ⁡ y ^ i e = - \sum_i y_i \ln \hat{y}_i e=iyilny^i

分类任务时,交叉熵更常用,有以下原因:

  • 交叉熵损失函数直接衡量了两个概率分布之间的差异,能够有效地反映预测分布与真实分布之间的差距。而平方误差衡量的主要是预测值与真实值的直接差异,但对于分类任务中的概率输出,平方误差并不能有效区分预测的好坏。
  • 同时交叉熵损失函数的梯度在接近正确分类时仍然较大,这意味着它可以在训练过程中对预测的微小调整更加敏感,帮助模型更快收敛。而平方误差损失在预测接近真实值时,其梯度会变得非常小,导致学习速度减慢。
  • 交叉熵损失函数对错误分类的惩罚更为严格,尤其是在模型非常自信地做出错误预测时,损失会变得非常大。而平方误差在这种情况下不会有如此强烈的反应,这可能导致模型在错误类别上持续做出不良预测。
  • 在分类任务中,softmax和sigmoid函数常用于输出层,这些函数与交叉熵损失函数在数学上是良好结合的。它们共同作用可以使得损失函数的优化更加有效。平方误差损失则不能很好地利用这些非线性激活函数的特性

因此,在分类任务中,交叉熵损失函数通常比平方误差损失函数表现得更好,能更有效地引导模型学习出准确的分类边界。

Task 2.3 实践任务:HW3(CNN)卷积神经网络-图像分类

直接本地3080Ti跑了下,教程很简单,跟着操作就行:

准备项目代码

git clone https://www.modelscope.cn/datasets/Datawhale/LeeDL-HW3-CNN.git

项目目录结构:

 .
├──  hw3_data.zip
├── HW3-ImageClassification.ipynb
└── README.md

代码调整

修改 transform:

train_tfm = transforms.Compose([
    # 将图像调整为固定大小(高度和宽度均为128)
    transforms.Resize((128, 128)),
    # 你可以在这里添加一些图像增强的操作。
    transforms.RandomHorizontalFlip(),
    transforms.RandomVerticalFlip(),
    # ToTensor()应该是所有变换中的最后一个。
    transforms.ToTensor(),
])

修改配置:

# 定义训练轮数
n_epochs = 50
# 如果在'patience'轮中没有改进,则提前停止
patience = 10

一键运行代码

分类准确率达到 70.84%
在这里插入图片描述
可视化效果:
在这里插入图片描述

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值