[深度学习实战]基于PyTorch的深度学习实战(上)[变量、求导、损失函数、优化器](二)

简介: 笔记

五、损失函数


  损失函数,又叫目标函数,是编译一个神经网络模型必须的两个参数之一。另一个必不可少的参数是优化器。

  损失函数是指用于计算标签值和预测值之间差异的函数,在机器学习过程中,有多种损失函数可供选择,典型的有距离向量,绝对值向量等

14.png

上图是一个用来模拟线性方程自动学习的示意图。粗线是真实的线性方程,虚线是迭代过程的示意,w1 是第一次迭代的权重,w2 是第二次迭代的权重,w3 是第三次迭代的权重。随着迭代次数的增加,我们的目标是使得 wn 无限接近真实值。

 那么怎么让 w 无限接近真实值呢?其实这就是损失函数和优化器的作用了。图中 1/2/3 这三个标签分别是 3 次迭代过程中预测 Y 值和真实 Y 值之间的差值(这里差值就是损失函数的意思了,当然了,实际应用中存在多种差值计算的公式),这里的差值示意图上是用绝对差来表示的,那么在多维空间时还有平方差,均方差等多种不同的距离计算公式,也就是损失函数了。

 这里示意的是一维度方程的情况,扩展到多维度,就是深度学习的本质了。

 下面介绍几种常见的损失函数的计算方法,pytorch 中定义了很多类型的预定义损失函数,需要用到的时候再学习其公式也不迟。

 我们先定义两个二维数组,然后用不同的损失函数计算其损失值。

15.png

import torch
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
sample = Variable(torch.ones(2,2))
a=torch.Tensor(2,2)
a[0,0]=0
a[0,1]=1
a[1,0]=2
a[1,1]=3
target = Variable (a)

sample 的值为:[[1,1],[1,1]]。

  target 的值为:[[0,1],[2,3]]。

5.1 nn.L1Loss

16.png

L1Loss 计算方法很简单,取预测值和真实值的绝对误差的平均数即可

criterion = nn.L1Loss()
loss = criterion(sample, target)
print(loss)

17.png

最后的结果为1,计算步骤为:

 先计算绝对差总和:|0-1|+|1-1|+|2-1|+|3-1|=4;

 然后再平均:4/4=1。


5.2 nn.SmoothL1Loss

 SmoothL1Loss 也叫作 Huber Loss,误差在 (-1,1) 上是平方损失,其他情况是 L1 损失。

18.png

criterion = nn.SmoothL1Loss()
loss = criterion(sample, target)
print(loss)

19.png

最后结果是:0.625。

5.3 nn.MSELoss

  平方损失函数。其计算公式是预测值和真实值之间的平方和的平均数

20.png

criterion = nn.MSELoss()
loss = criterion(sample, target)
print(loss)

21.png

 最后结果是:1.5。

5.4 nn.BCELoss

  二分类用的交叉熵,其计算公式较复杂,这里主要是有个概念即可,一般情况下不会用到。

22.png

 最后结果是:-50。

23.png

5.5 nn.CrossEntropyLoss

  交叉熵损失函数

24.png

该公式用的也较多,比如在图像分类神经网络模型中就常常用到该公式

criterion = nn.CrossEntropyLoss()
loss = criterion(sample, target)
print(loss)

25.png

最后结果是:2.0794。

 看文档我们知道 nn.CrossEntropyLoss 损失函数是用于图像识别验证的,对输入参数有各式要求,这里有这个概念就可以了,在后续的图像识别方向中会有正确的使用方法。


5.6 nn.NLLLoss

 负对数似然损失函数(Negative Log Likelihood)

26.png


在前面接上一个 LogSoftMax 层就等价于交叉熵损失了。注意这里的xlabel 和上个交叉熵损失里的不一样,这里是经过 log 运算后的数值。

 这个损失函数一般也是用在图像识别模型上。

criterion = F.nll_loss()
loss = criterion(sample, target)
print(loss)
loss=F.nll_loss(sample,target)

最后结果为报错,看来不能直接调用。

 Nn.NLLLoss 和 nn.CrossEntropyLoss 的功能是非常相似的。通常都是用在多分类模型中,实际应用中我们一般用 NLLLoss 比较多。

27.png

5.7 nn.NLLLoss2d

  和上面类似,但是多了几个维度,一般用在图片上。

input, (N, C, H, W)
target, (N, H, W)

  比如用全卷积网络做分类时,最后图片的每个点都会预测一个类别标签

28.png

最后结果报错,看来不能直接这么用。


