pytorch常用损失函数

损失函数的基本用法:

criterion = LossCriterion() #构造函数有自己的参数
loss = criterion(x, y) #调用标准时也有参数

得到的loss结果已经对mini-batch数量取了平均值

1.BCELoss(二分类)

CLASS torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction=‘mean‘)

创建一个衡量目标和输出之间二进制交叉熵的criterion

unreduced loss函数(即reduction参数设置为‘none‘)为:

N表示batch size,xn为输出,yn为目标

如果reduction不为‘none‘(默认设为‘mean‘),则:

即默认情况下,loss会基于element求平均值,如果size_average=False的话,loss会被累加。

这是用来测量误差error的重建,例如一个自动编码器。注意 0<=target[i]<=1。

参数:

  • weight (Tensor,可选) – 每批元素损失的手工重标权重。如果给定,则必须是一个大小为“nbatch”的张量。
  • size_average (bool, 可选) – 弃用(见reduction参数)。默认情况下,设置为True,即对批处理中的每个损失元素进行平均。注意,对于某些损失,每个样本有多个元素。如果字段size_average设置为False,则对每个小批的损失求和。当reduce为False时,该参数被忽略。默认值:True
  • reduce (bool,可选) – 弃用(reduction参数)。默认情况下,设置为True,即根据size_average参数的值决定对每个小批的观察值是进行平均或求和。如果reduce为False,则返回每个批处理元素的损失,不进行平均和求和操作,即忽略size_average参数。默认值:True
  • reduction (string,可选) – 指定要应用于输出的reduction操作:‘ none ‘ | ‘mean‘ | ‘ sum ‘。“none”:表示不进行任何reduction,“mean”:输出的和除以输出中的元素数,即求平均值,“sum”:输出求和。注意:size_average和reduce正在被弃用,与此同时,指定这两个arg中的任何一个都将覆盖reduction参数。默认值:“mean”

形状:

  • 输入:(N,*), *代表任意数目附加维度
  • 目标:(N,*),与输入拥有同样的形状
  • 输出:标量scalar,即输出一个值。如果reduce为False,即不进行任何处理,则(N,*),形状与输入相同。

举例:

m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3,requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(m(input), target)
output.backward()
input,target,output

返回:

(tensor([-0.8728,  0.3632, -0.0547], requires_grad=True),
 tensor([1., 0., 0.]),
 tensor(0.9264, grad_fn=<BinaryCrossEntropyBackward>))

m(input)结果为:

tensor([0.2947, 0.5898, 0.4863])

计算output = (1 * ln 0.2947+(1-1)*ln(1-0.2947) + 0*ln0.5898 + (1-0)*ln(1-0.5898) + 0*ln0.4863 + (1-0)*ln(1-0.4863)) / 3 = 0.9264

input.grad

返回:

tensor([-0.2351,  0.1966,  0.1621])

当我们进行的是二分类时,即激活函数使用的是sigmoid函数时,常使用交叉熵作为损失函数。这样就能够解决因sigmoid函数导致的梯度消失问题

比如当我们使用的不是二进制交叉熵作为损失函数,而是使用的是平方差损失,即MSELoss作为损失函数,如:

那么假设进行的是二分类,损失函数为 ln= (xn - yn)2 / 2, n=1,2 , 激活函数为sigmoid函数,所以xn=σ(z),其中z = wx + b

那么当进行链式求导时,得:

  • 对w求导: ∂L / ∂w = (xn - yn) * σ(z) * z‘ = (xn - yn) * σ(z) * x
  • 对b求导:  ∂L / ∂b = (xn - yn) * σ(z)

从上面两个公式可知梯度计算都与sigmoid函数的梯度相关,而因为sigmoid函数左右两边梯度趋于0,这就会导致反向传播过程中计算得到的梯度会趋于0,即导致发生梯度消失的问题

