欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pytorch中的kl散度,为什么kl散度是负数?

程序员文章站 2024-02-11 16:41:10
...

F.kl_div()或者nn.KLDivLoss()是pytroch中计算kl散度的函数,它的用法有很多需要注意的细节。

输入

第一个参数传入的是一个对数概率矩阵,第二个参数传入的是概率矩阵。并且因为kl散度具有不对称性,存在一个指导和被指导的关系,因此这连个矩阵输入的顺序需要确定一下。如果现在想用Y指导X,第一个参数要传X,第二个要传Y。就是被指导的放在前面,然后求相应的概率和对数概率就可以了。

所以,一随机初始化一个tensor为例,对于第一个输入,我们需要先对这个tensor进行softmax(确保各维度和为1),然后再取log;对于第二个输入,我们需要对这个tensor进行softmax。

import torch
import torch.nn.functional as F

a = torch.tensor([[0,0,1.1,2,0,10,0],[0,0,1,2,0,10,0]])
log_a =F.log_softmax(a)

b = torch.tensor([[0,0,1.1,2,0,7,0],[0,0,1,2,0,10,0]])
softmax_b =F.softmax(b,dim=-1)

kl_mean = F.kl_div(log_a, softmax_b, reduction='mean')
print(kl_mean)

为什么KL散度计算出来为负数

先确保对第一个输入进行了softmax+log操作,对第二个参数进行了softmax操作。不进行softmax操作就可能为负。

然后查看自己的输入是否是小数点后有很多位,当小数点后很多位的时候,pytorch下的softmax会产生各维度和不为1的现象,导致kl散度为负,如下所示:

a = torch.tensor([[0.,0,0.000001,0.0000002,0,0.0000007,0]])
log_a =F.log_softmax(a,dim=-1)
print("log_a:",log_a)

b = torch.tensor([[0.,0,0.000001,0.0000002,0,0.0000007,0]])
softmax_b =F.softmax(b,dim=-1)
print("softmax_b:",softmax_b)

kl_mean = F.kl_div(log_a, softmax_b,reduction='mean')
print("kl_mean:",kl_mean)

输出如下,我们可以看到softmax_b的各维度和不为1:

pytorch中的kl散度,为什么kl散度是负数?
微信扫码关注公众号,后台回复「电子书福利」,35本深度学习、机器学习、自然语言处理、算法领域的经典电子书,我们将一次性统统分享给大家!
pytorch中的kl散度,为什么kl散度是负数?

pytorch中的kl散度,为什么kl散度是负数?
pytorch中的kl散度,为什么kl散度是负数?

相关标签: 机器学习