六、优化器Optim


 优化器用通俗的话来说就是一种算法,是一种计算导数的算法。

 各种优化器的目的和发明它们的初衷其实就是能让用户选择一种适合自己场景的优化器。

 优化器的最主要的衡量指标就是优化曲线的平稳度,最好的优化器就是每一轮样本数据的优化都让权重参数匀速的接近目标值,而不是忽上忽下跳跃的变化。因此损失值的平稳下降对于一个深度学习模型来说是一个非常重要的衡量指标。

 pytorch 的优化器都放在 torch.optim 包中。常见的优化器有:SGD,Adam,Adadelta,Adagrad,Adamax 等。如果需要定制特殊的优化器,pytorch 也提供了定制化的手段,不过这里我们就不去深究了,毕竟预留的优化器的功能已经足够强大了。


 6.1 SGD

 SGD 指stochastic gradient descent,即随机梯度下降,随机的意思是随机选取部分数据集参与计算,是梯度下降的 batch 版本。SGD 支持动量参数,支持学习衰减率。SGD 优化器也是最常见的一种优化器,实现简单,容易理解。


 6.1.1 用法

optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)


 6.1.2 参数

 lr:大于 0 的浮点数,学习率。

 momentum:大于 0 的浮点数,动量参数。

 parameters:Variable 参数,要优化的对象。


 对于训练数据集,我们首先将其分成 n 个 batch,每个 batch 包含 m 个样本。我们每次更新都利用一个 batch 的数据 ,而非整个训练集,即:


 xt+1=xt+Δxt

 Δxt=-ηgt


 其中,η 为学习率,gt 为 x 在 t 时刻的梯度。


 6.1.3 好处

 这么做的好处在于:

 (1)当训练数据太多时,利用整个数据集更新往往时间上不现实。batch的方法可以减少机器的压力,并且可以更快地收敛。

 (2)当训练集有很多冗余时(类似的样本出现多次),batch 方法收敛更快。以一个极端情况为例,若训练集前一半和后一半梯度相同,那么如果前一半作为一个 batch,后一半作为另一个 batch,那么在一次遍历训练集时,batch 的方法向最优解前进两个 step,而整体的方法只前进一个 step。


6.2 RMSprop

 RMSProp 通过引入一个衰减系数,让 r 每回合都衰减一定比例,类似于Momentum 中的做法,该优化器通常是面对递归神经网络时的一个良好选择。


 6.2.1 具体实现

 需要:全局学习速率 ϵ,初始参数 θ,数值稳定量 δ,衰减速率 ρ。

 中间变量:梯度累计量 r(初始化为 0)。


 6.2.2 每步迭代过程

 (1)从训练集中的随机抽取一批容量为 m 的样本 {x1,…,xm} 以及相关的输出 yi 。

 (2)计算梯度和误差,更新 r,再根据 r 和梯度计算参数更新量 。


29.png

6.2.3 用法

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)


 6.2.4 参数

 lr:大于 0 的浮点数,学习率。

 rho:大于 0 的浮点数。

 epsilon:大于 0 的小浮点数,防止除 0 错误。


6.3 Adagrad

 AdaGrad 可以自动变更学习速率,只是需要设定一个全局的学习速率 ϵ,但是这并非是实际学习速率,实际的速率是与以往参数的模之和的开方成反比的。也许说起来有点绕口,不过用公式来表示就直白的多:

30.png

其中 δ 是一个很小的常量,大概在 10-7,防止出现除以 0 的情况.。


 6.3.1 具体实现

 需要:全局学习速率 ϵ,初始参数 θ,数值稳定量 δ 。

 中间变量:梯度累计量 r(初始化为 0) 。


 6.3.2 每步迭代过程

 (1) 从训练集中的随机抽取一批容量为 m 的样本 {x1,…,xm} 以及相关。

 (2)计算梯度和误差,更新r,再根据 r 和梯度计算参数更新量 。

31.png

6.3.3 优点

 能够实现学习率的自动更改。如果这次梯度大,那么学习速率衰减的就快一些;如果这次梯度小,那么学习速率衰减的就慢一些。


 6.3.4 缺点

 仍然要设置一个变量 ϵ 。

 经验表明,在普通算法中也许效果不错,但在深度学习中,深度过深时会造成训练提前结束。


 6.3.5 用法

keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)


 6.3.6 参数

 lr:大于 0 的浮点数,学习率。

 epsilon:大于 0 的小浮点数,防止除 0 错误。