而如果是以交叉熵作为损失函数,得到的梯度计算公式就会变为:

  • 对w求导: ∂L / ∂w = 1/n *  Σi xn * (σ(z)-yn)
  • 对b求导:  ∂L / ∂b =1/n *  Σi (σ(z)-yn)

可见不会与sigmoid的梯度相关,这样就不会出现梯度消失的问题

2.BCEWithLogitsLoss

CLASS torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction=‘mean‘, pos_weight=None)

与BCELoss的不同:

将sigmoid函数和BCELoss方法结合到一个类中

这个版本在数值上比使用一个带着BCELoss损失函数的简单的Sigmoid函数更稳定,通过将操作合并到一层中,我们利用log-sum-exp技巧来实现数值稳定性。

损失函数(即reduction参数设置为‘none‘)变为:

多出参数:

  • pos_weight (Tensor,可选) –正值例子的权重,必须是有着与分类数目相同的长度的向量

该参数用处:

可以通过增加正值示例的权重来权衡召回率和准确性。在多标签分类的情况下,损失可以描述为:

c表示类的数量(c>1表明是多标签二进制分类,c=1表明是单标签二进制分类),n为一批中的例子数量,pc为类别c的正值的权重,解决正负例样本不均衡的情况

pc>1增加召回率,pc<1增加准确性

举例:例如,如果一个数据集包含一个类的100个正示例和300个负示例,那么该类的pos_weigh设为300/100=3。该损失函数将表现得像数据集包含了300个正示例

如果不考虑参数pos_weigh,其实BCEWithLogitsLoss就相当于比BCELoss多进行了一个sigmoid操作,所以上面的例子:

m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3,requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(m(input), target)

等价于:

loss = nn.BCEWithLogitsLoss()
input = torch.randn(3,requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(input, target)

4.NLLLoss(多分类)

CLASS torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘mean‘)

用于多分类的负对数似然损失函数(negative log likelihood loss)

损失函数(即reduction参数设置为‘none‘)为:

如果提供了,可选的参数weight权重应该是一个一维张量,为每个类分配权重。当你有一个不平衡的训练集时,这是特别有用的。

通过转发调用给出的输入 (即nn.LogSoftmax()后的输出) 应该包含每个类的log-probability。输入要么是大小为(minibatch,C)或大小(minibatch,C,d1,d2,...,dK)的Tensor,k>=1表示k维的输入

通过在网络的最后一层添加LogSoftmax层,可以很容易地获得神经网络中的log-probability。如果不喜欢添加额外的层,可以使用CrossEntropyLoss损失函数来替代。

损失预期的目标应该是[0,c - 1]范围内的类索引,其中C =类的数量;如果指定ignore_index参数,该损失函数也接受这个类索引(这个索引不一定在类范围内)。

如果reduction不为‘none‘(默认设为‘mean‘),则:

该损失函数也能被使用在高维输入中,通过提供大小为(minibatch,C,d1,d2,...,dK)的输入,k>=1表示k维的输入,和一个与该大小相同的合适的目标值

在图片的例子中,该函数计算每一个像素的NLL loss

多出参数:

  • ignore_index (intoptional) – 指定一个被忽略的目标值,该目标值不影响输入梯度。当size_average为真时,对非忽略目标的损失进行平均。

形状:

  • 输入:(N,C), C代表类别的数量;或者在计算高维损失函数例子中输入大小为(N,C,d1?,d2?,...,dK?),k>=1
  • 目标:(N),与输入拥有同样的形状,每一个值大小为为 0≤targets[i]≤C−1 ;或者在计算高维损失函数例子中输入大小为(N,C,d1?,d2?,...,dK?),k>=1
  • 输出:标量scalar。如果reduction=‘none‘,则其大小与目标相同,为(N)或(N,C,d1?,d2?,...,dK?),k>=1

低维举例:

m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()
# input is of size N x C = 3 x 5
input = torch.randn(3,5,requires_grad=True)
input

