pytorch 實現(xiàn)計算 kl散度 F.kl_div()
先附上官方文檔說明: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'
然后看看怎么用:
第一個參數(shù)傳入的是一個對數(shù)概率矩陣,第二個參數(shù)傳入的是概率矩陣。這里很重要,不然求出來的kl散度可能是個負值。
比如現(xiàn)在我有兩個矩陣X, Y。因為kl散度具有不對稱性,存在一個指導和被指導的關(guān)系,因此這連個矩陣輸入的順序需要確定一下。
舉個例子:
如果現(xiàn)在想用Y指導X,第一個參數(shù)要傳X,第二個要傳Y。就是被指導的放在前面,然后求相應(yīng)的概率和對數(shù)概率就可以了。
import torch import torch.nn.functional as F # 定義兩個矩陣 x = torch.randn((4, 5)) y = torch.randn((4, 5)) # 因為要用y指導x,所以求x的對數(shù)概率,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散度是負數(shù)?
F.kl_div()或者nn.KLDivLoss()是pytroch中計算kl散度的函數(shù),它的用法有很多需要注意的細節(jié)。
輸入
第一個參數(shù)傳入的是一個對數(shù)概率矩陣,第二個參數(shù)傳入的是概率矩陣。并且因為kl散度具有不對稱性,存在一個指導和被指導的關(guān)系,因此這連個矩陣輸入的順序需要確定一下。如果現(xiàn)在想用Y指導X,第一個參數(shù)要傳X,第二個要傳Y。就是被指導的放在前面,然后求相應(yīng)的概率和對數(shù)概率就可以了。
所以,一隨機初始化一個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散度計算出來為負數(shù)
先確保對第一個輸入進行了softmax+log操作,對第二個參數(shù)進行了softmax操作。不進行softmax操作就可能為負。
然后查看自己的輸入是否是小數(shù)點后有很多位,當小數(shù)點后很多位的時候,pytorch下的softmax會產(chǎn)生各維度和不為1的現(xiàn)象,導致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:
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
selenium+python實現(xiàn)1688網(wǎng)站驗證碼圖片的截取功能
這篇文章主要介紹了selenium+python實現(xiàn)1688網(wǎng)站驗證碼圖片的截取,需要的朋友可以參考下2018-08-08Python 對象序列化與反序列化之pickle json詳細解析
我們知道在Python中,一切皆為對象,實例是對象,類是對象,元類也是對象。本文正是要聊聊如何將這些對象有效地保存起來,以供后續(xù)使用2021-09-09Python Pandas批量讀取csv文件到dataframe的方法
這篇文章主要介紹了Python Pandas批量讀取csv文件到dataframe的方法,需要的朋友可以參考下2018-10-10Python3通過chmod修改目錄或文件權(quán)限的方法示例
這篇文章主要介紹了Python3通過chmod修改目錄或文件權(quán)限的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06python爬蟲豆瓣網(wǎng)的模擬登錄實現(xiàn)
這篇文章主要介紹了python爬蟲豆瓣網(wǎng)的模擬登錄實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-08-08Python threading Local()函數(shù)用法案例詳解
這篇文章主要介紹了Python threading Local()函數(shù)用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09Python 文件操作之讀取文件(read),文件指針與寫入文件(write),文件打開方式示例
這篇文章主要介紹了Python 文件操作之讀取文件(read),文件指針與寫入文件(write),文件打開方式,結(jié)合實例形式分析了Python文件讀寫相關(guān)的指針、打開方式等相關(guān)操作技巧,需要的朋友可以參考下2019-09-09