1.交叉熵
1.1 信息量
1.信息是什么,信息是用来消灭随机不确定性的东西。
一个东西越不确定,就需要越多的信息,信息量就是用来衡量我们所需要的信息多少。
例如:
事件A:太阳明天不会爆炸。
事件B:太阳明天会爆炸。
就直观的来看,事件B里包含的信息量是不是很大,但是到底有多大你说不出来。下面公式告诉你有多大。
2.信息量公式:
I
(
x
)
=
−
l
o
g
(
p
(
x
)
)
I(x)=-log(p(x))
I(x)=−log(p(x))
I
(
x
)
I(x)
I(x):事件x确定发生所需要的信息量;
p
(
x
)
p(x)
p(x):事件x发生的概率。
事件发生的概率越大,那么它所需要的信息量就越小,反之亦反。
1.2信息熵
我们有了每个事件的信息量,这时我们就需要一个能描述所有事件信息量期望值的度量,这就是信息熵。
H
(
x
)
=
∑
i
=
1
n
p
(
x
i
)
I
(
x
i
)
=
−
∑
i
=
1
n
p
(
x
i
)
l
o
g
(
p
(
x
i
)
)
\begin{aligned} H(x) & = \sum_{i=1} ^n p(x_i)I(x_i) \\ & =-\sum_{i=1} ^n p(x_i)log(p(x_i)) \\ \end{aligned}
H(x)=i=1∑np(xi)I(xi)=−i=1∑np(xi)log(p(xi))
1.3相对熵(KL散度)
相对熵是两个概率分布间差异的非对称性度量 。(摘自百度)
例如:对于太阳明天会不会爆炸这个事,它真实的概率分布是:
P
r
e
a
l
=
(
P
A
,
P
B
)
P_{real} = (P_A,P_B)
Preal=(PA,PB)
现在我们用深度学习预测了太阳明天爆不爆炸的概率分布是:
Q
p
r
e
d
=
(
Q
A
,
Q
B
)
Q_{pred} = (Q_A,Q_B)
Qpred=(QA,QB)
那么
P
r
e
a
l
P_{real}
Preal与
Q
p
r
e
d
Q_{pred}
Qpred的相对熵是:
D
K
L
(
P
∣
∣
Q
)
=
∑
i
=
1
n
p
(
x
i
)
l
o
g
p
(
x
i
)
q
(
x
i
)
=
∑
i
=
1
n
p
(
x
i
)
l
o
g
(
p
(
x
i
)
)
−
∑
i
=
1
n
p
(
x
i
)
l
o
g
(
q
(
x
i
)
)
=
−
H
(
P
)
−
∑
i
=
1
n
p
(
x
i
)
l
o
g
(
q
(
x
i
)
)
\begin{aligned} D_{KL}(P||Q) & = \sum_{i=1} ^n p(x_i)log\frac{p(x_i)}{q(x_i)}\\ & =\sum_{i=1} ^n p(x_i)log(p(x_i))-\sum_{i=1} ^n p(x_i)log(q(x_i))\\ & =-H(P) - \sum_{i=1} ^n p(x_i)log(q(x_i))\\ \end{aligned}
DKL(P∣∣Q)=i=1∑np(xi)logq(xi)p(xi)=i=1∑np(xi)log(p(xi))−i=1∑np(xi)log(q(xi))=−H(P)−i=1∑np(xi)log(q(xi))
D
K
L
(
P
∣
∣
Q
)
D_{KL}(P||Q)
DKL(P∣∣Q)的值越小,表示
Q
p
r
e
d
Q_{pred}
Qpred分布和
P
r
e
a
l
P_{real}
Preal分布越接近,则我们预测的越准
1.4交叉熵
在相对熵中,由于
−
H
(
P
)
-H(P)
−H(P)是一个定值,所以我们只需关注其后半部分,即所谓的交叉熵:
H
(
P
,
Q
)
=
−
∑
i
=
1
n
p
(
x
i
)
l
o
g
(
q
(
x
i
)
)
H(P,Q) = -\sum_{i=1} ^n p(x_i)log(q(x_i))
H(P,Q)=−i=1∑np(xi)log(q(xi))
要想
Q
p
r
e
d
Q_{pred}
Qpred分布和
P
r
e
a
l
P_{real}
Preal分布越接近,就需要
D
K
L
(
P
∣
∣
Q
)
D_{KL}(P||Q)
DKL(P∣∣Q)的值越小,就是要交叉熵
H
(
P
,
Q
)
H(P,Q)
H(P,Q)越小。
2.交叉熵损失函数的运用
2.1softmax+交叉熵
当我们需要对单标签进行分类时,我们就选择softmax函数+交叉熵损失。
比如说一张图片上只有一种动物,猫,狗,或🐖
为什么要用sofrmax函数呢?因为交叉熵损失需要预测值的概率分布,而softmax函数可以将所有值映射到[0,1]区间上,且他们的和为1。
实验:
import tensorflow as tf
import numpy as np
#单标签数据
label = [[0,0,1]]
#输入数据是一张像素为4X4大小的图片
X = np.random.randn(1,16)*10
#定义占位符
x = tf.placeholder(shape=[None,16],dtype=tf.float32)
#定义权重与偏置
w1 = tf.Variable(tf.random_normal([16, 3], stddev=1, seed=1))
b1 = tf.Variable(tf.ones(3))
#网络结构
h0 = tf.matmul(x,w1)+b1
#通过softmax将预测值映射到[0,1]区间上
pred = tf.nn.softmax(h0)
#交叉熵损失
cross_entropy_softmax = tf.nn.softmax_cross_entropy_with_logits(labels=label,logits=h0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
h0,pred,cross_entropy_softmax = sess.run([h0,pred,cross_entropy_softmax],feed_dict={x:X})
print('未经过softmax激活的输出值为:%s' % h0)
print('经过softmax激活函数映射后:%s' % pred)
print('交叉熵损失:%s' % cross_entropy_softmax)
注意:tf.nn.softmax_cross_entropy_with_logits()]方法包含了softmax+交叉熵,所以传入的预测值是未经过softmax激活的值。
2.2sigmoid+交叉熵
当我们需要对多标签进行分类时,我们就选择sigmoid函数+交叉熵损失。
比如说一张图片上既有猫,狗和🐖,我们就需要sigmoid。
实验:
import tensorflow as tf
import numpy as np
#多标签数据
label = [[1.,0.,1.]]
#输入数据是一张像素为4X4大小的图片
X = np.random.randn(1,16)*10
#定义占位符
x = tf.placeholder(shape=[None,16],dtype=tf.float32)
#定义权重与偏置
w1 = tf.Variable(tf.random_normal([16, 3], stddev=1, seed=1))
b1 = tf.Variable(tf.ones(3))
#网络结构
h0 = tf.matmul(x,w1)+b1
#通过sigmoid将预测值映射到[0,1]区间上
pred = tf.nn.sigmoid(h0)
#交叉熵损失
cross_entropy_sigmoid = tf.nn.sigmoid_cross_entropy_with_logits(labels=label,logits=h0)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
h0,pred,cross_entropy_sigmoid = sess.run([h0,pred,cross_entropy_sigmoid],feed_dict={x:X})
print('未经过sigmoid激活的输出值为:%s' % h0)
print('经过sigmoid激活函数映射后:%s' % pred)
print('交叉熵损失:%s' % cross_entropy_sigmoid)
注意:tf.nn.sigmoid_cross_entropy_with_logits()]方法包含了sigmoid+交叉熵,所以传入的预测值是未经过sigmoid激活的值。