阅读 81

人脸识别loss,solo

目录

一、softmax ()和log_softmax ) )。

二、CrossEntropyLoss ()和NLLLoss ) )。

softmax ()和log_softmax ()、CrossEntropyLoss ()、NLLLoss () )是我们深度学习中的常用函数或常见概念,平时大家都很熟悉。 我也习惯使用,没有对它们进行整体比较和分析。 下面我们对上述四个概念或函数进行比较和分析,以加深对一些基础知识的理解。

一. softmax (和log_softmax )softmax

softmax函数的计算方法:对于输入的各要素值,求出以自然常数e为底的指数,除以它们整体之和。 具体公式如下

log_softmax

其含义非常简单明确,是将softmax求出的值对数化一次。 计算公式如下。

请注意,softmax可以在值域压缩3354 [ 0,1 ]之间,并且它们的值可以为1。 这里的意思是有点概率的意思。 log_softmax将在softmax中压缩的值扩展在[-inf,0]之间。

这里再多说一点点就是在神经网络多分类任务中为何要使用softmax函数来进行归一化。很直观的解释就是它能平衡概率分布,避免其他归一化方法出现概率为0的问题。

虽然已经出现了具体的表现形式的不同,但是为什么在有了softmax之后还要设计log_softmax函数呢? 在应用场景中,对任务进行分类时需要计算损失,但这一系列流程包括softmax ()函数的规范化过程和对规范化值进行对数化的操作。 另外,softmax必然存在一定的缺陷和问题,为了克服这些缺陷和问题,设计了log_softmax。

softmax的数值计算问题

使用softmax函数时,高概率不会出现数值计算问题。 仅当输入x的绝对值为较大值时,数值计算问题才会出现。 如果x为较大的正值,则在softmax中发生溢出的问题——是程序在计算过程中首先计算分子上的exp(x )。 如果x是非常大的正值,如果程序的数据类型float或double不能表示,则会报告错误; 如果x是极小的负值,exp(x )接近0,则程序将标记为0,如果所有x都是极小的负值,分母整体标记为0,则在运算过程中会出现错误——。

log_softmax

为了解决上述softmax的数值计算问题,设计了log_softmax。 当然,从公式直接看,log_softmax=Xi-log([exp(Xi ) ] )。 这里还没有解决上溢和下溢的问题。 学者们设计了一个聪明的方法:

通过设计: m是输入Xi中的最大值。 这样,log_softmax被变换为图像中的公式、蓝色框中的。 可能溢出的问题出现在红框中的公式中。 简单地分析,在xi为正情况下,xi-M都不会出现大于0的数字,因此溢出问题得到解决; xi-M都是较大的负值,但一定有xi-M==0。 这保证了红框的一个表达式与log(x )等价,其中如果x1且不是大数字) x接近0,则log(x )接近负无穷大时会发生溢出问题)。 这样就解决了下溢问题。

当然,如果这样操作,在计算过程中log_softmax和log(softmax )会有一定的差异。

验证softmax和log_softmax

直接模拟分类器,上传代码:

importtorchimporttorch.nnasnnimporttorch.optimasoptimimporttorch.nn.functional ASF # 设置随机种子保证重复性torch.manual_seed(1)的if _ name _=' _ main _ ' : classifier=nn.linear (4,2 ) embedding s

') print(softmax) print('*'*100) #验证概率为1 softmax_sum = torch.einsum('ij -> i',[softmax]) print('softmax_sum验证概率为1') print(softmax_sum) print('*'*100) log_softmax = torch.log(softmax) print('log(softmax)') print(log_softmax) print('*'*100) logsoftmax = F.log_softmax(output,dim=1) print('logsoftmax') print(logsoftmax) print('*'*100) #验证log(softmax)和logsoftmax是否相等 print('验证log(softmax)和logsoftmax是否相等') print(torch.equal(log_softmax,logsoftmax)) print(torch.equal(log_softmax.half(),logsoftmax.half()))

