交叉熵nn.CrossEntropyLoss()和nn.BCELoss()

交叉熵

用于判定实际的输出(概率)和期望的输出(概率)的接近程度(距离)。

交叉熵的值越小,两个概率分布就越接近。

相关概念

信息量:用于衡量一个事件的不确定性。一个事件发生的概率越大,不确定性越小,则它所携带的信息量就越小。如“骰子这次投出的点数小于10”这句话本身不含信息量。

假设 x x x是一个离散型随机变量,其取值集合为X,概率分布函数为 p ( x ) = P ( X = x ) , x ∈ X p(x)=P(X=x),x\in X p(x)=P(X=x),xX ,我们定义事件 X = x 0 X=x_0 X=x0 的信息量为: I ( x 0 ) = − log ⁡ ( p ( x 0 ) ) I(x_0)=−\operatorname{log}(p(x_0)) I(x0)=log(p(x0))

:用来衡量一个系统的混乱程度的,代表一个系统中信息量的总和;信息量总和越大,表明这个系统不确定性就越大。

计算公式

假设概率分布p为期望输出,概率分布q为实际输出,H(p, q)为交叉熵,则:

H ( p , q ) = − Σ x ( p ( x ) log ⁡ ( q ( x ) ) + ( 1 − p ( x ) ) log ⁡ ( 1 − q ( x ) ) ) H(p, q)=-\Sigma_x (p(x)\operatorname{log}(q(x))+(1-p(x))\operatorname{log}(1-q(x))) H(p,q)=Σx(p(x)log(q(x))+(1p(x))log(1q(x)))

torch.nn.CrossEntropyLoss()

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

在pytorch中,使用了交叉熵的一半进行计算[不影响结果大小的比较]: − Σ x p ( x ) log ⁡ q ( x ) -\Sigma_x p(x)\operatorname{log}q(x) Σxp(x)logq(x)
l o s s ( y ^ , t ) = − Σ i w i ( y i log ⁡ ( y ^ i ) ) n loss(\hat{y},t)=-\frac{\Sigma_i w_i (y_i\operatorname{log}(\hat{y}_i))}{n} loss(y^,t)=nΣiwi(yilog(y^i))

其中 y ^ \hat{y} y^是网络的输出向量,t是其对应的真实标签(int),n为batch_num

交叉熵损失函数专门用于处理one-hot型 (prediction) y_hat值对应的int型 (label) 目标值t多分类问题。

意思是,一个设计良好的模型经过训练后,理想状态下,最终结果应为y_hat[i==t]=1,y_hat[i!=t]=0

从数学的角度理解交叉熵损失函数

对于分类问题来说:

one-hot型prediction: y ^ \hat{y} y^

int型label: t t t,转换为one-hot型label: y y y,则有 y t = 1 y_t=1 yt=1,向量y的其余元素为0

从目前预测出的情况中获得期望的label输出的可能性是: Π i y ^ i y i \Pi_i\hat{y}_i^{y_i} Πiy^iyi

  1. 我们希望这个可能性越大越好
  2. 为了计算方便(将连乘转换为累加)且保证函数的单调性,我们取个log

我们求的是: arg ⁡ max ⁡ Σ i y i log ⁡ y ^ i = arg ⁡ min ⁡ − Σ i y i log ⁡ y ^ i \arg \max{\Sigma_i y_i \operatorname{log}\hat{y}_i}=\arg \min{-\Sigma_i y_i \operatorname{log}\hat{y}_i} argmaxΣiyilogy^i=argminΣiyilogy^i

又因为由int型label转化成的one-hot型向量只有一个元素值为1,其余元素值都为0

所以上式可化简为: arg ⁡ min ⁡ − log ⁡ y ^ t \arg \min{-\operatorname{log}\hat{y}_t} argminlogy^t

实现原理

这个损失函数其实是结合nn.LogSoftmax()nn.NLLLoss()两个函数

Softmax是让数值之和为1,符合概率分布的特性

nn.NLLLoss()(input, target)
# 在分类问题上,shape如下:
input: (batch_num, classes_num)
target: (batches_num)

# 有时我们想对图片做nn.CrossEntropyLoss(),shape如下:
# 如果这是一张2D图片,shape为(d1, d2)
# 比如说,我们去学一个图片pixel的二分类问题(该pixel是否属于Edge)
input: (batch_num, class_num, d1, d2)
target: (batches_num, d1, d2)
  1. 将int型target转化为one-hot编码y
  2. − Σ i y i × input i -\Sigma_i y_i\times \text{input}_i Σiyi×inputi
例子

one-hot型prediction: predition=[0.1, 0.1, 0.8]

int型label: 2 先转化为one-hot类型 => label=[0, 0, 1]

在这里插入图片描述

Loss = − ( 0 ∗ log ⁡ 0.1 + 0 ∗ log ⁡ 0.1 + 1 ∗ log ⁡ 0.8 ) = − 1 ∗ log ⁡ 0.8 \text{Loss}=-(0*\operatorname{log}0.1+0*\operatorname{log}0.1+1*\operatorname{log}0.8)=-1*\operatorname{log}0.8 Loss=(0log0.1+0log0.1+1log0.8)=1log0.8

# # 用代码细写出这个等价形式
import torch.nn as nn

input = torch.rand(3, 3) # predition
target = torch.tensor([0, 1, 2]) # shape=(3) # label

# 直接用nn.CrossEntropyLoss函数
criterion_entropy = nn.CrossEntropyLoss()
loss = criterion_entropy(input, target)

