2019-03-12 15:04:12 Neekity 阅读数 308

考虑某个未知的分布p(x)p(x),假定我们已经使用了一个近似的分布q(x)q(x)对它进行了建模。如果我们使用q(x)q(x)来建立一个编码体系,用来把x的值传给接受者,那么由于我们使用了q(x)q(x)而不是真正的p(x)p(x),因此在具体化x的值时,我们需要一些附加信息。我们需要的平均的附加信息量为KL(pq)=p(x)lnq(x)dx(p(x)lnp(x)dx)KL(p||q)=-\int p(x)\mathrm{ln} q(x)dx-(-\int p(x)\mathrm{ln}p(x)dx)=p(x)lnq(x)p(x)dx=-\int p(x)\mathrm{ln} \frac{q(x)}{p(x)}dx这被称为分布p(x)p(x)q(x)q(x)之间的相对熵或者KL散度。
现在考虑由p(x,y)p(x,y)给出的两个变量x和y组成的数据集。如果变量不是独立的,我们可以通过考察联合概率分布与边缘概率分布乘积之间的KL散度来判断它们是否接近于相互独立。I[x,y]=KL(p(x,y)p(x)p(y))I[x,y]=KL(p(x,y)||p(x)p(y))=p(x,y)lnp(x)p(y)p(x,y)dxdy=-\int \int p(x,y)\mathrm{ln}\frac{p(x)p(y)}{p(x,y)}dxdy 这就被称为x和y之间的互信息。
使用概率的加和规则和乘积规则,我们可以看到互信息与条件熵之间的关系为I[x,y]=H[x]H[xy]=H[y]H[yx]I[x,y]=H[x]-H[x|y]=H[y]-H[y|x]因此我们可以把互信息看成由于知道y值而造成的x的不确定性的减少。从贝叶斯的观点来看,我们可以把p(x)p(x)看成x的先验概率分布,把p(xy)p(x|y)看成我们观察到新数据y之后的后验概率分布。因此互信息表示一个新的预测y造成的x的不确定性的减少。

2019-11-12 13:09:36 weixin_37763870 阅读数 123

KL散度定义

KL(Kullback-Leibler divergence)散度多应用于概率论或信息论中,又可称相对熵(relative entropy)。它是用来描述两个概率分布P和Q的差异的一种方法
【记】KL具有非对称性,即D(P||Q) ≠ D(Q||P)
在信息论中,D(P||Q) 表示用概率分布Q来拟合真实分布P时,产生的信息损耗,其中P表示真实分布,Q表示P的拟合分布

KL散度公式定义

对于离散型随机变量有:
在这里插入图片描述
对于连续型随机变量有:
在这里插入图片描述

KL散度的物理定义

信息论中,它是用来度量使用基于Q分布的编码来编码来自P分布的样本平均所需的额外的比特(bit)个数
机器学习领域,是用来度量两个函数的相似程度或者相近程度
在信息论中,用基于P的编码去编码来自P的样本,其最优编码平均所需要的比特个数(即这个字符集的熵)为:
在这里插入图片描述
用基于P的编码去编码来自Q的样本,则所需要的比特个数变为:
在这里插入图片描述
【注】P(x)为各字符出现的频率,log(1P(x)\frac{1}{P(x)})为该字符相应的编码长度,log(1Q(x)\frac{1}{Q(x)})为对应于Q的分布各字符编码长度。
那么KL散度即可表示为如下:
在这里插入图片描述

简要介绍Jensen不等式

在这里插入图片描述

利用Jensen不等式证明P与Q之间的KL散度不小于0:
在这里插入图片描述

2019-12-10 15:02:00 Rocky6688 阅读数 19

KL散度(Kullback-Leibler divergence),可以以称作相对熵(relative entropy)或信息散度(information divergence)。KL散度的理论意义在于度量两个概率分布之间的差异程度,当KL散度越高的时候,说明两者的差异程度越大;而当KL散度低的时候,则说明两者的差异程度小。如果两者相同的话,则该KL散度应该为0。

接下来我们举一个具体的例子:

我们设定两个概率分布分别为P和Q,在假定为连续随机变量的前提下,他们对应的概率密度函数分别为p(x)和q(x)。我们可以写出如下公式:

KL(PQ)=p(x)logp(x)q(x)dxKL(P||Q) = \int p(x)\log \frac{p(x)}{q(x)}dx

