前面来源于知乎,后面分析来源于自己
作者:CyberRep
链接:https://www.zhihu.com/question/41252833/answer/195901726
来源:知乎
题目1:爸爸拿来一个箱子,跟小明说:里面有橙、紫、蓝及青四种颜色的小球任意个,各颜色小球的占比不清楚,现在我从中拿出一个小球,你猜我手中的小球是什么颜色?
为了使被罚时间最短,小明发挥出最强王者的智商,瞬间就想到了以最小的代价猜出答案,简称策略1,小明的想法是这样的。
在这种情况下,小明什么信息都不知道,只能认为四种颜色的小球出现的概率是一样的。所以,根据策略1,1/4概率是橙色球,小明需要猜两次,1/4是紫色球,小明需要猜两次,其余的小球类似,所以小明预期的猜球次数为:
H = 1/4 * 2 + 1/4 * 2 + 1/4 * 2 + 1/4 * 2 = 2
题目2:爸爸还是拿来一个箱子,跟小明说:箱子里面有小球任意个,但其中1/2是橙色球,1/4是紫色球,1/8是蓝色球及1/8是青色球。我从中拿出一个球,你猜我手中的球是什么颜色的?
小明毕竟是最强王者,仍然很快得想到了答案,简称策略2,他的答案是这样的。
在这种情况下,小明知道了每种颜色小球的比例,比如橙色占比二分之一,如果我猜橙色,很有可能第一次就猜中了。所以,根据策略2,1/2的概率是橙色球,小明需要猜一次,1/4的概率是紫色球,小明需要猜两次,1/8的概率是蓝色球,小明需要猜三次,1/8的概率是青色球,小明需要猜三次,所以小明预期的猜题次数为:
H = 1/2 * 1 + 1/4 * 2 + 1/8 * 3 + 1/8 * 3= 1.75
题目3:其实,爸爸只想让小明意识到自己的错误,并不是真的想罚他,所以拿来一个箱子,跟小明说:里面的球都是橙色,现在我从中拿出一个,你猜我手中的球是什么颜色?
最强王者怎么可能不知道,肯定是橙色,小明需要猜0次。
上面三个题目表现出这样一种现象:针对特定概率为p的小球,需要猜球的次数 = ,例如题目2中,1/4是紫色球,
= 2 次,1/8是蓝色球,
= 3次。那么,针对整个整体,预期的猜题次数为:
,这就是信息熵,上面三个题目的预期猜球次数都是由这个公式计算而来,第一题的信息熵为2,第二题的信息熵为1.75,最三题的信息熵为1 *
= 0 。那么信息熵代表着什么含义呢?
信息熵代表的是随机变量或整个系统的不确定性,熵越大,随机变量或系统的不确定性就越大。上面题目1的熵 > 题目2的熵 > 题目3的熵。在题目1中,小明对整个系统一无所知,只能假设所有的情况出现的概率都是均等的,此时的熵是最大的。题目2中,小明知道了橙色小球出现的概率是1/2及其他小球各自出现的概率,说明小明对这个系统有一定的了解,所以系统的不确定性自然会降低,所以熵小于2。题目3中,小明已经知道箱子中肯定是橙色球,爸爸手中的球肯定是橙色的,因而整个系统的不确定性为0,也就是熵为0。所以,在什么都不知道的情况下,熵会最大,针对上面的题目1~~题目3,这个最大值是2,除此之外,其余的任何一种情况,熵都会比2小。
所以,每一个系统都会有一个真实的概率分布,也叫真实分布,题目1的真实分布为(1/4,1/4,1/4,1/4),题目2的真实分布为(1/2,1/4,1/8,1/8),而根据真实分布,我们能够找到一个最优策略,以最小的代价消除系统的不确定性,而这个代价大小就是信息熵,记住,信息熵衡量了系统的不确定性,而我们要消除这个不确定性,所要付出的【最小努力】(猜题次数、编码长度等)的大小就是信息熵。具体来讲,题目1只需要猜两次就能确定任何一个小球的颜色,题目2只需要猜测1.75次就能确定任何一个小球的颜色。
现在回到题目2,假设小明只是钻石段位而已,智商没王者那么高,他使用了策略1,即
爸爸已经告诉小明这些小球的真实分布是(1/2,1/4, 1/8,1/8),但小明所选择的策略却认为所有的小球出现的概率相同,相当于忽略了爸爸告诉小明关于箱子中各小球的真实分布,而仍旧认为所有小球出现的概率是一样的,认为小球的分布为(1/4,1/4,1/4,1/4),这个分布就是非真实分布。此时,小明猜中任何一种颜色的小球都需要猜两次,即1/2 * 2 + 1/4 * 2 + 1/8 * 2 + 1/8 * 2 = 2。
很明显,针对题目2,使用策略1是一个坏的选择,因为需要猜题的次数增加了,从1.75变成了2,小明少玩了1.75的王者荣耀呢。因此,当我们知道根据系统的真实分布制定最优策略去消除系统的不确定性时,我们所付出的努力是最小的,但并不是每个人都和最强王者一样聪明,我们也许会使用其他的策略(非真实分布)去消除系统的不确定性,就好比如我将策略1用于题目2(原来这就是我在白银的原因),那么,当我们使用非最优策略消除系统的不确定性,所需要付出的努力的大小我们该如何去衡量呢?
这就需要引入交叉熵,其用来衡量在给定的真实分布下,使用非真实分布所指定的策略消除系统的不确定性所需要付出的努力的大小。
正式的讲,交叉熵的公式为: ,其中
表示真实分布,
表示非真实分布。例如上面所讲的将策略1用于题目2,真实分布
, 非真实分布
,交叉熵为
,比最优策略的1.75来得大。
因此,交叉熵越低,这个策略就越好,最低的交叉熵也就是使用了真实分布所计算出来的信息熵,因为此时 ,交叉熵 = 信息熵。这也是为什么在机器学习中的分类算法中,我们总是最小化交叉熵,因为交叉熵越低,就证明由算法所产生的策略最接近最优策略,也间接证明我们算法所算出的非真实分布越接近真实分布。
最后,我们如何去衡量不同策略之间的差异呢?这就需要用到相对熵,其用来衡量两个取值为正的函数或概率分布之间的差异,即:
KL(f(x) || g(x)) =
现在,假设我们想知道某个策略和最优策略之间的差异,我们就可以用相对熵来衡量这两者之间的差异。即,相对熵 = 某个策略的交叉熵 - 信息熵(根据系统真实分布计算而得的信息熵,为最优策略),公式如下:
KL(p || q) = H(p,q) - H(p) =
所以将策略1用于题目2,所产生的相对熵为2 - 1.75 = 0.25.
¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
softmax
我习惯成它为软max,知乎上有一个大牛这样解释道:
SVM只选自己喜欢的男神,Softmax把所有备胎全部拉出来评分,最后还归一化一下
可以看到每一个数据都送入softmax后,出来都是一个在0-1之间的数,而且这些数加起来,都等于1,重点是等于1,你想到了什么,对,是概率,因为一个事件发生的所有情况概率总和等于1,很巧妙吧,softmax竟然可以把一串数据转化为概率,为多分类打下美好的基础,想想,一串数据进入,输出最大的数就是对应的事件发生的概率。
sigmoid
这也是一个改变一串数据的函数,和softmax相同的地方是输出数据的范围都是0-1
和softmax不同的地方是,它对一串数据的每一个进行转换,所以一串数据中彼此都是独立的,也就是他们的概率相加不会有等于1的约束,这些数据联合起来没有什么鸟关系。
深度学习中的交叉熵
这个要分为两种情况讨论,首先设x*W后的数据是原始数据,也就是上文所说的那一串数据,
假设N=3,期望输出为p=(1,0,0),实际输出(原始数据):q1=(0.5,0.2,0.3),q2=(0.8,0.1,0.1),那么:
1.用softmax进行计算交叉熵(cross entropy)
如果在原始数据上你用的是softmax进行的归一化,那么交叉熵:
then:
很显然,q2与p更为接近,它的交叉熵也更小。
2.用sigmoid进行交叉熵计算
如果在原始数据上你用的是sigmoid进行的归一化,那么交叉熵:
之前说了,每一个Label都是独立分布的,相互之间没有影响。所以交叉熵在这里是单独对每一个节点进行计算,每一个节点只有两种可能值,所以是一个二项分布。
所以每一个都看成一个二分类,上式是一个二分类的交叉熵:
所以总的交叉熵也就是总的loss是:
H(p,q)=loss=loss1+loss2+loss3+.......
then:
其中Keras中的sigmoid交叉熵的实现就是loss = 'binary_crossentropy', 也就是tensorflow中的tf.nn.sigmoid_cross_entropy_with_logits()的实现:
测试如下:
import numpy as np
import tensorflow as tf
def sigmoid(x):
return 1.0/(1+np.exp(-x))
labels=np.array([[1.,0.,0.],[0.,1.,0.],[0.,0.,1.]])
logits=np.array([[11.,8.,7.],[10.,14.,3.],[1.,2.,4.]])
y_pred=sigmoid(logits)
prob_error1=-labels*np.log(y_pred)-(1-labels)*np.log(1-y_pred)
print(prob_error1)
print(".............")
labels1=np.array([[0.,1.,0.],[1.,1.,0.],[0.,0.,1.]])#不一定只属于一个类别
logits1=np.array([[1.,8.,7.],[10.,14.,3.],[1.,2.,4.]])
y_pred1=sigmoid(logits1)
prob_error11=-labels1*np.log(y_pred1)-(1-labels1)*np.log(1-y_pred1)
print(prob_error11)
print(".............")
with tf.Session() as sess:
print(sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels,logits=logits)))
print(".............")
print(sess.run(tf.nn.sigmoid_cross_entropy_with_logits(labels=labels1,logits=logits1)))
结果:你会发现第一个输出与第三个一致,第二个输出和第四个一致
[[1.67015613e-05 8.00033541e+00 7.00091147e+00]
[1.00000454e+01 8.31528373e-07 3.04858735e+00]
[1.31326169e+00 2.12692801e+00 1.81499279e-02]]
.............
[[1.31326169e+00 3.35406373e-04 7.00091147e+00]
[4.53988992e-05 8.31528373e-07 3.04858735e+00]
[1.31326169e+00 2.12692801e+00 1.81499279e-02]]
.............
2018-08-03 20:54:55.486212: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
[[1.67015613e-05 8.00033541e+00 7.00091147e+00]
[1.00000454e+01 8.31528373e-07 3.04858735e+00]
[1.31326169e+00 2.12692801e+00 1.81499279e-02]]
.............
[[1.31326169e+00 3.35406373e-04 7.00091147e+00]
[4.53988992e-05 8.31528373e-07 3.04858735e+00]
[1.31326169e+00 2.12692801e+00 1.81499279e-02]]
Process finished with exit code 0
总结:
其实softmax和sigmoid都可以用于多分类,只是softmax由于其联合起来为1的性质一般用于多分类,而sigmoid是用于二分类的基础上扩展到多分类的。
softmax求loss成为softmax回归,sigmoid求loss称为sigmoid逻辑回归,当类别说等于二时,softmax也退化成了逻辑回归!
sigmoid和softmax都是输出,不加交叉熵的时候,两者都是取最大值作为自己的输出,但是如果作为交叉熵的时候,sigmoid适用于对于一个数求loss,比如计算0和1之间的loss,这个时候用sigmoid就是无穷大,softmax适用于对一个向量求loss,比如计算[0,1,0,0],和[0.5,0.2,0.2,0.1]的loss