(pytorch进阶之路)交叉熵、信息熵、二分类交叉熵、负对数似然、KL散度、余弦相似度

CE loss

torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=- 100, reduce=None, reduction='mean', label_smoothing=0.0)

weight:权重,对不同类别均衡
ignore_index:目标为igonre_index的话不纳入loss值中

CE loss 一般用在分类任务中

交叉熵:用一个分布去衡量另外一个分布所需要的bit数目
H(p,q) = - ∑ p(x) log(q(x))

p(x)一般为1,one-hot的形式,只在一个概率上为1,其他位置为0,因此p(x)对应着1,其他0位置的地方就不做计算了,q(x)对应模型预测到那个类别的概率
在这里插入图片描述

知识蒸馏和暗标签,大模型预测出的结果作为小模型的输入,这个分布就不是1分布的one-hot标签了。此时的公式计算就是要对所有的类别做计算
在这里插入图片描述
关于reduction参数是是否做平均,有mean和sum
在这里插入图片描述

C是class,类别数目
调用传入input [C],[N,C] , [N,C,…] 时空维放后面比如C后面依次是H,W,channel,T,把分类维度C放在第二维度,后面的维度多少维都没问题,注意这里的input是未归一化的,也就是没有进行softmax

target可以传入一个整型,一个类别的标签,如果输入是[N,C],则传入[N],如果输入传入的是[N,C,…] ,则target为[N,…],target少了C ,此时target是delta目标分布

target传入的值域是在0到C-1之间,当然也可以设置成input一样的形状,比如在知识蒸馏和暗标签的时候,不过这个时候的值域是在0到1之间的浮点型

import torch
import torch.nn as nn
import torch.nn.functional as F

bs = 2
num_class = 4

logits = torch.randn(bs, num_class)
target_logits = torch.randn(bs, num_class)
target = torch.randint(num_class, size=[bs, ])

# 调用ce loss
ce_loss_fn = nn.CrossEntropyLoss()
ce_loss = ce_loss_fn(logits, target)
print(f"cross entropy loss:{ce_loss}")
ce_loss = ce_loss_fn(logits, torch.softmax(target_logits, dim=-1))
print(f"cross entropy loss:{ce_loss}")

负对数似然

NLL Loss

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

调用的参数基本和CELoss一致

如果用NLL forward函数调用的话,input是包含每个类别的对数概率,是做了对数化的

target是类别的索引,值域在0到C-1之间,target不提供浮点型的输入,因此target的维度始终比输入少一维

计算公式:
xn就是对数化数据,weight乘以1函数delta分布
在这里插入图片描述

nll_loss_fn = nn.NLLLoss()
# 因为nll要输入的是归一化后的对数logits,对最后一维做softmax和log
nll_loss = nll_loss_fn(torch.log(torch.softmax(logits, dim=-1) + 1e-7), target_index)
print(f"negative log-likelihood loss: {nll_loss}")

发现它的结果CE loss几乎一致,那么CE和NLL之间可以根据网络自行选择损失函数

KL散度

kullback leibler divergence 预测分布与目标分布距离的度量
torch.nn.KLDivLoss(size_average=None, reduce=None, reduction='mean', log_target=False)
交叉熵 = 信息熵 + KL散度

参数log_target:如果target是log形式的化把它置为True

KL散度的公示:L(y_pred, y_true) = Dkl(y_true,y_pred)
在这里插入图片描述

input可以是任意的维度,target和input一样的形状
为防止下溢的问题,input期望是log空间传入进来的,target可以是log空间也可以是线性空间

CE = IE + KL

做机器学习的时候,用CE和kld其实是一样的,因为IE传入的target分布是一个one-hot分布,熵其实为0,如果是非delta分布计算出的结果也是一个常数,对参数更新没有任何贡献


# 验证CE = IE + KL
print("=" * 100)
ce_loss_fn_sample = nn.CrossEntropyLoss(reduction='none')
ce_loss_sample = ce_loss_fn_sample(logits, torch.softmax(target_logits, dim=-1))
print("ce_loss_sample: ", ce_loss_sample)

