当前位置:网站首页>Pytorch模型训练实用教程学习笔记:三、损失函数汇总
Pytorch模型训练实用教程学习笔记:三、损失函数汇总
2022-08-01 19:16:00 【zstar-_】
前言
最近在重温Pytorch基础,然而Pytorch官方文档的各种API是根据字母排列的,并不适合学习阅读。
于是在gayhub上找到了这样一份教程《Pytorch模型训练实用教程》,写得不错,特此根据它来再学习一下Pytorch。
仓库地址:https://github.com/TingsongYu/PyTorch_Tutorial
损失函数汇总
Pytorch中,有下列一些损失函数.
L1loss
torch.nn.L1Loss(size_average=None, reduce=None)
功能:
计算 output 和 target 之差的绝对值,可选返回同维度的 tensor 或者是一个标量。
计算公式:
参数:
reduce(bool)- 返回值是否为标量,默认为 True
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
调用实例:
import torch
import torch.nn as nn
# 生成网络输出 以及 目标输出
output = torch.ones(2, 2, requires_grad=True)*0.5
target = torch.ones(2, 2)
# 设置三种不同参数的L1Loss
reduce_False = nn.L1Loss(size_average=True, reduce=False)
size_average_True = nn.L1Loss(size_average=True, reduce=True)
size_average_False = nn.L1Loss(size_average=False, reduce=True)
o_0 = reduce_False(output, target)
o_1 = size_average_True(output, target)
o_2 = size_average_False(output, target)
print('\nreduce=False, 输出同维度的loss:\n{}\n'.format(o_0))
print('size_average=True,\t求平均:\t{}'.format(o_1))
print('size_average=False,\t求和:\t{}'.format(o_2))
MSELoss
torch.nn.MSELoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
计算 output 和 target 之差的平方,可选返回同维度的 tensor 或者是一个标量。
计算公式:
参数:
reduce(bool)- 返回值是否为标量,默认为 True
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
调用实例:
# coding: utf-8
import torch
import torch.nn as nn
# ----------------------------------- MSE loss
# 生成网络输出 以及 目标输出
output = torch.ones(2, 2, requires_grad=True) * 0.5
target = torch.ones(2, 2)
# 设置三种不同参数的L1Loss
reduce_False = nn.MSELoss(size_average=True, reduce=False)
size_average_True = nn.MSELoss(size_average=True, reduce=True)
size_average_False = nn.MSELoss(size_average=False, reduce=True)
o_0 = reduce_False(output, target)
o_1 = size_average_True(output, target)
o_2 = size_average_False(output, target)
print('\nreduce=False, 输出同维度的loss:\n{}\n'.format(o_0))
print('size_average=True,\t求平均:\t{}'.format(o_1))
print('size_average=False,\t求和:\t{}'.format(o_2))
CrossEntropyLoss
torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-
100, reduce=None, reduction=‘elementwise_mean’)
功能:
将输入经过 softmax 激活函数之后,再计算其与 target 的交叉熵损失。即该方法将nn.LogSoftmax()和 nn.NLLLoss()进行了结合。严格意义上的交叉熵损失函数应该是nn.NLLLoss()。
计算公式:
参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题。weight 必须是 float类型的 tensor,其长度要于类别 C 一致,即每一个类别都要设置有 weight。
带 weight 的计算公式:
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
ignore_index(int)- 忽略某一类别,不计算其 loss,其 loss 会为 0,并且,在采用size_average 时,不会计算那一类的 loss,除的时候的分母也不会统计那一类的样本。
调用实例:
import torch
import torch.nn as nn
import numpy as np
import math
# ----------------------------------- CrossEntropy loss: base
loss_f = nn.CrossEntropyLoss(weight=None, size_average=True, reduce=False)
# 生成网络输出 以及 目标输出
output = torch.ones(2, 3, requires_grad=True) * 0.5 # 假设一个三分类任务,batchsize=2,假设每个神经元输出都为0.5
target = torch.from_numpy(np.array([0, 1])).type(torch.LongTensor)
loss = loss_f(output, target)
print('--------------------------------------------------- CrossEntropy loss: base')
print('loss: ', loss)
print('由于reduce=False,所以可以看到每一个样本的loss,输出为[1.0986, 1.0986]')
# 熟悉计算公式,手动计算第一个样本
output = output[0].detach().numpy()
output_1 = output[0] # 第一个样本的输出值
target_1 = target[0].numpy()
# 第一项
x_class = output[target_1]
# 第二项
exp = math.e
sigma_exp_x = pow(exp, output[0]) + pow(exp, output[1]) + pow(exp, output[2])
log_sigma_exp_x = math.log(sigma_exp_x)
# 两项相加
loss_1 = -x_class + log_sigma_exp_x
print('--------------------------------------------------- 手动计算')
print('第一个样本的loss:', loss_1)
# ----------------------------------- CrossEntropy loss: weight
weight = torch.from_numpy(np.array([0.6, 0.2, 0.2])).float()
loss_f = nn.CrossEntropyLoss(weight=weight, size_average=True, reduce=False)
output = torch.ones(2, 3, requires_grad=True) * 0.5 # 假设一个三分类任务,batchsize为2个,假设每个神经元输出都为0.5
target = torch.from_numpy(np.array([0, 1])).type(torch.LongTensor)
loss = loss_f(output, target)
print('\n\n--------------------------------------------------- CrossEntropy loss: weight')
print('loss: ', loss) #
print('原始loss值为1.0986, 第一个样本是第0类,weight=0.6,所以输出为1.0986*0.6 =', 1.0986*0.6)
# ----------------------------------- CrossEntropy loss: ignore_index
loss_f_1 = nn.CrossEntropyLoss(weight=None, size_average=False, reduce=False, ignore_index=1)
loss_f_2 = nn.CrossEntropyLoss(weight=None, size_average=False, reduce=False, ignore_index=2)
output = torch.ones(3, 3, requires_grad=True) * 0.5 # 假设一个三分类任务,batchsize为2个,假设每个神经元输出都为0.5
target = torch.from_numpy(np.array([0, 1, 2])).type(torch.LongTensor)
loss_1 = loss_f_1(output, target)
loss_2 = loss_f_2(output, target)
print('\n\n--------------------------------------------------- CrossEntropy loss: ignore_index')
print('ignore_index = 1: ', loss_1) # 类别为1的样本的loss为0
print('ignore_index = 2: ', loss_2) # 类别为2的样本的loss为0
NLLLoss
torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None,reduction=‘elementwise_mean’)
功能:
常用于多分类任务,但是 input 在输入 NLLLoss()之前,需要对 input 进行 log_softmax 函数激活,即将 input 转换成概率分布的形式,并且取对数。这些步骤隐含在了CrossEntropyLoss中。
参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题。weight 必须是 float类型的 tensor,其长度要于类别 C 一致,即每一个类别都要设置有 weight。
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为除以权重之和的平均值;为 False 时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
ignore_index(int)- 忽略某一类别,不计算其 loss,其 loss 会为 0,并且,在采用
size_average 时,不会计算那一类的 loss,除的时候的分母也不会统计那一类的样本。
调用实例:
# coding: utf-8
import torch
import torch.nn as nn
import numpy as np
# ----------------------------------- log likelihood loss
# 各类别权重
weight = torch.from_numpy(np.array([0.6, 0.2, 0.2])).float()
# 生成网络输出 以及 目标输出
output = torch.from_numpy(np.array([[0.7, 0.2, 0.1], [0.4, 1.2, 0.4]])).float()
output.requires_grad = True
target = torch.from_numpy(np.array([0, 0])).type(torch.LongTensor)
loss_f = nn.NLLLoss(weight=weight, size_average=True, reduce=False)
loss = loss_f(output, target)
print('\nloss: \n', loss)
print('\n第一个样本是0类,loss = -(0.6*0.7)={}'.format(loss[0]))
print('\n第二个样本是0类,loss = -(0.6*0.4)={}'.format(loss[1]))
PoissonNLLLoss
torch.nn.PoissonNLLLoss(log_input=True, full=False, size_average=None, eps=1e^8, reduce=None, reduction=‘elementwise_mean’)
功能:
用于 target 服从泊松分布的分类任务。
参数:
log_input(bool)- 为 True 时,计算公式为:loss(input,target)=exp(input) - target * input; 为 False 时,loss(input,target)=input - target * log(input+eps)
full(bool)- 是否计算全部的 loss。例如,当采用斯特林公式近似阶乘项时,此为target*log(target) - target+0.5∗log(2πtarget)
eps(float)- 当 log_input = False 时,用来防止计算 log(0),而增加的一个修正项。即loss(input,target)=input - target * log(input+eps)
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
调用实例:
# coding: utf-8
import torch
import torch.nn as nn
import numpy as np
# ----------------------------------- Poisson NLLLoss
# 生成网络输出 以及 目标输出
log_input = torch.randn(5, 2, requires_grad=True)
target = torch.randn(5, 2)
loss_f = nn.PoissonNLLLoss()
loss = loss_f(log_input, target)
print('\nloss: \n', loss)
KLDivLoss
torch.nn.KLDivLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
计算 input 和 target 之间的 KL 散度。
参数:
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值,平均值为element-wise 的,而不是针对样本的平均;为 False 时,返回是各样本各维度的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
注意事项:
要想获得真正的 KL 散度,需要如下操作:
- reduce = True ;size_average=False
- 计算得到的 loss 要对 batch 进行求平均
调用实例:
# coding: utf-8
import torch
import torch.nn as nn
import numpy as np
# ----------------------------------- KLDiv loss
loss_f = nn.KLDivLoss(size_average=False, reduce=False)
loss_f_mean = nn.KLDivLoss(size_average=True, reduce=True)
# 生成网络输出 以及 目标输出
output = torch.from_numpy(np.array([[0.1132, 0.5477, 0.3390]])).float()
output.requires_grad = True
target = torch.from_numpy(np.array([[0.8541, 0.0511, 0.0947]])).float()
loss_1 = loss_f(output, target)
loss_mean = loss_f_mean(output, target)
print('\nloss: ', loss_1)
print('\nloss_mean: ', loss_mean)
# 熟悉计算公式,手动计算样本的第一个元素的loss,注意这里只有一个样本,是 element-wise计算的
output = output[0].detach().numpy()
output_1 = output[0] # 第一个样本的第一个元素
target_1 = target[0][0].numpy()
loss_1 = target_1 * (np.log(target_1) - output_1)
print('\n第一个样本第一个元素的loss:', loss_1)
BCELoss
torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
二分类任务时的交叉熵计算函数。此函数可以认为是 nn.CrossEntropyLoss 函数的特例。其分类限定为二分类,y 必须是{0,1}。还需要注意的是,input 应该为概率分布的形式,这样才符合交叉熵的应用。所以在 BCELoss 之前,input 一般为 sigmoid 激活层的输出。
计算公式:
参数:
weight(Tensor)- 为每个类别的 loss 设置权值,常用于类别不均衡问题。
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
BCEWithLogitsLoss
torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’, pos_weight=None)
功能:
将 Sigmoid 与 BCELoss 结合,类似于 CrossEntropyLoss(将 nn.LogSoftmax()和 nn.NLLLoss()进行结合)。即 input 会经过 Sigmoid 激活函数,将 input 变成概率分布的形式。
计算公式:
参数:
weight(Tensor)- : 为 batch 中单个样本设置权值,If given, has to be a Tensor of size “nbatch”.
pos_weight-: 正样本的权重, 当 p>1,提高召回率,当 P<1,提高精确度。可达到权衡召回率(Recall)和精确度(Precision)的作用。 Must be a vector with length equal to the number of classes.
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True
MarginRankingLoss
torch.nn.MarginRankingLoss(margin=0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
计算两个向量之间的相似度,当两个向量之间的距离大于 margin,则 loss 为正,小于
margin,loss 为 0。
计算公式:
参数:
margin(float)- x1 和 x2 之间的差异。
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
HingeEmbeddingLoss
torch.nn.HingeEmbeddingLoss(margin=1.0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
折页损失的拓展,主要用于衡量两个输入是否相似。
参数:
margin(float)- 默认值为 1,容忍的差距。
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
MultiLabelMarginLoss
torch.nn.MultiLabelMarginLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
用于一个样本属于多个类别时的分类任务。
计算公式:
参数:
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False
时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
SmoothL1Loss
torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
计算平滑 L1 损失.
参数:
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
SoftMarginLoss
torch.nn.SoftMarginLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
计算二分类损失(和前面的BCELoss有什么区别未知)
参数:
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False
时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
MultiLabelSoftMarginLoss
torch.nn.MultiLabelSoftMarginLoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
SoftMarginLoss 多标签版本。
参数:
weight(Tensor)- 为每个类别的 loss 设置权值。weight 必须是 float 类型的 tensor,其长度要于类别 C 一致,即每一个类别都要设置有 weight。
CosineEmbeddingLoss
torch.nn.CosineEmbeddingLoss(margin=0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
衡量两个输入是否相似。
参数:
margin(float)- : 取值范围[-1,1], 推荐设置范围 [0, 0.5]
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
MultiMarginLoss
torch.nn.MultiMarginLoss(p=1, margin=1, weight=None, size_average=None, reduce=N
one, reduction=‘elementwise_mean’)
功能:
计算多分类的折页损失。
参数:
p(int)- 默认值为 1,仅可选 1 或者 2。
margin(float)- 默认值为 1
weight(Tensor)- 为每个类别的 loss 设置权值。weight 必须是 float 类型的 tensor,其长度要于类别 C 一致,即每一个类别都要设置有 weight。
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
TripletMarginLoss
torch.nn.TripletMarginLoss(margin=1.0, p=2, eps=1e-06, swap=False, size_average=None,reduce=None, reduction=‘elementwise_mean’)
功能:
计算三元组损失,人脸验证中常用。
参数:
margin(float)- 默认值为 1
p(int)- The norm degree ,默认值为 2
swap(float)–是否swap
size_average(bool)- 当 reduce=True 时有效。为 True 时,返回的 loss 为平均值;为 False时,返回的各样本的 loss 之和。
reduce(bool)- 返回值是否为标量,默认为 True。
边栏推荐
- 面试必问的HashCode技术内幕
- AntDB database appeared in the 24th high-speed exhibition, helping smart high-speed innovative applications
- 驱动上下游高效协同,跨境B2B电商平台如何释放LED产业供应链核心价值?
- What are the application advantages of SaaS management system?How to efficiently improve the digital and intelligent development level of food manufacturing industry?
- 腾讯云主机安全 x 轻量应用服务器|强强联合主机安全普惠版重磅发布
- Keras deep learning practice - traffic sign recognition
- 有点奇怪!访问目的网址,主机能容器却不行
- SENSORO成长伙伴计划 x 怀柔黑马科技加速实验室丨以品牌力打造To B企业影响力
- Hardware Bear Original Collection (Updated 2022/07)
- MySQL数据库————流程控制
猜你喜欢

MySQL数据库————流程控制

MySQL开发技巧——存储过程

网站建设流程

手撸代码,Redis发布订阅机制实现

MySQL数据库————存储过程和函数

力扣刷题之合并两个有序数组
![[Kapok] #Summer Challenge# Hongmeng mini game project - Sudoku (3)](/img/8d/4f5f7c2463b781cba1c68370d3c29c.png)
[Kapok] #Summer Challenge# Hongmeng mini game project - Sudoku (3)

Hardware Bear Original Collection (Updated 2022/07)

【pyqt5】自定义控件 实现能够保持长宽比地缩放子控件

odoo coding conventions (programming conventions, coding guidelines)
随机推荐
力扣刷题之移动零
Multi-Party Threshold Private Set Intersection with Sublinear Communication-2021:解读
Goldfish Brother RHCA Memoirs: CL210 manages OPENSTACK network -- network configuration options
When compiling a program with boost library with VS2013, it prompts fatal error C1001: An internal error occurred in the compiler
MLX90640 Infrared Thermal Imager Temperature Measurement Module Development Notes (Complete)
No need to crack, install Visual Studio 2013 Community Edition on the official website
modbus总线模块DAM-8082
ExcelPatternTool: Excel表格-数据库互导工具
英国伦敦大学|眼科强化学习:潜在应用和实施挑战
Library website construction source code sharing
【蓝桥杯选拔赛真题47】Scratch潜艇游戏 少儿编程scratch蓝桥杯选拔赛真题讲解
随时随地写代码--基于Code-server部署自己的云开发环境
请你说说多线程
app直播源码,点击搜索栏自动弹出下拉框
【周赛复盘】LeetCode第304场单周赛
[National Programming] "Software Programming - Lecture Video" [Zero Basic Introduction to Practical Application]
【神经网络】一文带你轻松解析神经网络(附实例恶搞女友)
如何看待腾讯云数据库负责人林晓斌借了一个亿炒股?
vtk体绘制代码报错的解决办法(代码在vtk7,8,9中都能运行),以及VTK数据集网站
C#/VB.NET 从PDF中提取表格