1.交叉熵
1.1 信息量
1.信息是什么,信息是用来消灭随机不确定性的东西。
一个东西越不确定,就需要越多的信息,信息量就是用来衡量我们所需要的信息多少。
例如:
事件A:太阳明天不会爆炸。
事件B:太阳明天会爆炸。
就直观的来看,事件B里包含的信息量是不是很大,但是到底有多大你说不出来。下面公式告诉你有多大。
2.信息量公式:
I(x)=−log(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=1np(xi)I(xi)=−∑i=1np(xi)log(p(xi))
\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散度)
相对熵是两个概率分布间差异的非对称性度量 。(摘自百度)
例如:对于太阳明天会不会爆炸这个事,它真实的概率分布是:
Preal=(PA,PB)
P_{real} = (P_A,P_B)
Preal=(PA,PB)
现在我们用深度学习预测了太阳明天爆不爆炸的概率分布是:
Qpred=(QA,QB)
Q_{pred} = (Q_A,Q_B)
Qpred=(QA,QB)
那么PrealP_{real}Preal与QpredQ_{pred}Qpred的相对熵是:
DKL(P∣∣Q)=∑i=1np(xi)logp(xi)q(xi)=∑i=1np(xi)log(p(xi))−∑i=1np(xi)log(q(xi))=−H(P)−∑i=1np(xi)log(q(xi))
\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))
DKL(P∣∣Q)D_{KL}(P||Q)DKL(P∣∣Q)的值越小,表示QpredQ_{pred}Qpred分布和PrealP_{real}Preal分布越接近,则我们预测的越准
1.4交叉熵
在相对熵中,由于−H(P)-H(P)−H(P)是一个定值,所以我们只需关注其后半部分,即所谓的交叉熵:
H(P,Q)=−∑i=1np(xi)log(q(xi))
H(P,Q) = -\sum_{i=1} ^n p(x_i)log(q(x_i))
H(P,Q)=−i=1∑np(xi)log(q(xi))
要想QpredQ_{pred}Qpred分布和PrealP_{real}Preal分布越接近,就需要DKL(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激活的值。