kl_loss_fn_sample = nn.KLDivLoss(reduction='none')
kld_loss_sample = kl_loss_fn_sample(torch.log(torch.softmax(logits, dim=-1)),
                                    torch.softmax(target_logits, dim=-1)).sum(-1)
print("kld_loss_sample: ", kld_loss_sample)

target_info_entropy = torch.distributions.Categorical(
    probs=torch.softmax(target_logits, dim=-1))\
    .entropy()

print("target_info_entropy:",  target_info_entropy)

print(torch.allclose(ce_loss_sample, target_info_entropy + kld_loss_sample))

BCE loss

二分类loss binary cross entropy
公式相当熟悉了
torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')

yn目标分布,xn是预测分布,BCE Loss的一般形式就是NLL loss
在这里插入图片描述
target y在0到1之间,这里输入的input是一个类别的标量

# bce loss
bce_loss_fn = torch.nn.BCELoss()
logits = torch.randn(bs)
prob_1 = torch.sigmoid(logits)
target = torch.randint(2, size=(bs, ))
bce_loss = bce_loss_fn(prob_1, target.float())
print(f"bce: {bce_loss}")

# 用NLL代替BCE
prob_0 = 1 - prob_1.unsqueeze(-1)
# 传入的是完整的概率
prob = torch.cat([prob_0, prob_1.unsqueeze(-1)], dim=-1)
# 传入的是对数的概率,
nll_loss_binary = nll_loss_fn(torch.log(prob), target)
print(nll_loss_binary)

COSINEEMBEDDINGLOSS

torch.nn.CosineEmbeddingLoss(margin=0.0, size_average=None, reduce=None, reduction='mean')

余弦相似度loss 一般是用在自监督学习,对比学习,做相似度匹配

如图片检索,找到top100相似图片,用预训练模型算出每张图片的向量表征,用query图片和每张图片做余弦相似度
在这里插入图片描述

y只能为1或者-1

# Cos Similarity loss
cos_loss_fn = nn.CosineEmbeddingLoss()
v1 = torch.randn(bs, 512)
v2 = torch.randn(bs, 512)
target = torch.randint(2, size=(bs, )) * 2 - 1  # [0,1] * 2 -1 = -1和1
cos_loss = cos_loss_fn(v1, v2, target)
print(f"cos_loss:{cos_loss }")

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
交叉损失函数和对数然损失函数是在机器学习中常用的损失函数,用于衡量模型输出与真实标签之间的差异。 交叉损失函数是一种常用的分类问题损失函数。它通过计算模型输出的概率分布与真实标签的概率分布之间的交叉来衡量两者的差异。在pytorch中,可以使用torch.nn.CrossEntropyLoss()函数来计算交叉损失。这个函数会同时计算softmax函数和交叉,所以输入的模型输出不需要经过softmax函数处理。 对数然损失函数是一种常用的用于最大然估计的损失函数。在二分类问题中,假设模型的输出是一个介于0和1之间的概率值,表示为θ。对数然损失函数可以用来衡量模型输出θ与真实标签0或1之间的差异。当模型输出θ接近1时,即模型预测为正例时的概率较大,对数然损失函数的值较小;当模型输出θ接近0时,即模型预测为例时的概率较大,对数然损失函数的值也较小。在pytorch中,可以使用torch.nn.functional.nll_loss()函数来计算对数然损失。 综上所述,交叉损失函数和对数然损失函数都是用来衡量模型输出与真实标签之间的差异的常用损失函数。交叉损失函数适用于分类问题,而对数然损失函数适用于二分类问题。在实际应用中,根据具体的问题和需求选择合适的损失函数来训练模型。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [损失函数-对数然和交叉(Pytorch中的应用)](https://blog.csdn.net/tcn760/article/details/123910565)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [15/4/2022交叉损失函数和对数然损失](https://blog.csdn.net/weixin_44228389/article/details/124202843)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值