返回:

tensor([[-0.8676,  1.5017,  0.2963, -0.9431, -0.0929],
        [ 0.3540,  1.0994, -1.1085, -0.4001,  0.0102],
        [ 1.3653, -0.3828,  0.6257, -2.4996,  0.1928]], requires_grad=True)

nn.LogSoftmax(dim=1)即先进行Softmax计算(得0-1的值),再取Log,得到的都是负数:

m(input)

返回:

tensor([[-2.8899, -0.5205, -1.7259, -2.9653, -2.1152],
        [-1.5082, -0.7628, -2.9707, -2.2623, -1.8520],
        [-0.6841, -2.4323, -1.4237, -4.5490, -1.8566]],
       grad_fn=<LogSoftmaxBackward>)
#each element in target has to have 0 <= value < C
target = torch.tensor([1,0,4])
output = loss(m(input), target)
output

返回:

tensor(1.2951, grad_fn=<NllLossBackward>)

高维例子:

# 2D loss example (used, for example, with image inputs)
N, C = 5,4
loss = nn.NLLLoss()
# input is of size N x channel x height x width
data = torch.randn(N, 16, 10, 10)
conv = nn.Conv2d(16, C, (3, 3))#输出为5*8*8
m = nn.LogSoftmax(dim=1)
# each element in target has to have 0 <= value < C
target = torch.empty(N, 8, 8, dtype=torch.long).random_(0, C) #target.size()=target = torch.empty(N, 8, 8, dtype=torch.long).random_(0, C)
output = loss(m(conv(data)), target)
output

返回:

tensor(1.5501, grad_fn=<NllLoss2DBackward>)

5.CrossEntropyLoss(多分类)

该criterion将nn.LogSoftmax()和nn.NLLLoss()方法结合到一个类中

当用C类训练分类问题时,它是有用的。如果提供了,可选的参数weight权重应该是一个一维张量,为每个类分配权重。当你有一个不平衡的训练集时,这是特别有用的。

每个类的输入应该包含原始的、未标准化的分数。

输入应该是大小为(minibatch,C)或大小(minibatch,C,d1,d2,...,dK)的Tensor,k>=1表示k维的输入

该criterion期望在[0,c - 1]范围内的一个类指标作为小batch大小的一维张量的每个值的目标值;如果指定ignore_index,该criterion也接受这个类索引值(这个索引不一定在类范围内)。

损失函数为:

如果带了weight参数为:

每一个小batch的观测值都返回平均后的损失。

该损失函数也能被使用在高维输入中,通过提供大小为(minibatch,C,d1,d2,...,dK)的输入,k>=1表示k维的输入,和一个与该大小相同的合适的目标值

所以上面NLLLoss的例子:

m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()
# input is of size N x C = 3 x 5
input = torch.randn(3,5,requires_grad=True)
#each element in target has to have 0 <= value < C
target = target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(m(input), target)

等价于这里的:

loss = nn.CrossEntropyLoss()
# input is of size N x C = 3 x 5
input = torch.randn(3,5,requires_grad=True)
#each element in target has to have 0 <= value < C
target = target = torch.empty(3, dtype=torch.long).random_(5)
output = loss(input, target)

6.L1Loss(L1 norm)

CLASS torch.nn.L1Loss(size_average=None, reduce=None, reduction=‘mean‘)

创建一个criterion计算input x和target y的每个元素的平均绝对误差(mean absolute error (MAE))

unreduced loss函数(即reduction参数设置为‘none‘)为:

N表示batch size

如果reduction不为‘none‘(默认设为‘mean‘),则:

x和y是有着n个向量的任意形状的张量

mean先对所有元素进行sum操作,然后除以n

如果设置reduction = ‘sum‘,除以n的操作可以省略,即只对所有元素进行sum操作

