BCE(Binary CrossEntropy)损失函数
图像二分类问题—>多标签分类
二分类是每个AI初学者接触的问题,例如猫狗分类、垃圾邮件分类…在二分类中,我们只有两种样本(正样本和负样本),一般正样本的标签y=1,负样本的标签y=0。比如下边这张图片,判断里边有没有人。
那么这张图片的标签为y=1,这时我们就根据标签y=1来设计模型的输出就行了。因为二分类只有正样本和负样本,并且两者的概率之和为1,所以不需要预测一个向量,只需要输出一个概率值就好了。损失函数一般是输出经过sigmoid激活函数之后,采用交叉熵损失函数计算LOSS,即
L
O
S
S
=
−
(
y
l
o
g
(
p
(
x
)
+
(
1
−
y
)
l
o
g
(
1
−
p
(
x
)
)
LOSS=-(ylog(p(x)+(1-y)log(1-p(x))
L
O
S
S
=
−
(
y
l
o
g
(
p
(
x
)
+
(
1
−
y
)
l
o
g
(
1
−
p
(
x
)
)
其中p(x)是模型输出,y是真实标签。
Sigmoid和Softmax的本质及其相应的损失函数和任务
我看到过的关于Sigmoid激活函数和Softmax函数的比较好的解释,分享给大家:
看到上边的解释,我们应该心里会有些许明朗。为何二分类采用Sigmoid激活函数和BCE损失函数;多分类,我们可以采用Softmax激活函数和多类别交叉熵损失函数。;对于多标签分类,采用Sigmoid激活函数和BCE损失函数了。
在这里不禁感慨,深度学习也不完全是炼丹,损失函数、激活函数、模型结构等都是大牛们结合统计学和目标场景设计的。
多标签分类任务的损失函数BCE
现在我换一个问题,这张图片中有没有人,有没有手机(多标签分类),那这时的标签就有四种情况了:
标签 | 含义 |
---|---|
(0, 0) | 图中既没人,也没手机 |
(0, 1) | 图中没人,但是有手机 |
(1, 0) | 图中有人,但是没手机 |
(1, 1) | 图中既有人,也有手机 |
以此类推,还可以扩展到
2
n
2^n
2
n
种情况(n类别分类)。很明显,问题已经由普通的二分类变成了多标签分类。多标签分类问题的输出和损失函数应该怎么定义呢?
因为多标签分类中有多个类别,不能单纯的输出一个值,而是应该输出一个向量,并且也不能继续将输出简单的用Softmax归一化到[0, 1]的概率值,且各类别的概率相加为1。**因为各类别之间不是互斥的,允许同时出现。**我们可以用sigmoid激活函数分别将输出向量的每个元素转换为概率值。
对于损失函数,比较简单的思路就是对输出向量的每个元素单独使用交叉熵损失函数,然后计算平均值。
这就是我们今天要说的BCE
。看一下Pytorch官方源码的实现方式就知道了。
Pytorch的BCE代码和示例
举个例子,假如模型输出
>>> import torch
>>> output = torch.randn(3,3)
>>> output
tensor([[-0.8858, 0.3241, 0.9456],
[ 1.4887, 1.8076, -0.0565],
[-1.6529, -1.8539, 0.6756]])
首先将输出向量中的所有元素转换为[0, 1]之间的概率值
>>> active_func = nn.Sigmoid()
>>> output = active_func(output)
>>> output
tensor([[0.2920, 0.5803, 0.7202],
[0.8159, 0.8591, 0.4859],
[0.1607, 0.1354, 0.6627]])
假设输入数据对应的标签为
>>> target = torch.FloatTensor([[0,1,1],[1,1,1],[0,0,0]])
>>> target
tensor([[0., 1., 1.],
[1., 1., 1.],
[0., 0., 0.]])
使用BCE损失函数计算LOSS
>>> loss = nn.BCELoss()
>>> loss = loss(output, target)
>>> loss
tensor(0.4114)
总结
经过上边的分析,BCE主要适用于二分类的任务,而且多标签分类任务可以简单地理解为多个二元分类任务叠加。所以BCE经过简单修改也可以适用于多标签分类任务。使用BCE之前,需要将输出变量量化在[0,1]之间(可以使用Sigmoid激活函数)。上边我们也深度刨析了Sigmoid和Softmax两种激活函数,探究其统计学本质,Sigmoid的输出为伯努利分布,也就是我们常说的二项分布;而Softmax的输出表示为多项式分布。所以Sigmoid通常用于二分类,Softmax用于多类别分类。