【问题标题】:KL Divergence for two probability distributions in PyTorchPyTorch 中两个概率分布的 KL 散度
【发布时间】:2018-09-27 21:48:10
【问题描述】:

我有两个概率分布。我应该如何在 PyTorch 中找到它们之间的 KL 散度?常规交叉熵只接受整数标签。

【问题讨论】:

    标签: machine-learning pytorch


    【解决方案1】:

    是的,PyTorch 在 torch.nn.functional 下有一个名为 kl_div 的方法,可以直接计算张量之间的 KL-devergence。假设您有相同形状的张量ab。您可以使用以下代码:

    import torch.nn.functional as F
    out = F.kl_div(a, b)
    

    更多详情,请参阅上述方法文档。

    【讨论】:

    • 是的,我见过那个函数,但它返回的是一个负值。我弄清楚问题出在哪里:我必须使用输入的log,以及目标的实际值。现在,它工作正常。
    • 你也可以用pytorch的张量方法写kl-equation。这很容易。
    【解决方案2】:

    函数kl_divwiki的解释不一样。

    我使用以下:

    # this is the same example in wiki
    P = torch.Tensor([0.36, 0.48, 0.16])
    Q = torch.Tensor([0.333, 0.333, 0.333])
    
    (P * (P / Q).log()).sum()
    # tensor(0.0863), 10.2 µs ± 508
    
    F.kl_div(Q.log(), P, None, None, 'sum')
    # tensor(0.0863), 14.1 µs ± 408 ns
    

    kl_div 相比,速度更快

    【讨论】:

    • 它给出了相同的答案,因此没有证据表明它不一样。速度完全是一个单独的问题。
    • 在我的测试中,第一种计算 kl div 的方法更快:D
    • @AleksandrDubinsky 它与输入不同的是Q.log(),当脱离机器学习的上下文时,这非常不直观。
    • @BlackJack21 感谢您解释 OP 的含义。虽然有点不直观,但出于数值精度的原因,将概率保存在对数空间中通常很有用。不直观的是,一个输入在日志空间中,而另一个不在。 ¯_(ツ)_/¯
    • @AleksandrDubinsky 我同意你的观点,这种设计令人困惑。
    【解决方案3】:

    如果你有两个pytorch distribution object 形式的概率分布。那么你最好使用函数torch.distributions.kl.kl_divergence(p, q)。有关文档,请关注link

    【讨论】:

    • 它给了我 NotImplementedError:
    • 检查 pytorch 版本。我认为应该>1.0
    • torch.distributions.kl.kl_divergence 似乎需要向pytorch.org/docs/stable/… 注册分发版
    【解决方案4】:

    如果使用 Torch 分发版

    mu = torch.Tensor([0] * 100)
    sd = torch.Tensor([1] * 100)
    
    p = torch.distributions.Normal(mu,sd)
    q = torch.distributions.Normal(mu,sd)
    
    out = torch.distributions.kl_divergence(p, q).mean()
    out.tolist() == 0
    True
    

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多