形状:

  • 输入:(N,*), *代表任意数目附加维度
  • 目标:(N,*),与输入拥有同样的形状
  • 输出:标量scalar,即输出一个值。如果reduction=‘none‘,即不进行任何处理,则为(N,*),形状与输入相同。

举例:

loss = nn.L1Loss()
input = torch.randn(1, 2, requires_grad=True)#tensor([[-0.0625, -2.1603]], requires_grad=True)
target = torch.randn(1, 2)#tensor([[0.6789, 0.9831]])
output = loss(input, target)#tensor(1.9424, grad_fn=<L1LossBackward>)

output= (|-0.0625-0.6789| + |-2.1603-0.9831|) / 2 = 1.9424

7.MSELoss(L2 norm)

创建一个criterion计算input x和target y的每个元素的均方误差(mean absolute error (MAE))

unreduced loss函数(即reduction参数设置为‘none‘)为:

N表示batch size

如果reduction不为‘none‘(默认设为‘mean‘),则:

x和y是有着n个向量的任意形状的张量

mean先对所有元素进行sum操作,然后除以n

如果设置reduction = ‘sum‘,除以n的操作可以省略,即只对所有元素进行sum操作

形状:

  • 输入:(N,*), *代表任意数目附加维度
  • 目标:(N,*),与输入拥有同样的形状

举例:

loss = nn.MSELoss()
input = torch.randn(1, 2, requires_grad=True)#tensor([[-1.4445, -2.4888]], requires_grad=True)
target = torch.randn(1, 2)#tensor([[ 0.7117, -0.1200]])
output = loss(input, target)#tensor(5.1303, grad_fn=<MseLossBackward>)

output =( (-1.4445-0.7117)2 + ( -2.4888 + 0.1200 )2 ) / 2 = 5.1303

8.SmoothL1Loss

CLASS torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction=‘mean‘)

创建一个criterion,如果绝对元素误差低于1,则使用平方项,否则使用L1项。与MSELoss相比,它对异常值的敏感度较低; 在某些情况下,它可以防止梯度的爆炸式增长(例如,参见Ross Girshick的Fast R-CNN论文)。

也被称为Huber损失:

x和y是有着n个向量的任意形状的张量

mean先对所有元素进行sum操作,然后除以n

如果设置reduction = ‘sum‘,除以n的操作可以省略,即只对所有元素进行sum操作

形状:

  • 输入:(N,*), *代表任意数目附加维度
  • 目标:(N,*),与输入拥有同样的形状
  • 输出:标量scalar,即输出一个值。如果reduction=‘none‘,即不进行任何处理,则为(N,*),形状与输入相同。

原文地址:https://www.cnblogs.com/wanghui-garcia/p/10862733.html

时间: 2024-10-29 19:43:34

pytorch常用损失函数的相关文章

常用损失函数积累

损失函数(loss function)是用来估量模型的预测值f(x)与真实值Y的不一致程度,它是一个非负实值函数,通常使用L(Y, f(x))来表示,损失函数越小,模型的鲁棒性就越好.损失函数是经验风险函数的核心部分,也是结构风险函数重要组成部分.模型的结构风险函数包括了经验风险项和正则项,通常可以表示成如下式子: 其中,前面的均值函数表示的是经验风险函数,L代表的是损失函数,后面的Φ是正则化项(regularizer)或者叫惩罚项(penalty term),它可以是L1,也可以是L2,或者其

Pytorch:损失函数

损失函数通过调用torch.nn包实现. 基本用法: criterion = LossCriterion() #构造函数有自己的参数 loss = criterion(x, y) #调用标准时也有参数 L1范数损失 L1Loss 计算 output 和 target 之差的绝对值. torch.nn.L1Loss(reduction='mean')# reduction-三个值,none: 不使用约简:mean:返回loss和的平均值: sum:返回loss的和.默认:mean. 均方误差损失

Pytorch 常用函数