从上面的公式可以看出,当且仅当P=Q时,KL(P||Q) = 0。此外我们也发现KL散度具备非负的特性,即P(P||Q) >= 0。但是从公式中我们也可以发现,Kl散度不具备对称性,也就是说P对于Q的KL散度并不等于Q对于P的KL散度。因此,KL散度并不是一个度量(metric)

我们在来看看离散的情况下KL散度的公式:

KL(PQ)=p(x)logp(x)q(x)KL(P||Q) = \sum p(x)\log \frac{p(x)}{q(x)}

接下来我们对上面的式子进行展开:

KL(PQ)=p(x)logp(x)q(x)=p(x)log(q(x))+p(x)log(p(x))=H(P,Q)H(P)KL(P||Q) = \sum p(x)\log \frac{p(x)}{q(x)} = -\sum p(x)\log(q(x)) + \sum p(x)\log(p(x)) = H(P,Q) - H(P)

最后得到的第一项类似熵的形式,这一项称作P和Q的交叉熵(cross entropy),后面一项就是熵。

在信息论中,熵代表着信息量,H§代表着基于P分布自身的编码长度,也就是最优的编码长度(最小字节数)。而H(P,Q)则代表着用P的分布去近似Q分布的信息,自然需要更多的编码长度。并且两个分布差异越大,需要的编码长度越大。所以两个值相减是大于等于0的一个值,代表冗余的编码长度,也就是两个分布差异的程度。所以KL散度在信息论中还可以称为相对熵(relative entropy)。

对深度学习中的生成模型来说,我们希望最小化真实数据分布与生成模型分布之间的KL散度,从而使得生成模型尽可能接近真实数据的分布。在实际实践中,我们是几乎不可能知道真实数据分布Pdata(x)的,我们使用训练数据形成的经验分布在逼近Pdata(x)。

2018-10-23 20:07:31 qq_29053993 阅读数 2741

KL散度(Kullback-Leibler divergence)

又称KL距离,相对熵。KL散度是描述两个概率分布P和Q之间差异的一种方法。直观地说,可以用来衡量给定任意分布偏离真实分布的程度,如果两个分布完全匹配,那么KL(p||q)=0,否则它的取值应该是0~∞(inf)之间。KL散度越小,真实分布与近视分布之间的匹配程度就越好。

KL散度的计算公式

离散概率分布的KL散度计算公式:
KL(pq)=p(x)logp(x)q(x) KL(p||q)=\sum p(x)\log \frac{p(x)}{q(x)}
连续概率分布的KL散度计算公式:
KL(pq)=p(x)logp(x)q(x)dx KL(p||q)=\int p(x)\log \frac{p(x)}{q(x)}dx

KL散度的基本性质

  • 非负性
    KL散度的结果是非负的,简单证明如下:
    KL(pq)=xp(x)logp(x)q(x)=xp(x) logq(x)p(x) KL(p||q)=\sum _xp(x) \log \frac {p(x)}{q(x)}=-\sum _xp(x)\ log \frac{q(x)}{p(x)}
    由于对数函数是一个上凸函数,所以有:
    log[xp(x)q(x)p(x)]=log[xq(x)]=log1=0 \ge-\log[\sum_xp(x)\frac{q(x)}{p(x)}]=-\log[\sum_xq(x)]=-\log 1=0
  • 不对称性
    KL(pq)̸=KL(qp)KL(p||q)\not=KL(q||p)

关于KL散度的数学概念,可移步[link] https://www.jiqizhixin.com/articles/2018-05-29-2?from=synced&keyword=直观解读kl散度的数学概念

JS散度(Jensen-Shannon divergence)

JS散度也称JS距离,是KL散度的一种变形。

JS散度的数学公式

JS(pq)=12KL(pp+q2)+12KL(qp+q2) JS(p||q)=\frac12KL(p||\frac{p+q}2)+\frac12KL(q||\frac{p+q}{2})

不同于KL的主要两方面

  • 值域范围
    JS散度的值域范围是[0,1],相同为0,相反则为1。相比较于KL,对相似度的判别更准确了。
  • 对称性
    JS(pq)=JS(qp)JS(p||q)=JS(q||p),而对称能让散度度量更准确。下面用一段代码展示这其中的道理:
