信息量、熵、交叉熵、KL散度、JS散度雜談及代碼實現

信息量、熵、交叉熵、KL散度、JS散度雜談及代碼實現

信息量

任何事件都會承載著一定的信息量,包括已經發生的事件和未發生的事件,只是它們承載的信息量會有所不同。如昨天下雨這個已知事件,因為已經發生,既定事實,那么它的信息量就為 0。如明天會下雨這個事件,因為未有發生,那么這個事件的信息量就大。

從上面例子可以看出信息量是一個與事件發生概率相關的概念,而且可以得出,事件發生的概率越小,其信息量越大。這也很好理解,比如某明星被爆出軌、逃稅等,這種事件信息量就很大,我們在口語中也會稱這種新聞 “信息量很大” ,因為是小概率事件,然而近幾年看起來好像已經不是小概率事件了。而對于我是我媽生的,這種事件,信息量就幾乎為零,因為這是確定事件。

另外,獨立時間的信息量是可疊加的,比如 ”a. 張三喝了阿薩姆紅茶,b. 李四喝了英式紅茶“ 的信息量就應該是a和b的信息量之和,如果張三李四喝什么茶是兩個獨立事件。

我們已知某個事件的信息量是與它發生的概率有關,那我們可以通過如下公式計算信息量:假設 XXX 是一個離散型隨機變量,其取值集合為 xxx ,概率分布函數 P(x)=Pr(X=x),x∈XP(x)=Pr(X=x),x\in XP(x)=Pr(X=x),xX ,則定義事件 x=x0x=x_0x=x0? 的信息量為:
I(x0)=?logP(x0)I(x_0)=-logP(x_0) I(x0?)=?logP(x0?)
我們可以看到,當某個時間的概率為1時,即其一定會發生,則此時它的信息量為0:I=?log1=0I=-log1=0I=?log1=0

熵就是信息量的期望,即:
S(x)=?∑iP(xi)logP(xi)S(x)=-\sum_iP(x_i)logP(x_i) S(x)=?i?P(xi?)logP(xi?)

可以認為,熵表征的是隨機事件的不確定性的大小,即事件可能性越多、越不確定,熵越大。這從公式中也可以看出來:

  • P(xi)P(x_i)P(xi?) 作為事件的概率肯定小于 1,取對數肯定小于 0,再取負號肯定大于 0。也就是說,熵累加的每一項都是正數,因此:可能性越多,熵越大。
  • 再看每一項的確定性,當 P(xi)=1P(x_i)=1P(xi?)=1000 ,分別代表必定發生或必定不發生,這兩種情況事件的確定性最小,從式子中也可以看出 P(xi)=1P(x_i)=1P(xi?)=1000 ,該項都為 0。而當 P(xi)P(x_i)P(xi?) 的值在 0-1 中間某點時,事件非常不確定,此時該項值較大。因此說,越不確定,熵越大。

KL散度

以上說的都是某一個事件的信息量,如果我們另有一個獨立的隨機事件,我們該怎么計算事件A和事件B的差別?我們先介紹默認的計算方法:KL散度,有時又稱相對熵、KL距離,實際上,雖然可以叫做KL距離,但它絕不是嚴格意義上的距離,因為KL散度不具有對稱性,即A對B的KL散度 和 B對A的KL散度是不一樣的。

KL散度的數學定義:對于離散事件
DKL=(A∣∣B)=∑iPA(xi)log(PA(xi)PB(xi))=∑iPA(xi)logPA(xi)?PA(xi)logPB(xi)D_{KL}=(A||B)=\sum_iP_A(x_i)log(\frac{P_A(x_i)}{P_B(x_i)})=\sum_iP_A(x_i)logP_A(x_i)-P_A(x_i)logP_B(x_i) DKL?=(A∣∣B)=i?PA?(xi?)log(PB?(xi?)PA?(xi?)?)=i?PA?(xi?)logPA?(xi?)?PA?(xi?)logPB?(xi?)
而對于連續事件,我們把求和改成積分即可。

