NLLloss,KLDivLoss,CrossEntropyLoss三类损失函数比对

前置知识

这三个函数在深度学习模型中十分常见,尤其是在知识蒸馏领域,经常会将这三个函数进行比较

1、Softmax函数

softmax函数通常作为多分类以及归一化函数使用,其公式如下:
s o f t m a x ( x ) = e x i ∑ i = 1 e x i softmax(x)=\frac{e^{x_i}}{\sum_{i=1} e^{x_i}} softmax(x)=i=1exiexi
softmax函数有些重点的特点:

  • 所有经过softmax输出数值总和为1且大于0,这满足一个概率分布。这点很好理解,因为分母是个求和,所有分式分子加起来就会得到分母
  • 扩大化大小差距。这是由指数函数 e x e^x ex造成的,根据指数函数图像,自变量值 x x x越大,其因变量 y y y值增长的越快。可以看下面这个例子
x 1 2 3 4
softmax(x) 0.032 0.087 0.237 0.644

这就进一步带来一个问题,是否可以通过一个方法,使数之间差距没有那么大呢?这里我们使用了一个超参数温度T,来控制差距,公式如下:
s o f t m a x ( x , T ) = e x i t ∑ i = 1 e x i t softmax(x,T)=\frac{e^\frac {x_i}t}{\sum_{i=1} e^\frac {x_i}t} softmax(x,T)=i=1etxietxi
然后接着之前的例子,我们令T=0.5,1,2,4时,观察数据的变化。

T\x 1 2 3 4
0.5 0.002 0.016 0.117 0.865
1 0.032 0.087 0.237 0.644
2 0.101 0.167 0.276 0.455
4 0.165 0.212 0.272 0.350

可以发现随着 T T T的增大,不同类别之间的差距值越小(对负标签,即非正确标签关注度更高),但是大小关系并不改变。下图是另一个softmax值与温度的关系图。
请添加图片描述

2、log_softmax函数

log_softmax函数就是将softmax得到的输出值作为对数函数的输入值
l o g ( s o f t m a x ( x ) ) log(softmax(x)) log(softmax(x))

NLLLoss函数

NLLloss是衡量两者之间的差距,公式如下:
N L L l o s s ( p , q ) = − ∑ i = 1 q i l o g p i NLLloss(p,q)=-\sum_{i=1} q_ilogp_i NLLloss(p,q)=i=1qilogpi
这里涉及到信息熵的概念,小伙伴们可以通过我关于机器学习贝叶斯那一篇博客去了解。简单理解来说就是, p , q p,q p,q两者差距越大则最后损失函数值越大,负号的作用就是为了满足这个关系

CrossEntropyLoss函数

CrossEntropy函数又称交叉熵损失函数,其实公式表现形式和NLL损失函数一致,但是 p 、 q p、q pq具体含义不同,这里的 p 、 q p、q pq是要经过log_softmax的【在pytorch中】
C r o s s E n t r o p y L o s s ( p , q ) = − ∑ i = 1 q i l o g p i CrossEntropyLoss(p,q)=-\sum_{i=1} q_ilogp_i CrossEntropyLoss(p,q)=i=1qilogpi

KLDivLoss函数

KLDivLoss是用来判断两个分布的拟合/相似/匹配程度,假设现在有两个概率分布 P 、 Q P、Q PQ,它们的KL散度分别为:
D K L ( P ∣ ∣ Q ) = − ∑ i P ( i ) l n Q ( i ) P ( i ) = ∑ i P ( i ) l n P ( i ) Q ( i ) D K L ( p ∣ ∣ q ) = ∑ i p ( x i ) l n p ( x i ) q ( x i ) = ∑ i p ( x i ) [ l o g ( p ( x i ) ) − l o g ( q ( x i ) ) ] D_{KL}(P||Q)=-\sum_i P(i)ln\frac{Q(i)}{P(i)}=\sum_i P(i)ln\frac{P(i)}{Q(i)}\\ D_{KL}(p||q)=\sum_i p(x_i)ln\frac{p(x_i)}{q(x_i)}=\sum_i p(x_i)[log(p(x_i))-log({q(x_i)})] DKL(P∣∣Q)=iP(i)lnP(i)Q(i)=iP(i)lnQ(i)P(i)DKL(p∣∣q)=ip(xi)lnq(xi)p(xi)=ip(xi)[log(p(xi))log(q(xi))]
KLDivLoss适合用于连续分布的距离度量;并且对离散采用的连续输出空间分布进行回归通常很有用

NLLLoss与CrossEntropyLoss、KLDivLoss区别

NLLLoss与CrossEntropyLoss的区别在于一个log_softmax()函数,KLDivLoss与其它两者的区别在于其实两个KL散度之差再求和,而另外两者是求和(当然具体公式会有一定区别)

#NLLloss
def forward()
	x=self.fc2(x)
	x=F.log_softmax(x,dim=1)
return x

F.nll_loss()

#CrossEntropy
def forward()
	x=self.fc2(x)
return x

F.cross_entropy()

猜你喜欢

转载自blog.csdn.net/m0_61787307/article/details/131554799