KL散度理论讲解

KL散度(Kullback-Leibler divergence)

概念:

  • KL散度( Kullback-Leibler divergence)也被称为相对熵,是一种非对称度量方法,常用于度量两个概率分布之间的距离。
  • KL散度也可以衡量两个随机分布之间的距离,两个随机分布的相似度越高的,它们的KL散度越小,当两个随机分布的差别增大时,它们的KL散度也会增大,因此KL散度可以用于比较文本标签或图像的相似性。
  • 基于KL散度的演化损失函数有JS散度函数。JS散度也称JS距离,用于衡量两个概率分布之间的相似度,它是基于KL散度的一种变形,消除了KL散度非对称的问题,与KL散度相比,它使得相似度判别更加准确。
  • 相对熵是恒大于等于0的。当且仅当两分布相同时,相对熵等于0。
  • 注意事项: 需提前将输入计算 log-probabilities,如通过nn.logsoftmax()

作用: 一种用来度量两个概率分布之间差异的方法。
定义: 对于两个概率分布P和Q,KL散度是P分布相对于Q分布的信息量:
K L ( P ∣ ∣ Q ) = ∑ p ( x ) ∗ l o g ( p ( x ) / q ( x ) ) KL(P||Q) = ∑ p(x) * log(p(x)/q(x)) KL(P∣∣Q)=p(x)log(p(x)/q(x))
这其中,p(x)和q(x)分别表示P和Q分布在x上的概率。
KL散度数学公式

KL散度有以下几个重要性质:

  1. 非对称性:KL(P||Q) != KL(Q||P)
  2. KL(P||Q) >= 0。KL散度总是非负的,因为log函数的自变量永远大于0。
  3. 只有在P=Q时,KL散度等于0。 0表示两个分布没有差异,最大差异时KL散度最大。
  4. KL散度并不是一个真正的距离度量。它不满足三角不等式,不能直接用于聚类等任务。

KL散度常用于以下场景:

  1. 评估概率模型。通过比较模型分布和真实分布的KL散度,评估模型拟合的好坏。
  2. . 下界最小化。 variational autoencoder使用KL散度作为重构分布和先验分布之间的正则项。
  3. 信息增益。KL散度可以理解为从分布Q转移到分布P所获得的额外信息量。
  4. 评估概率聚合模型。比如Gaussian mixture model可以通过评估各 high-dimensional 分布与真实分布的KL散度来进行聚合。

所以,总的来说,KL散度是用来评估两个概率分布差异性的重要工具。它满足非负性和可达性,但不满足对称性和三角不等式,所以不是一个距离度量。KL散度有许多重要的应用,特别是在评估模型、下界最小化、信息论等机器学习领域。

pytorch中的调用:

# ---- reduction: none/sum/mean/batchmean、batchmean:batchsize维度求平均值
nn.KLDivLoss(size_average=None, reduce=None, reduction='mean')

简单代码实现:

import numpy as np

def kl_divergence(p, q):
    """计算KL散度"""
    p = np.asarray(p, dtype=np.float)
    q = np.asarray(q, dtype=np.float)
    
    return np.sum(p * np.log(p / q))

# 示例
p = [0.1, 0.7, 0.2]  # 分布p
q = [0.2, 0.5, 0.3]  # 分布q 

kl = kl_divergence(p, q)
print(kl)  # 输出0.08512282595722163

我们实现了kl_divergence函数来计算KL散度。它接收两个概率数组p和q,并返回p相对于q的KL散度。
在示例中,我们定义了两个简单的概率分布p和q,并调用函数来计算它们之间的KL散度,输出为0.201。

KL散度的另一个常见实现是使用scipy.stats.entropy函数:

from scipy.stats import entropy 

kl = entropy(p, q)  # 也可以计算KL散度
#0.08512282595722163
#entropy函数更为通用,可以计算KL散度、香农熵等信息论度量。

在实践中,我们经常将KL散度应用于以下场景:

  1. 评估Gaussain分布或高斯混合模型:
import numpy as np
from scipy.stats import norm

# 采样100个点在-3到3之间
x = np.linspace(-3, 3, 100)

# 真实分布参数  
mean_true, std_true = 0, 1  

# 模型分布参数  
mean_est, std_est = 0.2, 1.2  

# 计算KL散度
p = norm.pdf(x, mean_true, std_true)  
q = norm.pdf(x, mean_est, std_est)
kl = kl_divergence(p, q) # 0.776629000396034
  1. 评估概率模型的拟合程度:
from sklearn.linear_model import LogisticRegression
import numpy as np

# 生成一些训练数据
X_train = np.random.randn(100, 5)   
y_train = np.random.randint(3, size=100)  # 0,1,2三个类别

# 生成一些测试数据
X_test = np.random.randn(50, 5)

#以逻辑回归为例
lr = LogisticRegression()
lr.fit(X_train, y_train)

# 概率模型预测分布
y_preds = lr.predict_proba(X_test)  

# 真实标签分布 
y_test_dist = [0.2, 0.3, 0.5]   

# 计算KL散度  
kl = kl_divergence(y_test_dist, y_preds) 
#7.71060178021998
  1. 作为variational autoencoder的正则化项:
z_mean, z_std = encoder(x)  # 编码器输出(可以自己设计)
z = z_mean + z_std * np.random.randn(*z_std.shape)  # 采样
x_recon = decoder(z)        # 解码  

# 先验分布p(z)
p = np.array([0.5, 0.5])  

# q(z|x)
q = np.array([0.4, 0.6])   

# kl项
kl = kl_divergence(p, q) 
loss = loss_func(x, x_recon) + kl   # loss添加kl正则化项
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Miss.wei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值