可以看到,KL散度有這么幾個特點:

  • 當兩個事件完全相同時,即 PA=PBP_A=P_BPA?=PB? 時,DKL=0D_{KL}=0DKL?=0
  • 如果把 A、BA、BAB 的位置互換,則上式右邊的值也會不同,KL散度不具有對稱性,即 DKL(A∣∣B)≠DKL(B∣∣A)D_{KL}(A||B) \ne D_{KL}(B||A)DKL?(A∣∣B)=DKL?(B∣∣A)
  • 可以發現,上式右邊的左半部分 ∑iPA(xi)logPA(xi)\sum_i P_A(x_i)logP_A(x_i)i?PA?(xi?)logPA?(xi?) 其實就是事件 A 的熵,這點也是非常重要發現。

有這樣的結論: A對B的KL散度由A自己的熵值和B在A上的期望共同決定,當使用A對B的KL散度來衡量兩個分布的差異時,就是求A、B的對數差在A上的期望值。

交叉熵

終于來到了我們最熟悉的交叉熵,它是分類任務的最常用的損失函數,每個煉丹師在最開始拿MNIST手寫數字分類做Hello World時,應該都使用的交叉熵損失函數。

可是我們上面已經介紹了:KL散度可以用來衡量兩個分布的差異,那為什么不直接拿KL散度來做損失函數呢?我們先來對比一下A的熵、A對B的KL散度和A對B的交叉熵三者的公式:

  • A的熵:S(A)=?∑iPA(xi)logPA(xi)S(A)=-\sum_iP_A(x_i)logP_A(x_i)S(A)=?i?PA?(xi?)logPA?(xi?)
  • A對B的KL散度:DKL(A∣∣B)=∑iPA(xi)logPA(xi)?PA(xi)logPB(xi)D_{KL}(A||B)=\sum_iP_A(x_i)logP_A(x_i)-P_A(x_i)logP_B(x_i)DKL?(A∣∣B)=i?PA?(xi?)logPA?(xi?)?PA?(xi?)logPB?(xi?)
  • A對B的交叉熵:H(A,B)=?∑iPA(xi)logPB(xi)H(A,B)=-\sum_iP_A(x_i)logP_B(x_i)H(A,B)=?i?PA?(xi?)logPB?(xi?)

是不是越看越感覺這哥仨的某一部分有些像,它們之間應該是存在某種關系的。的確是這樣的,有:
DKL(A∣∣B)=H(A,B)?I(A)D_{KL}(A||B)=H(A,B)-I(A) DKL?(A∣∣B)=H(A,B)?I(A)
KL散度=交叉熵-熵

也就是說,KL散度與交叉熵的不同就體現在A本身的熵值上,如果A本身的熵值是一個常量,那么優化KL散度和優化交叉熵實質上就是等價的了

再補充兩個交叉熵的性質:

  • 自己與自己的交叉熵即自己的熵值,即 H(A,A)=S(A)H(A,A)=S(A)H(A,A)=S(A)
  • 與KL散度類似,交叉熵也不具有對稱性,即 H(A,B)≠H(B,A)H(A,B)\ne H(B,A)H(A,B)=H(B,A)

將交叉熵作為損失函數

在我們訓練優化機器學習模型時,我們希望學到的是真實數據的分布 PReal(x)P_{Real}(x)PReal?(x),但這只是理想情況,我們不可能得到理想的真實分布。我們實際中一般都是通過在大規模的有標注訓練數據分布 PLabel(x)P_{Label}(x)PLabel?(x) 上來近似 PReal(x)P_{Real}(x)PReal?(x)

在訓練中,如果我們用 KL 散度來表示分布之間的差異,那么我們希望的就是模型學習到的分布 PModel(x)P_{Model}(x)PModel?(x) 能夠與標注訓練數據的分布差異越小越好,也就是說我們要最小化這樣的KL散度:DKL(Label∣∣Model)D_{KL}(Label||Model)DKL?(Label∣∣Model)

