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,可选) –
弃用(
见
)。默认情况下,设置为True,即根据size_average参数的值决定对每个小批的观察值是进行平均或求和。如果reduce为False,则返回每个批处理元素的损失,不进行平均和求和操作,即忽略size_average参数。默认值:Truereduction
参数 - reduction (string,可选) – 指定要应用于输出的
操作:' none ' | 'mean' | ' sum '。“none”:表示不进行任何reduction
,“mean”:输出的和除以输出中的元素数,即求平均值,“sum”:输出求和。注意:size_average和reduce正在被弃用,与此同时,指定这两个arg中的任何一个都将覆盖reduction参数。默认值:“mean”reduction
形状:
- 输入:(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(,requires_grad=True)
target = torch.empty().random_()
output = loss(m(input), target)
等价于:
loss = nn.BCEWithLogitsLoss()
input = torch.randn(,requires_grad=True)
target = torch.empty().random_()
output = loss(input, target)
4.NLLLoss(多分类)
CLASS torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-, 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 (int, optional) – 指定一个被忽略的目标值,该目标值不影响输入梯度。当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=)
loss = nn.NLLLoss()
# input is of size N x C = x
input = torch.randn(,,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 <= value < C
target = torch.tensor([,,])
output = loss(m(input), target)
output
返回:
tensor(1.2951, grad_fn=<NllLossBackward>)
高维例子:
# 2D loss example (used, for example, with image inputs)
N, C = ,
loss = nn.NLLLoss()
# input is of size N x channel x height x width
data = torch.randn(N, , , )
conv = nn.Conv2d(, C, (, ))#输出为5**
m = nn.LogSoftmax(dim=)
# each element in target has to have <= value < C
target = torch.empty(N, , , dtype=torch.long).random_(, C) #target.size()=target = torch.empty(N, , , dtype=torch.long).random_(, 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=)
loss = nn.NLLLoss()
# input is of size N x C = x
input = torch.randn(,,requires_grad=True)
#each element in target has to have <= value < C
target = target = torch.empty(, dtype=torch.long).random_()
output = loss(m(input), target)
等价于这里的:
loss = nn.CrossEntropyLoss()
# input is of size N x C = x
input = torch.randn(,,requires_grad=True)
#each element in target has to have <= value < C
target = target = torch.empty(, dtype=torch.long).random_()
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(, , requires_grad=True)#tensor([[-0.0625, -2.1603]], requires_grad=True)
target = torch.randn(, )#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(, , requires_grad=True)#tensor([[-1.4445, -2.4888]], requires_grad=True)
target = torch.randn(, )#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,*),形状与输入相同。
pytorch常用损失函数的更多相关文章
- PyTorch常用代码段整理合集
PyTorch常用代码段整理合集 转自:知乎 作者:张皓 众所周知,程序猿在写代码时通常会在网上搜索大量资料,其中大部分是代码段.然而,这项工作常常令人心累身疲,耗费大量时间.所以,今天小编转载了知乎 ...
- pytorch常用函数总结(持续更新)
pytorch常用函数总结(持续更新) torch.max(input,dim) 求取指定维度上的最大值,,返回输入张量给定维度上每行的最大值,并同时返回每个最大值的位置索引.比如: demo.sha ...
- 【深度学习】一文读懂机器学习常用损失函数(Loss Function)
最近太忙已经好久没有写博客了,今天整理分享一篇关于损失函数的文章吧,以前对损失函数的理解不够深入,没有真正理解每个损失函数的特点以及应用范围,如果文中有任何错误,请各位朋友指教,谢谢~ 损失函数(lo ...
- PyTorch 常用代码段整理
基础配置 检查 PyTorch 版本 torch.__version__ # PyTorch version torch.version.cuda ...
- Pytorch 常用函数
1. torch.renorm(input, p, dim, maxnorm, out=None) → Tensor Returns a tensor where each sub-tensor of ...
- PyTorch常用参数初始化方法详解
1. 均匀分布 torch.nn.init.uniform_(tensor, a=0, b=1) 从均匀分布U(a, b)中采样,初始化张量. 参数: tensor - 需要填充的张量 a - 均匀分 ...
- pytorch常用的padding函数
1)ReflectionPad2d CLASS torch.nn.ReflectionPad2d(padding) 使用输入边界的反射来填充输入tensor 对于N维的填充,使用torch.nn.fu ...
- pytorch常用normalization函数
参考:https://blog.csdn.net/liuxiao214/article/details/81037416 归一化层,目前主要有这几个方法,Batch Normalization(201 ...
- PyTorch常用函数总结
将一个tensor分到多个GPU上:torch.cuda.comm.scatter
随机推荐
- python中redis
一.简介 二.redis的安装和使用 三.python操作readis之安装和支持存储类型 四.python操作redis值普通链接 五.python操作redis值连接池 六.操作之String操作 ...
- php各种框架的区别
一.CI框架 CI框架是一个简单快速的PHP MVC轻量级框架,它执行效率高,快速简洁,代码量少,适合中小型项目开发,也可以做大型项目,但扩展能力不是很好,Ci支持的url模式默认为pathinfo形 ...
- webpack中bundler源码编写
新建一个项目,再新建一个src文件夹,里面有三个文件,word.js,message.js,index.js word.js export const word = 'hello'; message. ...
- tcp文件下载
服务器端 import socket def send_file_2_client(new_client_socket,client_addr): # 接收信息 file_name = new_cli ...
- 使用UEditor 报错Cannot read property 'nodeType' of undefined 解决办法
报如下错误 解决办法: //对编辑器的操作最好在编辑器ready之后再做 ue.ready(function() { }) <!-- 实例化编辑器 --> <script type= ...
- PHP 判断给定两个时间是否在同一周,月,年
判断是否在同一周 date_default_timezone_set('PRC'); //判断是否在同一周,原理:求出其中一个时间戳所在周的周一凌晨时间戳和周日24.00时间戳,如果另一个时间戳在这个 ...
- hive优化,控制map、reduce数量
一.调整hive作业中的map数 1.通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为1 ...
- greenplum(postgresql) 数据字典
greenplum是基于postgresql开发的分布式数据库,里面大部分的数据字典是一样的.我们在维护gp的时候对gp的数据字典比较熟悉,特此分享给大家.在这里不会详细介绍每个字典的内容,只会介绍常 ...
- 关于 js 函数参数的this
先看一道面试题: var number = 10; function fn() { console.log(this.number); } var obj = { number: 2, show: f ...
- hdu 5452
无意中看到这道题 没读懂英文题面 百度题解寻找题面 看到: #include <iostream> #include <cstdio> #include <algorit ...