# 拆解成分步计算的形式
input = nn.LogSoftmax(dim=1)(input)
loss = nn.NLLLoss()(input, target)

torch.nn.BCELoss

torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction='mean')
计算公式

在pytorch中,使用了交叉熵进行计算: − Σ x ( p ( x ) log ⁡ ( q ( x ) ) + ( 1 − p ( x ) ) log ⁡ ( 1 − q ( x ) ) ) -\Sigma_x (p(x)\operatorname{log}(q(x))+(1-p(x))\operatorname{log}(1-q(x))) Σx(p(x)log(q(x))+(1p(x))log(1q(x)))
l o s s ( y ^ , t ) = − Σ i w i [ y i log ⁡ ( y ^ i ) + ( 1 − y i ) log ⁡ ( 1 − y ^ i ) ] n loss(\hat{y},t)=-\frac{\Sigma_i w_i [y_i\operatorname{log}(\hat{y}_i)+(1-y_i)\operatorname{log}(1-\hat{y}_i)]}{n} loss(y^,t)=nΣiwi[yilog(y^i)+(1yi)log(1y^i)]

其中 y ^ \hat{y} y^是网络的输出向量,t是其对应的真实标签(int),n=batch_num

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: nn.BCELoss()和nn.CrossEntropyLoss()是PyTorch库中常用的损失函数。 nn.BCELoss()是二分类问题中使用的二元交叉熵损失函数。这个函数适用于输出数据为概率值的情况,如sigmoid函数输出的概率值。它计算每个样本的损失然后对它们取平均值。BCE代表二元交叉熵(binary cross entropy)。这个损失函数可以反映模型预测结果与真实标签之间的差距,并帮助模型通过梯度下降来更新网络参数,使得预测结果与真实标签尽可能接近。 nn.CrossEntropyLoss()是多分类问题中使用的交叉熵损失函数。这个函数适用于输出数据为类别索引的情况,如使用softmax函数进行多分类任务的结果。它将模型预测的概率分布与真实标签之间的差异转化为一个标量损失值。CrossEntropy代表交叉熵损失,它将每个样本的预测概率与真实标签对应位置的真实概率进行比较,并对它们进行求和然后取平均。这个损失函数可以帮助模型学习到正确的类别预测,使得预测的概率分布与真实标签的概率分布尽可能接近。 综上所述,nn.BCELoss()适用于二分类问题,计算模型输出概率值与真实标签之间的差异;而nn.CrossEntropyLoss()适用于多分类问题,计算模型输出概率分布与真实标签之间的差异。 ### 回答2: nn.BCELoss()和nn.CrossEntropyLoss()都是PyTorch中用于计算损失函数的类。 nn.BCELoss()是二分类问题中使用的损失函数,用于计算二分类交叉熵损失。它将模型的输出与目标标签进行比较,并计算每个样本的二进制交叉熵损失。如果目标标签是正类,则损失函数会惩罚模型输出为负类的程度,反之亦然。nn.BCELoss()常用于二分类任务中,例如图像分类中的两类分割、异常检测等。 nn.CrossEntropyLoss()则用于多分类问题中,计算多分类交叉熵损失。它接受模型的输出和目标标签,并计算每个样本的交叉熵损失。在多分类问题中,目标标签需用One-Hot编码或整数类型表示。nn.CrossEntropyLoss()会将模型输出进行softmax处理,再与目标标签进行比较,计算交叉熵损失。它对于多分类问题是常用的损失函数。 总结: 1. nn.BCELoss()适用于二分类问题,计算二分类交叉熵损失。 2. nn.CrossEntropyLoss()适用于多分类问题,计算多分类交叉熵损失。 两者主要区别在于输入形式和模型输出的处理方式。 ### 回答3: nn.BCELoss()和nn.CrossEntropyLoss()都是PyTorch框架中常用的损失函数。它们的差异在于应用的场景和处理方式不同。 nn.BCELoss()是二分类问题的损失函数,适用于输出为概率值的情况。它的全称是Binary Cross Entropy Loss,用于衡量模型输出的概率与真实标签之间的差异。该损失函数采用式子:Loss = -[y*log(x) + (1-y)*log(1-x)],其中y是真实标签,x是模型输出的概率。nn.BCELoss()常用于输出值为0或1的二分类任务,比如判断图像中是否包含某个物体。 nn.CrossEntropyLoss()是多分类问题的损失函数,适用于输出为类别的情况。它的全称是Cross Entropy Loss,用于衡量模型输出的类别预测值与真实标签之间的差异。该损失函数采用式子:Loss = -[y*log(x)],其中y是真实标签的类别索引,x是模型输出的类别概率分布。nn.CrossEntropyLoss()将分类问题转化为一个概率分布的差异度量,常用于多分类任务,比如图像分类、文本分类等。 两者之间的区别主要在于输入形式和问题类型不同。nn.BCELoss()适用于二分类问题,输出为概率值;nn.CrossEntropyLoss()适用于多分类问题,输出为类别。同时需要注意的是,对于二分类问题,可以使用nn.CrossEntropyLoss()代替nn.BCELoss(),只是需要设置输出类别为2。而对于多分类问题,如果输出为概率值,则可以使用nn.BCELoss(),但需要将输出进行二值化处理。 综上所述,nn.BCELoss()和nn.CrossEntropyLoss()是PyTorch框架中常用的损失函数,用于不同类型的分类问题。根据具体的问题和输出类型,选择合适的损失函数可以提高模型训练的效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值