可以看到,這里的 PLabelP_{Label}PLabel? 就相當于上面的 PAP_APA? ,而 PModelP_{Model}PModel? 就相當于 PBP_BPB?。而我們的標簽的分布 PLabelP_{Label}PLabel? 的熵值還真就是個常量,更準確地說:標簽的分布對于待更新的模型參數來說,是常量。因為標簽值不對模型參數進行求導,它的分布是固定的,是不受模型參數變化的影響的。那么我們要最小化 DKL(Label∣∣Model)D_{KL}(Label||Model)DKL?(Label∣∣Model) 也就等價與計算交叉熵 $H(Label,Model) $了。而交叉熵算起來又更為方便,因此我們一般就將交叉熵作為損失函數了。

JS散度

JS散度又是怎么回事呢?我們看到,上面的KL散度和交叉熵都是不對稱的形式,這在很多問題中是不合適的。因此JS散度的提出,解決了KL散度的不對稱性的問題。

JS散度的公式如下:
JS(A∣∣B)=12KL(A∣∣A+B2)+12KL(B∣∣A+B2)JS(A||B)=\frac{1}{2}KL(A||\frac{A+B}{2})+\frac{1}{2}KL(B||\frac{A+B}{2}) JS(A∣∣B)=21?KL(A∣∣2A+B?)+21?KL(B∣∣2A+B?)
JS散度有這樣的性質:

  • 值域范圍[0,1][0,1][0,1]
  • 具有對稱性,即 JS(A∣∣B)=JS(B∣∣A))JS(A||B)=JS(B||A))JS(A∣∣B)=JS(B∣∣A)),這從公式里也能看出來,A、BA、BAB 互換還是一樣的。

代碼實現及測試

以下根據公式手動實現了熵、KL 散度、JS 散度的計算,并與 scipy 庫中的實現進行了對比。

import numpy as np
from scipy.stats import entropy
from scipy.spatial.distance import jensenshannondef calc_entropy(probs):# probs.shape: [n, ]log_probs = np.log2(probs)ent = -1 * np.sum(probs * log_probs)return entdef calc_KL_divergence(pa, pb):log_pa = np.log2(pa)log_pb = np.log2(pb)kl = np.sum(pa * log_pa - pa * log_pb)return kldef calc_JS_divergence(pa, pb):pc = 0.5 * (pa + pb)js = 0.5 * calc_KL_divergence(pa, pc) + 0.5 * calc_KL_divergence(pb, pc)return jsif __name__ == '__main__':a = np.array( [0.1, 0.2, 0.7] )b = np.array( [0.2, 0.3, 0.5] )sa = calc_entropy(a)sa_ = entropy(a, base=2)sb = calc_entropy(b)sb_ = entropy(b, base=2)print(f"entropy of a: {sa}, {sa_}")print(f"entropy of b: {sb}, {sb_}")kl_ab = calc_KL_divergence(a, b)kl_ab_ = entropy(a, b, base=2)kl_ba = calc_KL_divergence(b, a)kl_ba_ = entropy(b, a, base=2)print(f"kl of a->b: {kl_ab}, {kl_ab_}")print(f"kl of b->a: {kl_ba}, {kl_ba_}")js_ab = calc_JS_divergence(a, b)js_ab_ = jensenshannon(a, b, base=2)print(f"js of a, b: {js_ab}, {js_ab}")

Ref

https://blog.csdn.net/qq_36552489/article/details/103793667

https://www.zhihu.com/question/65288314

https://blog.csdn.net/FrankieHello/article/details/80614422

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532609.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CTFHUB《Web-信息泄露-備份文件下載》網站源碼,