6.4 Adadelta

 Adagrad 算法存在三个问题:

 (1)其学习率是单调递减的,训练后期学习率非常小。

 (2)其需要手工设置一个全局的初始学习率。

 (3)更新 xt 时,左右两边的单位不统一。

 Adadelta 针对上述三个问题提出了比较漂亮的解决方案。

 首先,针对第一个问题,我们可以只使用 adagrad 的分母中的累计项离当前时间点比较近的项,如下式:


32.png

这里ρ 是衰减系数 ,通过这个衰减系数,我们令每一个时刻的 gt 随时间按照 ρ 指数衰减,这样就相当于我们仅使用离当前时刻比较近的gt信息,从而使得还很长时间之后,参数仍然可以得到更新。

 针对第三个问题,其实 sgd 跟 momentum 系列的方法也有单位不统一的问题。sgd、momentum 系列方法中:

33.png

 类似的,adagrad 中,用于更新 Δx 的单位也不是 x 的单位,而是 1

  而对于牛顿迭代法

34.png

 其中 H 为 Hessian 矩阵,由于其计算量巨大,因而实际中不常使用。其单位为:

35.png

注意,这里f 无单位 。因而,牛顿迭代法的单位是正确的

  所以,我们可以模拟牛顿迭代法来得到正确的单位。注意到:

36.png

这里,在解决学习率单调递减的问题的方案中,分母已经是 ∂f/∂x 的一个近似了。这里我们可以构造 Δx 的近似,来模拟得到 H-1 的近似从而得到近似的牛顿迭代法。具体做法如下:

37.png

可以看到,如此一来adagrad 中分子部分需要人工设置的初始学习率也消失了 ,从而顺带解决了上述的第二个问题。


 6.4.1 用法

keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)


建议保持优化器的默认参数不变。


 6.4.2 参数

 lr:大于 0 的浮点数,学习率。

 rho:大于 0 的浮点数。

 epsilon:大于 0 的小浮点数,防止除 0 错误。


6.5 Adam

 Adam 是一种基于一阶梯度来优化随机目标函数的算法。

 Adam 这个名字来源于 adaptive moment estimation,自适应矩估计。概率论中矩的含义是:如果一个随机变量 X 服从某个分布,X 的一阶矩是E(X),也就是样本平均值,X 的二阶矩就是 E(X^2),也就是样本平方的平均值。

 Adam 算法根据损失函数对每个参数的梯度的一阶矩估计和二阶矩估计动态调整针对于每个参数的学习速率。Adam 也是基于梯度下降的方法,但是每次迭代参数的学习步长都有一个确定的范围,不会因为很大的梯度导致很大的学习步长,参数的值比较稳定。

 Adam(Adaptive Moment Estimation)本质上是带有动量项的 RMSprop,它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam 的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。


6.5.1 具体实现

 需要:步进值 ϵ,初始参数 θ,数值稳定量 δ,一阶动量衰减系数 ρ1,二阶动量衰减系数 ρ2 。

 其中几个取值一般为:δ=10-8,ρ1=0.9,ρ2=0.999 。

 中间变量:一阶动量 s,二阶动量 r,都初始化为 0 。


6.5.2 每步迭代过程

 (1)从训练集中的随机抽取一批容量为 m 的样本 {x1,…,xm} 以及相关的输出 yi 。

 (2)计算梯度和误差,更新 r 和 s,再根据 r 和 s 以及梯度计算参数更新量 。


38.png

6.5.3 用法

keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)


 6.5.4 参数

 lr:大于 0 的浮点数,学习率。

 beta_1/beta_2:浮点数, 0<beta<1,通常很接近 1。

 epsilon:大于 0 的小浮点数,防止除0错误。


6.6 Adamax

keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)

 Adamax 优化器的方法是基于无穷范数的 Adam 方法的变体。


 6.6.1 参数

 lr:大于 0 的浮点数,学习率。

 beta_1/beta_2:浮点数, 0<beta<1,通常很接近 1。

 epsilon:大于 0 的小浮点数,防止除 0 错误。


