PyTorch学习笔记7—损失函数、梯度下降

本篇是pytorch学习笔记系列第七篇,这一系列博客应该大多会来自于开源教程书:pytorch中文手册(pytorch handbook),其github网址为:https://github.com/zergtant/pytorch-handbook 本篇博客内容来自于这一手册以及pytorch官方的教程 ,感兴趣的观众们可以去自行下载

1 损失函数(Loss Function)

损失函数(loss function)是用来估量模型的预测值(我们例子中的output)与真实值(例子中的y_train)的不一致程度,它是一个非负实值函数,损失函数越小,模型的鲁棒性就越好。 我们训练模型的过程,就是通过不断的迭代计算,使用梯度下降的优化算法,使得损失函数越来越小。损失函数越小就表示算法达到意义上的最优。

这里有一个重点:因为PyTorch是使用mini-batch来进行计算的,所以损失函数的计算出来的结果已经对mini-batch取了平均

常见(PyTorch内置)的损失函数一下几个:

1.1 nn.L1Loss:

输入x和目标y之间差的绝对值,要求 x 和 y 的维度要一样(可以是向量或者矩阵),得到的 loss 维度也是对应一样的

𝑙𝑜𝑠𝑠(𝑥,𝑦)=1/𝑛∑|𝑥𝑖−𝑦𝑖|

1.2 nn.NLLLoss:

用于多分类的负对数似然损失函数

𝑙𝑜𝑠𝑠(𝑥,𝑐𝑙𝑎𝑠𝑠)=−𝑥[𝑐𝑙𝑎𝑠𝑠]

NLLLoss中如果传递了weights参数,会对损失进行加权,公式就变成了

𝑙𝑜𝑠𝑠(𝑥,𝑐𝑙𝑎𝑠𝑠)=−𝑤𝑒𝑖𝑔ℎ𝑡𝑠[𝑐𝑙𝑎𝑠𝑠]∗𝑥[𝑐𝑙𝑎𝑠𝑠]

1.3 nn.MSELoss:

均方损失函数 ,输入x和目标y之间均方差

𝑙𝑜𝑠𝑠(𝑥,𝑦)=1/𝑛∑(𝑥𝑖−𝑦𝑖)2

1.4 nn.CrossEntropyLoss:

多分类用的交叉熵损失函数,LogSoftMax和NLLLoss集成到一个类中,会调用nn.NLLLoss函数,我们可以理解为CrossEntropyLoss()=log_softmax() + NLLLoss()

𝑙𝑜𝑠𝑠(𝑥,𝑐𝑙𝑎𝑠𝑠)=−log𝑒𝑥𝑝(𝑥[𝑐𝑙𝑎𝑠𝑠])∑𝑗𝑒𝑥𝑝(𝑥[𝑗])) =−𝑥[𝑐𝑙𝑎𝑠𝑠]+𝑙𝑜𝑔(∑𝑗𝑒𝑥𝑝(𝑥[𝑗]))

因为使用了NLLLoss,所以也可以传入weight参数,这时loss的计算公式变为:

𝑙𝑜𝑠𝑠(𝑥,𝑐𝑙𝑎𝑠𝑠)=𝑤𝑒𝑖𝑔ℎ𝑡𝑠[𝑐𝑙𝑎𝑠𝑠]∗(−𝑥[𝑐𝑙𝑎𝑠𝑠]+𝑙𝑜𝑔(∑𝑗𝑒𝑥𝑝(𝑥[𝑗])))

所以一般多分类的情况会使用这个损失函数

1.5 nn.BCELoss:

计算 x 与 y 之间的二进制交叉熵。

𝑙𝑜𝑠𝑠(𝑜,𝑡)=−1𝑛∑𝑖(𝑡[𝑖]∗𝑙𝑜𝑔(𝑜[𝑖])+(1−𝑡[𝑖])∗𝑙𝑜𝑔(1−𝑜[𝑖]))

与NLLLoss类似,也可以添加权重参数:

𝑙𝑜𝑠𝑠(𝑜,𝑡)=−1𝑛∑𝑖𝑤𝑒𝑖𝑔ℎ𝑡𝑠[𝑖]∗(𝑡[𝑖]∗𝑙𝑜𝑔(𝑜[𝑖])+(1−𝑡[𝑖])∗𝑙𝑜𝑔(1−𝑜[𝑖]))

用的时候需要在该层前面加上 Sigmoid 函数。

2 梯度下降

在介绍损失函数的时候我们已经说了,梯度下降是一个使损失函数越来越小的优化算法,在无求解机器学习算法的模型参数,即约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一所以梯度下降是我们目前所说的机器学习的核心,了解了它的含义,也就了解了机器学习算法的含义。

2.1 梯度

在微积分里面,对多元函数的参数求∂偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。 例如函数f(x,y), 分别对x,y求偏导数,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,简称grad f(x,y)或者▽f(x,y)。

几何上讲,梯度就是函数变化增加最快的地方,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向梯度减少最快,也就是更加容易找到函数的最小值。

我们需要最小化损失函数,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。

2.2 梯度下降法直观解释