1.網站源碼 三種方法: 方法一:dirsearch掃描git泄露 有文件下載 拿到flag 方法二:御劍(超時10s) 御劍其實也可以掃出來,但是一般我們掃域名超時時間都是三秒,本環境中需要超時10秒才能得到…

Linux下C/C++程序編譯鏈接加載過程中的常見問題及解決方法

Linux下C/C程序編譯鏈接加載過程中的常見問題及解決方法 1 頭文件包含的問題 報錯信息 該錯誤通常發生在編譯時&#xff0c;常見報錯信息如下&#xff1a; run.cpp:2:10: fatal error: dlpack/dlpack.h: No such file or directory#include <dlpack/dlpack.h>^~~~~~~…

DVWA Command Injection 練習總結

low: 首先查看源碼沒有對字符進行任何過濾 target參數為將要ping的ip地址&#xff0c;比如在輸入框輸入127.0.0.1后&#xff0c;對于windows系統&#xff0c;會發出ping 127.0.0.1操作。 這里可以引入命令行的幾種操作方式&#xff1a; A && B&#xff1a; 先執行A…

在vimrc中設置record

在vimrc中設置record Vim的record功能在大量重復操作的場景下非常實用&#xff0c;但是&#xff0c;一般我們都要每次進入Vim時重新錄制record。而對于一些非常常用的record&#xff0c;我們想讓它永久地保持&#xff0c;我們知道這種需求需要借助Vim的配置文件vimrc。但是具體…

DVWA sql注入 WP

sql注入基本思路&#xff1a; 1.源碼 2.判斷數字型和字符型 3.猜測字段數 4.查詢數據庫中的字段 5.查詢表中的字段 6.查詢user表中的字段 7.拿字段中數據 low: 1.源碼&#xff1a; <?phpif( isset( $_REQUEST[ Submit ] ) ) {// Get input$id $_REQUEST[ id ];// Check…

cmake find_package路徑詳解

cmake find_package路徑詳解 轉自&#xff1a;https://zhuanlan.zhihu.com/p/50829542 經常在Linux下面寫C程序&#xff0c;尤其是需要集成各種第三方庫的工程&#xff0c;肯定對find_package指令不陌生。 這是條很強大的指令。可以直接幫我們解決整個工程的依賴問題&#x…

DVWA File Inclusion——Writeup

文件包含&#xff1a; 即File Inclusion&#xff0c;意思是文件包含&#xff08;漏洞&#xff09;&#xff0c;是指當服務器開啟allow_url_include選項時&#xff0c;就可以通過php的某些特性函數&#xff08;include()&#xff0c;require()和include_once()&#xff0c;requi…

PyTorch JIT與TorchScript

PyTorch JIT與TorchScript 轉自&#xff1a;https://zhuanlan.zhihu.com/p/370455320 如果搜索 PyTorch JIT&#xff0c;找到的將會是「TorchScript」的文檔&#xff0c;那么什么是 JIT 呢&#xff1f;JIT 和 TorchScript 又有什么聯系&#xff1f; 文章只會關注概念的部分&a…

DVWA Cross Site Request Forgery (CSRF) -------WP

CSRF: 介紹 CSRF跨站點請求偽造(Cross—Site Request Forgery)&#xff0c;跟XSS攻擊一樣&#xff0c;存在巨大的危害性&#xff0c;你可以這樣來理解&#xff1a; 攻擊者盜用了你的身份&#xff0c;以你的名義發送惡意請求&#xff0c;對服務器來說這個請求是完全合法的&…

PyTorch C++ API libtorch 簡介

PyTorch C API libtorch 簡介 翻譯自 PyTorch 官方文檔&#xff1a;https://pytorch.org/cppdocs/index.html#acknowledgements 整體劃分 根據 PyTorch 官方文檔 的介紹&#xff0c;PyTorch的C API可以粗略分為以下五個部分&#xff1a; ATen&#xff1a;基礎的張量和數學計…

DVWA upload

LOW medium high impossible

