您好,登錄后才能下訂單哦!
小編給大家分享一下pytorch如何計算kl散度,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
先附上官方文檔說明:https://pytorch.org/docs/stable/nn.functional.html
torch.nn.functional.kl_div(input, target, size_average=None, reduce=None, reduction='mean')
Parameters
input – Tensor of arbitrary shape
target – Tensor of the same shape as input
size_average (bool, optional) – Deprecated (see reduction). By default, the losses are averaged over each loss element in the batch. Note that for some losses, there multiple elements per sample. If the field size_average is set to False, the losses are instead summed for each minibatch. Ignored when reduce is False. Default: True
reduce (bool, optional) – Deprecated (see reduction). By default, the losses are averaged or summed over observations for each minibatch depending on size_average. When reduce is False, returns a loss per batch element instead and ignores size_average. Default: True
reduction (string, optional) – Specifies the reduction to apply to the output: 'none' | 'batchmean' | 'sum' | 'mean'. 'none': no reduction will be applied 'batchmean': the sum of the output will be divided by the batchsize 'sum': the output will be summed 'mean': the output will be divided by the number of elements in the output Default: 'mean'
第一個參數傳入的是一個對數概率矩陣,第二個參數傳入的是概率矩陣。這里很重要,不然求出來的kl散度可能是個負值。
比如現在我有兩個矩陣X, Y。因為kl散度具有不對稱性,存在一個指導和被指導的關系,因此這連個矩陣輸入的順序需要確定一下。
如果現在想用Y指導X,第一個參數要傳X,第二個要傳Y。就是被指導的放在前面,然后求相應的概率和對數概率就可以了。
import torch
import torch.nn.functional as F
# 定義兩個矩陣
x = torch.randn((4, 5))
y = torch.randn((4, 5))
# 因為要用y指導x,所以求x的對數概率,y的概率
logp_x = F.log_softmax(x, dim=-1)
p_y = F.softmax(y, dim=-1)
kl_sum = F.kl_div(logp_x, p_y, reduction='sum')
kl_mean = F.kl_div(logp_x, p_y, reduction='mean')
print(kl_sum, kl_mean)
>>> tensor(3.4165) tensor(0.1708)
補充:pytorch中的kl散度,為什么kl散度是負數?
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)
先確保對第一個輸入進行了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)
以上是“pytorch如何計算kl散度”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。