梯度下降法就好比下山,我们并不知道下山的路,于是决定走一步算一步,每走到一个位置的时候,求解当前位置的梯度,沿着梯度的负方向,也就是当前最陡峭的位置向下走一步,然后继续求解当前位置梯度,向这一步所在位置沿着最陡峭最易下山的位置走一步。这样一步步的走下去,一直走到觉得我们已经到了山脚。

如下图所示,(此图摘自百度百科)
在这里插入图片描述

这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处(局部最优解)。

这个问题在以前的机器学习中可能会遇到,因为机器学习中的特征比较少,所以导致很可能陷入到一个局部最优解中出不来,但是到了深度学习,动辄百万甚至上亿的特征,出现这种情况的纪律几乎为0,所以我们可以不用考虑这个问题。

2.3 Mini-batch的梯度下降法

对整个训练集进行梯度下降法的时候,我们必须处理整个训练数据集,然后才能进行一步梯度下降,即每一步梯度下降法需要对整个训练集进行一次处理,如果训练数据集很大的时候处理速度会很慢,而且也不可能一次的载入到内存或者显存中,所以我们会把大数据集分成小数据集,一部分一部分的训练,这个训练子集即称为Mini-batch。 在PyTorch中就是使用这种方法进行的训练,可以看看上一章中关于dataloader的介绍里面的batch_size就是我们一个Mini-batch的大小。

为了介绍的更简洁,使用 吴恩达老师的 deeplearning.ai 课程板书。

对于普通的梯度下降法,一个epoch只能进行一次梯度下降;
在这里插入图片描述
而对于Mini-batch梯度下降法,一个epoch可以进行Mini-batch的个数次梯度下降。 普通的batch梯度下降法和Mini-batch梯度下降法代价函数的变化趋势,如下图所示:
在这里插入图片描述

  • 如果训练样本的大小比较小时,能够一次性的读取到内存中,那我们就不需要使用Mini-batch,
  • 如果训练样本的大小比较大时,一次读入不到内存或者现存中,那我们必须要使用 Mini-batch来分批的计算
  • Mini-batch size的计算规则如下,在内存允许的最大情况下使用2的N次方个size
    在这里插入图片描述

2.4 torch.optim

torch.optim是一个实现了各种优化算法的库。大部分常用优化算法都有实现,我们直接调用即可。

2.4.1 torch.optim.SGD

随机梯度下降算法,带有动量(momentum)的算法作为一个可选参数可以进行设置,样例如下:

#lr参数为学习了率对于SGD来说一般选择0.1 0.01.0.001,如何设置会在后面实战的章节中详细说明
##如果设置了momentum,就是带有动量的SGD,可以不设置
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)

2.4.2 torch.optim.RMSprop

除了以上的带有动量Momentum梯度下降法外,RMSprop(root mean square prop)也是一种可以加快梯度下降的算法,利用RMSprop算法,可以减小某些维度梯度更新波动较大的情况,使其梯度下降的速度变得更快

#我们的课程基本不会使用到RMSprop所以这里只给一个实例
optimizer = torch.optim.RMSprop(model.parameters(), lr=0.01, alpha=0.99)

2.4.3 torch.optim.Adam

Adam 优化算法的基本思想就是将 Momentum 和 RMSprop 结合起来形成的一种适用于不同深度学习结构的优化算法

# 这里的lr,betas,还有eps都是用默认值即可,所以Adam是一个使用起来最简单的优化方法
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08)

2.5 方差/偏差

偏差度量了学习算法的期望预测与真实结果的偏离程序, 即 刻画了学习算法本身的拟合能力
方差度量了同样大小的训练集的变动所导致的学习性能的变化, 即 模型的泛化能力

在这里插入图片描述

从图中我们可以看出

高偏差(high bias)的情况,一般称为欠拟合(underfitting),即我们的模型并没有很好的去适配现有的数据,拟合度不够。
高方差(high variance)的情况一般称作过拟合(overfitting),即模型对于训练数据拟合度太高了,失去了泛化的能力。

如何解决这两种情况呢?

欠拟合:

  • 增加网络结构,如增加隐藏层数目;
  • 训练更长时间;
  • 寻找合适的网络架构,使用更大的NN结构;

过拟合 :

  • 使用更多的数据;
  • 正则化( regularization);
  • 寻找合适的网络结构;

2.6 正则化

利用正则化来解决High variance 的问题,正则化是在 Cost function 中加入一项正则化项,惩罚模型的复杂度,这里我们简单的介绍一下正则化的概念

2.6.1 L1正则化

损失函数基础上加上权重参数的绝对值

𝐿=𝐸𝑖𝑛+𝜆∑𝑗||𝑤𝑗||

2.6.2 L2正则化

损失函数基础上加上权重参数的平方和

𝐿=𝐸𝑖𝑛+𝜆∑𝑗𝑤2𝑗

需要说明的是:l1 相比于 l2 会更容易获得稀疏解(知乎)

本篇完…

本系列已更新的学习笔记:
PyTorch学习笔记1—PyTorch简介
PyTorch学习笔记2—win10下pytorch-gpu安装以及CUDA安装记录
PyTorch学习笔记3—PyTorch深度学习入门(一)—基本方法
PyTorch学习笔记4—PyTorch深度学习入门(二)—自动求导
PyTorch学习笔记5—PyTorch深度学习入门(三)—神经网络
PyTorch学习笔记6—PyTorch深度学习入门(四)—入门实例

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值