安裝 PyTorch C++ API libtorch 及一個最小例子

安裝 PyTorch C API libtorch 及一個最小例子 翻譯自&#xff1a;https://pytorch.org/cppdocs/installing.html 我們提供依賴 PyTorch 所需的所有頭文件、庫和 CMake 配置文件的二進制分發版。我們將此發行版稱為 LibTorch&#xff0c;您可以在我們的網站上下載包含最新 Lib…

ImageNet 1K 類別名與索引的對應關系

ImageNet 1K 類別名與索引的對應關系 轉自&#xff1a;http://befree2008.github.io/2018/10/05/20181005_ImageNet1000%E5%88%86%E7%B1%BB%E5%90%8D%E7%A7%B0%E5%92%8C%E7%BC%96%E5%8F%B7/ ImageNet 2012 1000個類名稱和編號。ILSVRC2012_img_train.tar 這個文件解壓出來都是…

sqlilab--writeup (5~6) 布爾盲注

1.# 和 – &#xff08;有個空格&#xff09;表示注釋&#xff0c;可以使它們后面的語句不被執行。在url中&#xff0c;如果是get請求**(記住是get請求&#xff0c;也就是我們在瀏覽器中輸入的url)** &#xff0c;解釋執行的時候&#xff0c;url中#號是用來指導瀏覽器動作的&am…

PyTorch導出JIT模型并用C++ API libtorch調用

PyTorch導出JIT模型并用C API libtorch調用 本文將介紹如何將一個 PyTorch 模型導出為 JIT 模型并用 PyTorch 的 CAPI libtorch運行這個模型。 Step1&#xff1a;導出模型 首先我們進行第一步&#xff0c;用 Python API 來導出模型&#xff0c;由于本文的重點是在后面的部署…

sqli-lab--writeup(7~10)文件輸出,時間布爾盲注

前置知識點&#xff1a; 1、outfile是將檢索到的數據&#xff0c;保存到服務器的文件內&#xff1a; 格式&#xff1a;select * into outfile “文件地址” 示例&#xff1a; mysql> select * into outfile ‘f:/mysql/test/one’ from teacher_class; 2、文件是自動創建…

樹莓派4B (aarch64) 安裝PyTorch 1.8 的可行方案

樹莓派4B (aarch64) 安裝PyTorch 1.8 的可行方案 最終可行方案 試了一堆方案&#xff08;源碼編譯、Fast.ai的安裝文件等&#xff09;之后&#xff0c;終于找到一個可行的方案。是在 PyTorch 官方討論社區的一個帖子中找到的&#xff0c;在回復中一個大佬給出了自己在2021年1…

sqli-lab———writeup(11~17)

less11 用戶名提交單引號顯示sql語法錯誤&#xff0c;故存在sql注入 根據單引號報錯&#xff0c;在用戶名和密碼任意行輸入 萬能密碼&#xff1a;‘ or 11# 輸入后username語句為&#xff1a;SELECT username, password FROM users WHERE username or 11; 雙引號 password語…

深入理解Python中的全局解釋鎖GIL

深入理解Python中的全局解釋鎖GIL 轉自&#xff1a;https://zhuanlan.zhihu.com/p/75780308 注&#xff1a;本文為蝸牛學院資深講師卿淳俊老師原創&#xff0c;首發自公眾號https://mp.weixin.qq.com/s/TBiqbSCsjIbNIk8ATky-tg&#xff0c;如需轉載請私聊我處獲得授權并注明出處…

sqli-lab————Writeup(18~20)各種頭部注入

less18 基于錯誤的用戶代理&#xff0c;頭部POST注入 admin admin 登入成功&#xff08;進不去重置數據庫&#xff09; 顯示如下 有user agent參數&#xff0c;可能存在注入點 顯示版本號&#xff1a; 爆庫&#xff1a;User-Agent:and extractvalue(1,concat(0x7e,(select …