相关文章
|
27天前
|
机器学习/深度学习 人工智能 PyTorch
PyTorch深度学习 ? 带你从入门到精通!!!
🌟 蒋星熠Jaxonic,深度学习探索者。三年深耕PyTorch,从基础到部署,分享模型构建、GPU加速、TorchScript优化及PyTorch 2.0新特性,助力AI开发者高效进阶。
PyTorch深度学习 ? 带你从入门到精通!!!
|
25天前
|
边缘计算 人工智能 PyTorch
130_知识蒸馏技术:温度参数与损失函数设计 - 教师-学生模型的优化策略与PyTorch实现
随着大型语言模型(LLM)的规模不断增长,部署这些模型面临着巨大的计算和资源挑战。以DeepSeek-R1为例,其671B参数的规模即使经过INT4量化后,仍需要至少6张高端GPU才能运行,这对于大多数中小型企业和研究机构来说成本过高。知识蒸馏作为一种有效的模型压缩技术,通过将大型教师模型的知识迁移到小型学生模型中,在显著降低模型复杂度的同时保留核心性能,成为解决这一问题的关键技术之一。
|
1月前
|
机器学习/深度学习 存储 PyTorch
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
Neural ODE将神经网络与微分方程结合,用连续思维建模数据演化,突破传统离散层的限制,实现自适应深度与高效连续学习。
86 3
Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
|
27天前
|
机器学习/深度学习 数据采集 人工智能
深度学习实战指南:从神经网络基础到模型优化的完整攻略
🌟 蒋星熠Jaxonic,AI探索者。深耕深度学习,从神经网络到Transformer,用代码践行智能革命。分享实战经验,助你构建CV、NLP模型,共赴二进制星辰大海。
|
7月前
|
机器学习/深度学习 JavaScript PyTorch
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
生成对抗网络(GAN)的训练效果高度依赖于损失函数的选择。本文介绍了经典GAN损失函数理论,并用PyTorch实现多种变体,包括原始GAN、LS-GAN、WGAN及WGAN-GP等。通过分析其原理与优劣,如LS-GAN提升训练稳定性、WGAN-GP改善图像质量,展示了不同场景下损失函数的设计思路。代码实现覆盖生成器与判别器的核心逻辑,为实际应用提供了重要参考。未来可探索组合优化与自适应设计以提升性能。
552 7
9个主流GAN损失函数的数学原理和Pytorch代码实现:从经典模型到现代变体
|
4月前
|
机器学习/深度学习 存储 PyTorch
PyTorch + MLFlow 实战:从零构建可追踪的深度学习模型训练系统
本文通过使用 Kaggle 数据集训练情感分析模型的实例,详细演示了如何将 PyTorch 与 MLFlow 进行深度集成,实现完整的实验跟踪、模型记录和结果可复现性管理。文章将系统性地介绍训练代码的核心组件,展示指标和工件的记录方法,并提供 MLFlow UI 的详细界面截图。
195 2
PyTorch + MLFlow 实战:从零构建可追踪的深度学习模型训练系统
|
8月前
|
机器学习/深度学习 数据可视化 算法
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
神经常微分方程(Neural ODEs)是深度学习领域的创新模型,将神经网络的离散变换扩展为连续时间动力系统。本文基于Torchdyn库介绍Neural ODE的实现与训练方法,涵盖数据集构建、模型构建、基于PyTorch Lightning的训练及实验结果可视化等内容。Torchdyn支持多种数值求解算法和高级特性,适用于生成模型、时间序列分析等领域。
408 77
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
|
7月前
|
机器学习/深度学习 自然语言处理 算法
PyTorch PINN实战:用深度学习求解微分方程
物理信息神经网络(PINN)是一种将深度学习与物理定律结合的创新方法,特别适用于微分方程求解。传统神经网络依赖大规模标记数据,而PINN通过将微分方程约束嵌入损失函数,显著提高数据效率。它能在流体动力学、量子力学等领域实现高效建模,弥补了传统数值方法在高维复杂问题上的不足。尽管计算成本较高且对超参数敏感,PINN仍展现出强大的泛化能力和鲁棒性,为科学计算提供了新路径。文章详细介绍了PINN的工作原理、技术优势及局限性,并通过Python代码演示了其在微分方程求解中的应用,验证了其与解析解的高度一致性。
1429 5
PyTorch PINN实战:用深度学习求解微分方程
|
8月前
|
机器学习/深度学习 PyTorch TensorFlow
深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras
在深度学习的世界中,PyTorch、TensorFlow和Keras是最受欢迎的工具和框架,它们为研究者和开发者提供了强大且易于使用的接口。在本文中,我们将深入探索这三个框架,涵盖如何用它们实现经典深度学习模型,并通过代码实例详细讲解这些工具的使用方法。
|
11月前
|
机器学习/深度学习 人工智能 TensorFlow
基于TensorFlow的深度学习模型训练与优化实战
基于TensorFlow的深度学习模型训练与优化实战
488 3

热门文章

最新文章

推荐镜像

更多