多标签分类与BCEloss(转)
多标签分类与BCEloss(转)
2019年12月9日 0条评论 1,325次阅读 0人点赞
什么是多标签分类
学习过机器学习的你,也许对分类问题很熟悉。比如下图:
图片中是否包含房子?你的回答就是有或者没有,这就是一个典型的二分类问题。
同样,是这幅照片,问题变成了,这幅照片是谁拍摄的?备选答案你,你的父亲,你的母亲?这就变成了一个多分类问题。
但今天谈论的多标签是什么呢?
如果我问你上面图包含一座房子吗?选项会是YES或NO。
你会发现图中所示的答案有多个yes,而不同于之前的多分类只有一个yes。
这里思考一下:
一首歌:如果你有四个类别的音乐,分别为:古典音乐、乡村音乐、摇滚乐和爵士乐,那么这些类别之间是互斥的。这首歌属于哪个类别?这是一个什么问题?
一首歌:如果你有四个类别的音乐,分别为:人声音乐、舞曲、影视原声、流行歌曲,那么这些类别之间并不是互斥的。这首歌属于哪个类别?这是一个什么问题?
多标签的问题的损失函数是什么
这里需要先了解一下softmax 与 sigmoid函数
这两个函数最重要的区别,我们观察一下:
区别还是很明显的。
综上,我们可以得出以下结论:
pytorch中的实现
PyTorch提供了两个类来计算二分类交叉熵(Binary Cross Entropy),分别是BCELoss() 和BCEWithLogitsLoss()
看一下源码,参考帮助,我们来玩一下
import torch
from torch import autograd
input = autograd.Variable(torch.randn(3,3), requires_grad = True)
print(input)
输出
tensor([[-0.2095, 0.3870, 0.3870],[ 0.0344, 0.2967, 1.2312],[-0.5740, -0.9555, -0.9694]], requires_grad=True)
Python Copy
因为Note that the targets t[i] should be numbers between 0 and 1.
所以需要先sigmoid
from torch import nn
m = nn.Sigmoid()
print(m(input))
Python Copy
输出
tensor([[0.4478, 0.5956, 0.5956],[0.5086, 0.5736, 0.7740],[0.3603, 0.2778, 0.2750]], grad_fn=<SigmoidBackward>)
Python Copy
假设你的target如下:
target = torch.FloatTensor([[0,1,1],[1,1,1],[0,0,0]])
print(target)
tensor([[0., 1., 1.],[1., 1., 1.],[0., 0., 0.]])
Python Copy
我们先根据源码中公式,
自己计算一下:
import math
r11 = 0 math.log(0.4478) + (1-0) math.log((1 - 0.4478))
r12 = 1 math.log(0.5956) + (1-1) math.log((1 - 0.5956))
r13 = 1 math.log(0.5956) + (1-1) math.log((1 - 0.5956))
r21 = 1 math.log(0.5086) + (1-1) math.log((1 - 0.5086))
r22 = 1 math.log(0.5736) + (1-1) math.log((1 - 0.5736))
r23 = 1 math.log(0.7740) + (1-1) math.log((1 - 0.7740))
r31 = 0 math.log(0.3603) + (1-0) math.log((1 - 0.3603))
r32 = 0 math.log(0.2778) + (1-0) math.log((1 - 0.2778))
r33 = 0 math.log(0.2750) + (1-0) math.log((1 - 0.2750))
r1 = -(r11 + r12 + r13) / 3
r2 = -(r21 + r22 + r23) / 3
r3 = -(r31 + r32 + r33) / 3
bceloss = (r1 + r2 + r3) / 3
print(bceloss)
输出
0.46801216818957675
Python Copy
核心解读
就是把每一个标签的预测值(sigmoid计算之后)交给cross_entropy函数来进行分类计算。比如样本1是一张图片(r1),r11代表某一个标签(有房子),r12代表某一个标签(有树), r13代表某一个标签(有小狗),最后r1就是样本1的预测值与真实值之间的loss。
我们再对比一下使用torch内置的loss函数
loss = nn.BCELoss()
print(loss(m(input), target) )
输出
tensor(0.4680, grad_fn=<BinaryCrossEntropyBackward>)
Python Copy
和我们自己算的误差非常小,可以忽略。
我们可以把sigmoid和bce的过程放到一起,使用内建的BCEWithLogitsLoss函数
loss = nn.BCEWithLogitsLoss()
print(loss(input,target))
Python Copy
输出
tensor(0.4680, grad_fn=<BinaryCrossEntropyWithLogitsBackward>)
Python Copy
参考
多标签分类与BCEloss
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
