• KL 散度(相对熵)


    KL 散度又叫 相对熵,是衡量 两个概率分布 匹配程度的指标,KL 散度越大,分布差异越大,匹配度越低 

    计算公式如下

    或者

     

    其中 p是 目标分布,或者叫被匹配的分布,或者叫模板分布,q 是去匹配的分布;

    试想,p 是真实值,q 是预测值,岂不是 个 loss function

    性质

    如果 两个分布 完全匹配,Dkl=0;

    KL 散度是非对称的,即 D(p||q) 不一定等于 D(q||p);

    KL 散度 取值范围 大于等于 0;        【参考资料2有证明,有个 杰森不等式】

    直观解释

    KL 散度左边是个 概率,右边是个 log(p/q);

    先看下右边的 log,如果 p > q,log 为正,如果 p < q,log 为负,如果 p = q,log 为 0;

    为了使 KL 是个期望值,加入了权重 p,也就是说,p 使得 高概率的匹配区域 比 低概率的匹配区域 更加重要

    p(xi) 大,说明 xi 对应的 占比大,占比大的 是不是该 重视一下呢,而 乘以 p(xi) 刚好可以使得其 权重增大,代表 重视了

    直观而言,优先正确匹配近似分布中真正高可能性的事件是有实际价值的。
    从数学上讲,这能让你自动忽略落在真实分布的支集(支集(support)是指分布使用的 X 轴的全长度)之外的分布区域。
    另外,这还能避免计算 log(0) 的情况——如果你试图计算落在真实分布的支集之外的任意区域的这个对数项,就可能出现这种情况。

    Python 实现

    import numpy as np
    import scipy.stats      # 不能只 import scipy
    
    # 随机生成两个离散型分布
    x = [np.random.randint(1, 11) for i in range(10)]
    px = x / np.sum(x)
    print(px)
    y = [np.random.randint(1, 11) for i in range(10)]
    py = y / np.sum(y)
    print(py)
    
    
    ##### scipy API进行计算
    # scipy计算函数可以处理非归一化情况,因此这里使用
    # scipy.stats.entropy(x, y)或scipy.stats.entropy(px, py)均可
    KL = scipy.stats.entropy(x, y)
    print(KL)           # 0.14931583282835742
    
    
    ##### 手动实现
    KL = 0.0
    for i in range(10):
        KL += px[i] * np.log(px[i] / py[i])
    print(KL)           # 0.14931583282835742

    Pytorch 中 KL 计算出现负值

    需加个 log

    import torch
    
    KL_criterion = torch.nn.KLDivLoss(size_average=False)
    a = torch.tensor([0.2, 0.1, 0.3, 0.4])
    b = torch.tensor([0.1, 0.2, 0.3, 0.4])
    
    loss1 = KL_criterion(a.log(), b)
    print(loss1)        # tensor(0.0693)    加 log 正确
    loss2 = KL_criterion(a, b)
    print(loss2)        # tensor(-1.5699)   不加 log 为 负数,错误

    注意:分布的结果相加需要为1

    参考资料:

    https://www.jianshu.com/p/7b7c0777f74d  直观解读KL散度的数学概念    讲得比较好,主要参考,里面还有其他内容,可以看看

    https://zhuanlan.zhihu.com/p/39682125  KL散度理解

    https://www.cnblogs.com/hxsyl/p/4910218.html  浅谈KL散度

    https://www.zhihu.com/question/384982085/answer/1856014994  pytorch KL散度为负数?

  • 相关阅读:
    EF6学习笔记二十五:分布式事务
    EF6学习笔记二十四:事务
    EF6学习笔记二十三:拦截器异常、耗时监控
    EF6学习笔记二十二:初识NLog日志框架
    EF6学习笔记二十一:格式化日志输出
    EF6学习笔记二十:简单日志记录
    EF6学习笔记十九:不一样的复杂类型
    EF6学习笔记十八:DetectChanges
    EF6学习笔记十七:快照追踪与代理追踪性能测试
    EF6学习笔记十六:变更追踪
  • 原文地址:https://www.cnblogs.com/yanshw/p/16045519.html
Copyright © 2020-2023  润新知