import numpy as np
import math
# 离散随机变量的KL散度和JS散度的计算方法
def KL(p,q):
    #p,q为两个list,里面存着对应的取值的概率,整个list相加为1
    if 0 in q:
        raise ValueError
    return sum(_p * math.log(_p/_q) for (_p,_q) in zip(p,q) if _p != 0)

def JS(p,q):
    M = [0.5 * (_p + _q) for (_p,_q) in zip(p,q)]
    return 0.5 * (KL(p,M) + KL(q,M))

def exp(a,b):
    a = np.array(a,dtype=np.float32)
    b = np.array(b,dtype=np.float32)
    a /= a.sum()
    b /= b.sum()
    print(a)
    print(b)
    print(KL(a,b))
    print(JS(a,b))
# exp 1
exp([1,2,3,4,5],[5,4,3,2,1])

[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.5216030835963031
0.11968758856917597

# exp 2
#把公式中的第二个分布做修改,假设这个分布中有某个值的取值非常小,就有可能增加两个分布的散度值
exp([1,2,3,4,5],[1e-12,4,3,2,1])
exp([1,2,3,4,5],[5,4,3,2,1e-12])

[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[1.e-13 4.e-01 3.e-01 2.e-01 1.e-01]
2.065502018456509
0.0985487692550548
[0.06666667 0.13333334 0.2        0.26666668 0.33333334]
[3.5714287e-01 2.8571430e-01 2.1428572e-01 1.4285715e-01 7.1428574e-14]
9.662950847122168
0.19399530008415986

# exp 3
exp([1e-12,2,3,4,5],[5,4,3,2,1])
exp([1,2,3,4,1e-12],[5,4,3,2,1])

[7.1428574e-14 1.4285715e-01 2.1428572e-01 2.8571430e-01 3.5714287e-01]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.7428131560123377
0.19399530008415986
[1.e-01 2.e-01 3.e-01 4.e-01 1.e-13]
[0.33333334 0.26666668 0.2        0.13333334 0.06666667]
0.38315075574389773
0.0985487692550548

将第一个实验与第二个实验做对比,可以看出KL散度的波动比较大,而JS的波动相对小。
如果将第二个实验和第三个实验做对比,可以发现KL散度在衡量两个分布的差异时具有很大的不对称性。如果后面的分布在某一个值上缺失,就回得到很大的散度值;但是如果前面的分布在某一个值上缺失,最终的KL散度并没有太大的波动。这个demo可以清楚地看出KL不对称性带来的一些小问题,而JS具有对称性,所以第二个实验和第三个实验的JS散度实际上是距离相等的分布组。

2019-12-10 23:17:48 Allenalex 阅读数 13

本文主要包括:
1.kl{\color{red}1. kl散度和交叉熵的概念比较}
2.{\color{red}2. 交叉熵在分类任务中的本质}

在学习机器学习的过程中,我们经常会碰到这两个概念:KL散度(kl divergence)以及交叉熵,并且经常是同时出现的。很多同学对这两个概念都理解的不是很透彻,造成经常会搞混他们两者。本文最主要的目的就是带大家深入理解这两个重要的概念,同时搞懂,区别的理解他们,保证以后不会再搞混它们。
首先,这两个概念都来自信息论。
交叉熵:当我们使用模型Q来编码(表示)来自分布P的数据时,所需要的平均bit数。
交叉熵数学定义为:
H(p,q)=i=1np(xi)log(q(xi))H(p,q)=-\sum_{i=1}^n p(x_i)log(q(x_i))

KL散度: 也就是相对熵, 是当我们使用模型(分布)Q来编码,而不是使用真实的P分布来编码数据时,额外需要的平均bit数。(重点在“额外”,也就是“相对”----交叉熵相对熵额外的那部分熵,就是KL散度)
KL散度的数学定义为:
DKL(pq)=i=1np(xi)log(p(xi)q(xi)D_{KL}(p||q)=\sum_{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i})
对KL散度数学定义进行分解:
在这里插入图片描述
等式的前一部分恰巧就是p的熵,等式的后一部分,就是交叉熵。可以看出,交叉熵减去熵等于KL散度。也就是,交叉熵是,如果用q代替p产生x, 得到的熵,而相对熵,是相对用自身概率p,而新增的那部分信息(熵)。

其中,在分类任务中, 熵这一项,就是分类类别的熵,这个值为0(因为一条记录的label是确定属于某个类别的,也就是没有任何信息可言,熵就是0,或者说,指定的那个类别为1,其他为0,通过熵的计算公式也可以知道,熵为0),所以,在分类任务中,最小化KL散度和最小化交叉熵是一样的(实际上,我们在分类任务中,常用的就是交叉熵)

接下来我们来探究下交叉熵在分类预测中的本质。也就是说,在分类中,交叉熵损失为0的模型是完美的模型,那>0的交叉熵究竟意味着什么呢?怎么理解交叉熵损失不同的取值?
下面这段代码可以看下,从分布完全匹配到两个分布完全相反,这过程中的交叉熵变化。

# cross-entropy for predicted probability distribution vs label
from math import log
from matplotlib import pyplot

# calculate cross-entropy
def cross_entropy(p, q, ets=1e-15):
	return -sum([p[i]*log(q[i]+ets) for i in range(len(p))])

# define the target distribution for two events
target = [0.0, 1.0]
# define probabilities for the first event
probs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
# create probability distributions for the two events
dists = [[1.0 - p, p] for p in probs]
# calculate cross-entropy for each distribution
ents = [cross_entropy(target, d) for d in dists]
# plot probability distribution vs cross-entropy
pyplot.plot([1-p for p in probs], ents, marker='.')
pyplot.title('Probability Distribution vs Cross-Entropy')
pyplot.xticks([1-p for p in probs], ['[%.1f,%.1f]'%(d[0],d[1]) for d in dists], rotation=70)
pyplot.subplots_adjust(bottom=0.2)
pyplot.xlabel('Probability Distribution')
pyplot.ylabel('Cross-Entropy (nats)')
pyplot.show()

输出的图最终如下所示:

在这里插入图片描述
就像预期的那样,当预测的概率分布和目标分布完全匹配的时候,交叉熵是为0的,随着分布差别越来越大,交叉熵也是平稳增加的。只要当分布完全相反是,交叉熵才会飙升很大。当然,在实际的分类任务中,肯定是不会出现这样跟实际分布完全相反的分布的。如果把这种极端完全相反的去掉,代码如下:

# cross-entropy for predicted probability distribution vs label
from math import log
from matplotlib import pyplot

# calculate cross-entropy
def cross_entropy(p, q, ets=1e-15):
	return -sum([p[i]*log(q[i]+ets) for i in range(len(p))])

# define the target distribution for two events
target = [0.0, 1.0]
# define probabilities for the first event
probs = [1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1]
# create probability distributions for the two events
dists = [[1.0 - p, p] for p in probs]
# calculate cross-entropy for each distribution
ents = [cross_entropy(target, d) for d in dists]
# plot probability distribution vs cross-entropy
pyplot.plot([1-p for p in probs], ents, marker='.')
pyplot.title('Probability Distribution vs Cross-Entropy')
pyplot.xticks([1-p for p in probs], ['[%.1f,%.1f]'%(d[0],d[1]) for d in dists], rotation=70)
pyplot.subplots_adjust(bottom=0.2)
pyplot.xlabel('Probability Distribution')
pyplot.ylabel('Cross-Entropy (nats)')
pyplot.show()

在这里插入图片描述
从以上的结果我们可以回答以下问题: 多大的交叉熵分值才是好的分值?
如果是使用的是nat (以e为底的log), 平均交叉熵低于0.2就不错。小于0.1或者0.05就更加的好了。否则,如果得到的交叉熵大于0.2或者0.3,你还可以继续优化;如果你得到的交叉熵要大于1了,那说明你肯定在很多的样本上的预测的概率非常的差。
总结如下:
Cross-Entropy = 0.00: Perfect probabilities.
Cross-Entropy < 0.02: Great probabilities.
Cross-Entropy < 0.05: On the right track.
Cross-Entropy < 0.20: Fine.
Cross-Entropy > 0.30: Not great.
Cross-Entropy > 1.00: Terrible.
Cross-Entropy > 2.00 Something is broken.
熟悉这个,能够帮助你很好的解释你的LR或者神经网络模型的交叉熵损失。
你还可以给每个类分开计算交叉熵,这样你能够看下你的模型在每个类上的表现。

参考资料

[1]: https://machinelearningmastery.com/cross-entropy-for-machine-learning/
[2]:https://machinelearningmastery.com/divergence-between-probability-distributions/

KL散度的理解

阅读数 893

没有更多推荐了,返回首页