结果如下:


可以得出:

1、softmax确实进行了归一化

2、log(softmax)和log_softmax()在pytorch实现下,并不完全相等的。(代码中float32精度下就不想等,而float16——也就是half()下是相等的)

log_softmax的优势就是计算过程更加平稳,不会出现溢出问题,同时相比如先softmax然后在log两次操作更加的方便和快速。

二、CrossEntropyLoss()和NLLLoss()

这里讨论都是基于pytorch框架下实现的损失函数。

CrossEntropyLoss()

首先看看CrossEntropyLoss()函数的计算公式:


从pytorch官网API文档中可以看到CrossEntropyLoss()就是对网络的输出先做了softmax操作,然后再取对数。那么交叉熵损失到底度量的是一个什么东西?

信息量:它是用来衡量一个事件的不确定性的。一个事件发生的概率越大,不确定性越小,则它所携带的信息量就越小;事件发生的概率越小,不确定性就越大,信息量就越大。则信息量定义为:I(x) = -log[p(x)]。

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

交叉熵:它主要刻画的是实际输出(概率)与期望输出(概率)的差异,也就是交叉熵的值越小,两个概率分布就越接近。

NLLLoss

NLLLoss的具体描述如下:


negative log likelihood loss——可以看到就是对网络输出取了一个负号——负对数似然损失——这里并没有进行取对数,具体怎么形容它的含义没想到合适的描述——刻画的是输出与实际的相异性?

这两个函数一般都是用在分类任务中的,CrossEntropyLoss()等价于log_softmax()+NLLLoss()——pytorch框架实现都是一模一样的。另外单独使用NLLLoss损失函数的任务我还没有接触到过,后续有机会接触到了再来更新。

下面对CrossEntropyLoss()和log_softmax()+NLLLoss()进行简单的验证,上代码:

import torchimport torch.nn as nnimport torch.optim as optimimport torch.nn.functional as F#设置随机种子保证复现性torch.manual_seed(1)if __name__ == '__main__': #把batch内的每个样本的loss都分别记录下来 criterion = nn.CrossEntropyLoss(reduction='none') criterion1 = nn.NLLLoss(reduction='none') criterion_mean = nn.CrossEntropyLoss() classifier = nn.Linear(4,2) embeddings = torch.randn((2,4)) output = classifier(embeddings) label = torch.tensor([1,0],dtype=torch.long) entropy_loss = criterion(output,label) print('entropy_loss',entropy_loss) print('*'*100) log_softmax = F.log_softmax(output,dim=1) print('log_softmax',log_softmax) nll_loss = criterion1(log_softmax,label) print('nll_loss',nll_loss) print('*'*100) entropy_loss_mean = criterion_mean(output,label) print('entropy_loss_mean',entropy_loss_mean) print('*'*100) print('entropy_loss mena',entropy_loss.mean())

上面的代码比较简单,分别进行了CrossEntropyLoss和CrossEntropyLoss——batch平均以及NLLLoss损失的计算,结果如下图


可以看到entropy_loss的值和nll_loss的值是一样的;同时最后的均值验证显示,reduction系数默认的mean计算的结果确实是正确的——(0.9203+1.1605)/2 =1.0404;最后NLLlos的结果显示,就是在log_softmax得到的结果对对应的label一样的index处的值取负号。

 

以上就是这次博文的全部内容了,softmax确实是一个很好的归一化方法,能够把一组值归一化为一组概率分布;log_softmax则解决了softmax出现的数值溢出问题;在计算神经网络的损失的时候,log_softmax可以全部替换掉softmax,尤其是在CrossEntropyLoss和NLLLoss进行分类任务的时候;还有一个重要的结论就是CrossEntropyLoss()等价于F.log_softmax()+NLLLoss()。

 

 

log_softmax与softmax的区别在哪里?

Pytorch常用的交叉熵损失函数CrossEntropyLoss()详解


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