BCELoss和BCEWithLogitsLoss怎么在Pytorch中使用
BCELoss和BCEWithLogitsLoss怎么在Pytorch中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
BCELoss
在图片多标签分类时,如果3张图片分3类,会输出一个3*3的矩阵。
先用Sigmoid给这些值都搞到0~1之间:
假设Target是:
下面我们用BCELoss来验证一下Loss是不是0.7194!
emmm应该是我上面每次都保留4位小数,算到最后误差越来越大差了0.0001。不过也很厉害啦哈哈哈哈哈!
BCEWithLogitsLoss
BCEWithLogitsLoss就是把Sigmoid-BCELoss合成一步。我们直接用刚刚的input验证一下是不是0.7193:
嘻嘻,我可真是太厉害啦!
补充:Pytorch中BCELoss,BCEWithLogitsLoss和CrossEntropyLoss的区别
BCEWithLogitsLoss = Sigmoid+BCELoss
当网络最后一层使用nn.Sigmoid时,就用BCELoss,当网络最后一层不使用nn.Sigmoid时,就用BCEWithLogitsLoss。
(BCELoss)BCEWithLogitsLoss
用于单标签二分类或者多标签二分类,输出和目标的维度是(batch,C),batch是样本数量,C是类别数量,对于每一个batch的C个值,对每个值求sigmoid到0-1之间,所以每个batch的C个值之间是没有关系的,相互独立的,所以之和不一定为1。
每个C值代表属于一类标签的概率。如果是单标签二分类,那输出和目标的维度是(batch,1)即可。
CrossEntropyLoss用于多类别分类
输出和目标的维度是(batch,C),batch是样本数量,C是类别数量,每一个C之间是互斥的,相互关联的,对于每一个batch的C个值,一起求每个C的softmax,所以每个batch的所有C个值之和是1,哪个值大,代表其属于哪一类。如果用于二分类,那输出和目标的维度是(batch,2)。
补充:Pytorch踩坑记之交叉熵(nn.CrossEntropy,nn.NLLLoss,nn.BCELoss的区别和使用)
在Pytorch中的交叉熵函数的血泪史要从nn.CrossEntropyLoss()这个损失函数开始讲起。
从表面意义上看,这个函数好像是普通的交叉熵函数,但是如果你看过一些Pytorch的资料,会告诉你这个函数其实是softmax()和交叉熵的结合体。
然而如果去官方看这个函数的定义你会发现是这样子的:
哇,竟然是nn.LogSoftmax()和nn.NLLLoss()的结合体,这俩都是什么玩意儿啊。再看看你会发现甚至还有一个损失叫nn.Softmax()以及一个叫nn.nn.BCELoss()。我们来探究下这几个损失到底有何种关系。
nn.Softmax和nn.LogSoftmax
首先nn.Softmax()官网的定义是这样的:
嗯...就是我们认识的那个softmax。那nn.LogSoftmax()的定义也很直观了:
果不其然就是Softmax取了个log。可以写个代码测试一下:
import torchimport torch.nn as nn a = torch.Tensor([1,2,3])#定义Softmaxsoftmax = nn.Softmax()sm_a = softmax=nn.Softmax()print(sm)#输出:tensor([0.0900, 0.2447, 0.6652]) #定义LogSoftmaxlogsoftmax = nn.LogSoftmax()lsm_a = logsoftmax(a)print(lsm_a)#输出tensor([-2.4076, -1.4076, -0.4076]),其中ln(0.0900)=-2.4076
nn.NLLLoss
上面说过nn.CrossEntropy()是nn.LogSoftmax()和nn.NLLLoss的结合,nn.NLLLoss官网给的定义是这样的:
The negative log likelihood loss. It is useful to train a classification problem with C classes
负对数似然损失 ,看起来好像有点晦涩难懂,写个代码测试一下:
import torchimport torch.nn a = torch.Tensor([[1,2,3]])nll = nn.NLLLoss()target1 = torch.Tensor([0]).long()target2 = torch.Tensor([1]).long()target3 = torch.Tensor([2]).long() #测试n1 = nll(a,target1)#输出:tensor(-1.)n2 = nll(a,target2)#输出:tensor(-2.)n3 = nll(a,target3)#输出:tensor(-3.)
看起来nn.NLLLoss做的事情是取出a中对应target位置的值并取负号,比如target1=0,就取a中index=0位置上的值再取负号为-1,那这样做有什么意义呢,要结合nn.CrossEntropy往下看。
nn.CrossEntropy
看下官网给的nn.CrossEntropy()的表达式:
看起来应该是softmax之后取了个对数,写个简单代码测试一下:
import torchimport torch.nn as nn a = torch.Tensor([[1,2,3]])target = torch.Tensor([2]).long()logsoftmax = nn.LogSoftmax()ce = nn.CrossEntropyLoss()nll = nn.NLLLoss() #测试CrossEntropyLosscel = ce(a,target)print(cel)#输出:tensor(0.4076) #测试LogSoftmax+NLLLosslsm_a = logsoftmax(a)nll_lsm_a = nll(lsm_a,target)#输出tensor(0.4076)
看来直接用nn.CrossEntropy和nn.LogSoftmax+nn.NLLLoss是一样的结果。为什么这样呢,回想下交叉熵的表达式:
其中y是label,x是prediction的结果,所以其实交叉熵损失就是负的target对应位置的输出结果x再取-log。这个计算过程刚好就是先LogSoftmax()再NLLLoss()。
------------------------------------
所以我认为nn.CrossEntropyLoss其实应该叫做softmaxloss更为合理一些,这样就不会误解了。
nn.BCELoss
你以为这就完了吗,其实并没有。还有一类损失叫做BCELoss,写全了的话就是Binary Cross Entropy Loss,就是交叉熵应用于二分类时候的特殊形式,一般都和sigmoid一起用,表达式就是二分类交叉熵:
直觉上和多酚类交叉熵的区别在于,不仅考虑了的样本,也考虑了的样本的损失。
pytorch的优点
1.PyTorch是相当简洁且高效快速的框架;2.设计追求最少的封装;3.设计符合人类思维,它让用户尽可能地专注于实现自己的想法;4.与google的Tensorflow类似,FAIR的支持足以确保PyTorch获得持续的开发更新;5.PyTorch作者亲自维护的论坛 供用户交流和求教问题6.入门简单
看完上述内容,你们掌握BCELoss和BCEWithLogitsLoss怎么在Pytorch中使用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341