交叉熵的作用
通过神经网络解决多分类问题时,最常用的一种方式就是在最后一层设置n个输出节点,无论在浅层神经网络还是在CNN中都是如此,比如,在AlexNet中最后的输出层有1000个结点:
而即便是ResNet取消了隐藏层的全连接,也会在最后有一个1000个节点的输出层,比如下图中的ResNet18,ResNet34,ResNet0,ResNet101和ResNet152,最后的输出都是1000-d fc,也就是1000个结点:
一般情况下,最后一个输出层的节点个数与分类任务的目标数相等。假设最后的节点数为N,那么对于每一个样例,神经网络可以得到一个N维的数组作为输出结果,数组中每一个维度会对应一个类别。在最理想的情况下,如果一个样本属于k,那么这个类别所对应的的输出节点的输出值应该为1,而其他结点的输出都为0,即[0,0,1,0,…0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果,交叉熵就是用来判定实际的输出与期望的输出的接近程度!
但是这里有一个特例,就是二分类问题,二分类问题时,网络可以输出N=2个结点,这种情况下和上面说到的是一致的。但是也可以只输出一个结点,用这个结点的值是否大于0.5来做二分类,Logist处理二分类问题时就是这样。
激活函数
神经网络的原始输出(也就是结点的直接输出结果)不是一个概率值,实质上只是输入的数值做了复杂的加权和与非线性处理之后的一个值而已,那么如何将这个输出变为概率分布呢?对于上面提到的两种情况,一般会采用Softmax和Sigmoid做激活处理。
Softmax
假设神经网络的原始输出为
y
1
,
y
2
,
.
.
.
.
,
y
n
y_{1},y_{2},....,y_{n}
y1,y2,....,yn,那么经过Softmax处理之后的输出为:
s
o
f
t
m
a
x
(
y
i
)
=
e
i
y
∑
j
=
1
n
e
i
y
softmax(y_{i}) = \frac{e^y_{i}}{\sum_{j=1}^{n}e^y_{i}}
softmax(yi)=∑j=1neiyeiy
很显然的是:
∑
j
=
1
n
s
o
f
t
m
a
x
(
y
i
)
=
1
\sum_{j=1}^{n}softmax(y_{i}) = 1
j=1∑nsoftmax(yi)=1
也就是说每个结点的输出,加起来为1,所以经过Softmax处理后单个节点的输出变成的一个概率值。
Sigmoid
Softmax激活起码要对应N大于等于2的输出结点,那么上述的另一种情况,只有一个结点时处理二分类问题,应该怎么激活?这里就用到了Sigmoid,Sigmoid在早期ANN中常用于去线性化,因为它的特性是将一个数压缩到0-1之间:
S i g m o i d ( y ) = 1 1 + e − y Sigmoid(y) = \frac{1}{1+e^{-y}} Sigmoid(y)=1+e−y1
压缩后的结果就可以作为二分类中某一类的概率值,由于是二分类问题,所以另一类的概率值自然就是
1
−
S
i
g
m
o
i
d
(
y
)
1-Sigmoid(y)
1−Sigmoid(y)。
这样处理,和N=2时做Softmax,效果是相似的,都可以表征出二分类的概率。
交叉熵原理
交叉熵刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近。
二值交叉熵
分类任务中有二分类,交叉熵中也有一个特例,就是二值交叉熵。
二值交叉熵是对应Sigmoid激活时的二分类问题的,它的公式是这样:
L
(
p
,
t
)
=
−
[
t
l
o
g
(
p
)
+
(
1
−
t
)
l
o
g
(
1
−
p
)
]
L(p,t) = -[tlog(p)+(1-t)log(1-p)]
L(p,t)=−[tlog(p)+(1−t)log(1−p)]
其中,
t
t
t为样本的期望输出,
p
p
p为样本的实际输出,其中
p
=
S
i
g
m
o
i
d
(
y
)
p=Sigmoid(y)
p=Sigmoid(y)。这里的
p
p
p和
t
t
t都只是一个数。
二值交叉熵的这个公式是可证的,在另一篇文章中给出了上述公式的证明。
这个公式如何表征距离呢,举个例子:
假设期望输出
t
=
1
t=1
t=1,实际输出
p
1
=
0.3
p_{1}=0.3
p1=0.3,
p
2
=
0.6
p_{2}=0.6
p2=0.6那么:
L
1
(
t
,
p
1
)
=
−
l
o
g
(
0.3
)
=
0.522
L_{1}(t,p_{1}) = -log(0.3)=0.522
L1(t,p1)=−log(0.3)=0.522
L
2
(
t
,
p
2
)
=
−
l
o
g
(
0.6
)
=
0.221
L_{2}(t,p_{2}) = -log(0.6)=0.221
L2(t,p2)=−log(0.6)=0.221
显然
t
2
t_{2}
t2的损失更小。
假设期望输出
p
=
0
p=0
p=0,实际输出
t
1
=
0.3
t_{1}=0.3
t1=0.3,
t
2
=
0.6
t_{2}=0.6
t2=0.6那么:
L
1
(
t
,
p
1
)
=
−
l
o
g
(
1
−
0.3
)
=
0.154
L_{1}(t,p_{1}) = -log(1-0.3)=0.154
L1(t,p1)=−log(1−0.3)=0.154
L
2
(
t
,
p
2
)
=
−
l
o
g
(
1
−
0.6
)
=
0.397
L_{2}(t,p_{2}) = -log(1-0.6)=0.397
L2(t,p2)=−log(1−0.6)=0.397
显然
t
1
t_{1}
t1的损失更小。
交叉熵
在二分类的基础上,交叉熵有更通用的表达形式,因为二分类只是分类问题的特例,更多的还是多分类问题,比如前面提到的1000分类。通用的交叉熵要对应Softmax函数使用,所以有时候Softmax+交叉熵也被称为Softmax损失函数,它表达式为:
H
(
T
,
P
)
=
−
∑
1
C
T
l
o
g
(
P
)
H(T,P) = -\sum_{1}^{C} Tlog(P)
H(T,P)=−1∑CTlog(P)
其中,
T
T
T为样本的期望输出,它是一个one-hot编码形式,比如二分类时label=0,one-hot应该为[1,0];三分类时label=0,one-hot应该为[1,0,0]。
P
P
P为样本的实际输出,其中
P
=
[
s
o
f
t
m
a
x
(
y
1
)
,
s
o
f
t
m
a
x
(
y
2
)
,
.
.
.
,
s
o
f
t
m
a
x
(
y
i
=
n
)
]
P=[softmax(y_{1}),softmax(y_{2}),...,softmax(y_{i=n})]
P=[softmax(y1),softmax(y2),...,softmax(yi=n)]。
这里的
T
T
T和
P
P
P就不再是一个数了,而是一个长度与类别数相同的集合,所以这里用了大写。
这个公式如何表征距离呢,还是举例说明,首先是上面二分类的例子:
假设期望输出
t
=
1
t=1
t=1,实际输出
p
1
=
0.3
p_{1}=0.3
p1=0.3,
p
2
=
0.6
p_{2}=0.6
p2=0.6,那么把它变成一个N=2的集合应该是:
T
=
[
0
,
1
]
T=[0,1]
T=[0,1],
P
1
=
[
0.7
,
0.3
]
P_{1}=[0.7,0.3]
P1=[0.7,0.3],
P
2
=
[
0.4
,
0.6
]
P_{2}=[0.4,0.6]
P2=[0.4,0.6]
H
1
(
T
,
P
1
)
=
−
l
o
g
(
0.3
)
=
0.522
H_{1}(T,P_{1}) =-log(0.3)=0.522
H1(T,P1)=−log(0.3)=0.522
H
2
(
T
,
P
2
)
=
−
l
o
g
(
0.6
)
=
0.221
H_{2}(T,P_{2}) = -log(0.6)=0.221
H2(T,P2)=−log(0.6)=0.221
到这里就发现,和上面的结果是一致的,因为我们本来就是用Sigmoid的输出去假设了Softmax的输出,因为二分类只有1减去当前类别的概率,剩下的就会是另一个类别的概率。上述的交叉熵公式
H
(
P
,
T
)
H(P,T)
H(P,T),如果把
∑
\sum
∑展开,也就成了
L
(
p
,
t
)
L(p,t)
L(p,t)。
第二个
p
=
0
p=0
p=0的例子就不太详细举例了。
下面假设一个三分类情况,
T
=
[
1
,
0
,
0
]
T=[1,0,0]
T=[1,0,0],
P
1
=
[
0.8
,
0.1
,
0.1
]
P_{1}=[0.8,0.1,0.1]
P1=[0.8,0.1,0.1],
P
2
=
[
0.5
,
0.3
,
0.2
]
P_{2}=[0.5,0.3,0.2]
P2=[0.5,0.3,0.2]
H
1
(
P
,
T
1
)
=
−
(
1
×
l
o
g
(
0.8
)
+
0
×
l
o
g
(
0.1
)
+
0
×
l
o
g
(
0.1
)
)
=
0.096
H_{1}(P,T_{1}) =-(1\times log(0.8)+0\times log(0.1)+0\times log(0.1))=0.096
H1(P,T1)=−(1×log(0.8)+0×log(0.1)+0×log(0.1))=0.096
H
2
(
P
,
T
2
)
=
−
(
1
×
l
o
g
(
0.5
)
+
0
×
l
o
g
(
0.3
)
+
0
×
l
o
g
(
0.2
)
)
=
0.301
H_{2}(P,T_{2}) = -(1\times log(0.5)+0\times log(0.3)+0\times log(0.2))=0.301
H2(P,T2)=−(1×log(0.5)+0×log(0.3)+0×log(0.2))=0.301
T
1
T_{1}
T1要更接近label,所以损失更小。