1. torch.renorm(input, p, dim, maxnorm, out=None) → Tensor Returns a tensor where each sub-tensor of input along dimension dim is normalized such that the p-norm of the sub-tensor is lower than the value maxnorm. 解释:返回一个张量,包含规范化后的各个子张量,使得沿着dim维划分的各子张

PyTorch常用函数:torch.ge; torch.gt; torch.le; equal; eq

torch.ge torch.ge(input, other, out=None) → Tensor 逐元素比较input和other,即是否 input>=otherinput>=other. 如果两个张量有相同的形状和元素值,则返回True ,否则 False. 第二个参数可以为一个数或与第一个参数相同形状和类型的张量 参数: input (Tensor) – 待对比的张量 other (Tensor or float) – 对比的张量或float值 out (Tensor, option

pytorch 入门指南

两类深度学习框架的优缺点 动态图(PyTorch) 计算图的进行与代码的运行时同时进行的. 静态图(Tensorflow <2.0) 自建命名体系 自建时序控制 难以介入 使用深度学习框架的优点 GPU 加速 (cuda) 自动求导 常用网络层的API PyTorch 的特点 支持 GPU 动态神经网络 Python 优先 命令式体验 轻松扩展 1.Pytorch简介 Pytorch是Facebook 的 AI 研究团队发布了一个基于 Python的科学计算包,旨在服务两类场合: 替代numpy

损失函数 hinge loss vs softmax loss

1. 损失函数 损失函数(Loss function)是用来估量你模型的预测值 f(x) 与真实值 Y 的不一致程度,它是一个非负实值函数,通常用 L(Y,f(x)) 来表示. 损失函数越小,模型的鲁棒性就越好. 损失函数是经验风险函数的核心部分,也是结构风险函数的重要组成部分.模型的风险结构包括了风险项和正则项,通常如下所示: 其中,前面的均值函数表示的是经验风险函数,L代表的是损失函数,后面的 Φ 是正则化项(regularizer)或者叫惩罚项(penalty term), 它可以是L1,

对于分类问题的神经网络最后一层的函数:sigmoid、softmax与损失函数

对于分类问题的神经网络最后一层的函数做如下知识点总结: sigmoid和softmax一般用作神经网络的最后一层做分类函数(备注:sigmoid也用作中间层做激活函数): 对于类别数量大于2的分类问题,如果每个类别之间互斥,则选用softmax函数(例如:类别为牡丹花.玫瑰花.菊花),如果每个类别之间有交叉则选用与类别数量相等的sigmoid函数(例如:类别为小孩.大人.男人.女人,此处应该选用4个sigmoid函数): 神经网络最后一层的分类函数直接面临作损失函数的选择: softmax函数的

交叉熵损失函数

交叉熵损失是分类任务中的常用损失函数,但是是否注意到二分类与多分类情况下的交叉熵形式上的不同呢? 两种形式 这两个都是交叉熵损失函数,但是看起来长的却有天壤之别.为什么同是交叉熵损失函数,长的却不一样? 因为这两个交叉熵损失函数对应不同的最后一层的输出:第一个对应的最后一层是softmax,第二个对应的最后一层是sigmoid 先来看下信息论中交叉熵的形式 交叉熵是用来描述两个分布的距离的,神经网络训练的目的就是使 g(x) 逼近 p(x). softmax层的交叉熵 (x)是什么呢?就是最后一

[pytorch]pytorch loss function 总结

原文: http://www.voidcn.com/article/p-rtzqgqkz-bpg.html 最近看了下 PyTorch 的损失函数文档,整理了下自己的理解,重新格式化了公式如下,以便以后查阅. 注意下面的损失函数都是在单个样本上计算的,粗体表示向量,否则是标量.向量的维度用 表示. nn.L1Loss nn.SmoothL1Loss 也叫作 Huber Loss,误差在 (-1,1) 上是平方损失,其他情况是 L1 损失. nn.MSELoss 平方损失函数 nn.BCELoss