L5.2 一個高維的機率,能不能拆成一串一維的機率?
本篇重用2 篇
不對 latent variable 積分,還能怎麼建模?
上一篇用 ELBO 處理 latent variable 積分難算的問題。現在換一種模型設計:想像寫訊息時,先寫第一個字,再依照前文接下一個字。每一步只需要回答「已經寫了這些字,下一個字可能是什麼?」
把這個直覺寫成機率,正是乘法定則(chain rule)。對一組變數 ,選定順序後有:
分解本身是恆等式,不是近似。 在有正機率的前綴上,反覆使用 conditional probability 的定義,便得到
一個高維的對數機率變成 個一維的對數機率相加。每一項都是一個普通的「給定一堆東西、預測下一個」的問題,也就是前面五個 class 的全部工具直接可用。
我們還是要學這些 conditional distributions。Bengio 等人 [1] 的 neural language model 就用網路做下一個詞的預測;van den Oord 等人 [2] 則把同一個做法用在像素上。
乘法定則沒有任何近似,
可是它把一個做不到的問題變成了做得到的——
那個「變簡單」是從哪裡來的,代價又付在哪?
課堂提問Q1
難在哪?具體地說:如果不用分解,直接讓一個網路輸出 的機率,你會卡在哪一步?而分解之後那一步為什麼變得可行?把兩種做法的成本各算一次。
先想一想,再展開看整理後的答案
卡在正規化。 一個網路很容易輸出一個「分數」——越像真的資料分數越高。但分數不是機率。要變成機率必須除以一個總和:
是對所有可能的 加總。 個位置、每個位置 種取值,那是 項。、 已經是 項;、(一段文字)是一個沒有名字的數。而且 依賴 ,所以每一步梯度下降都要重算一次。這就是能量模型難訓練的根本原因。
分解把這個和拆成 個小和。 每一項 是單一個座標上的分布,正規化只要對那一個座標的 種取值加總:
這就是 softmax。正規化項由一個 項的和,變成 L 個 K 項的和;網路處理上下文的成本則要另外算,不能把整個模型的總成本都寫成 。
乘積也自動正規化:先對最後一個座標加總,得到 1,再逐層往前加總。因此只要各 conditional density 能精確計算,這個模型的 joint likelihood 就能精確計算,不需要 ELBO。
代價在哪。 三個,本篇三節各處理一個。
- 每一項的條件是全部的前文。真的做到要 個不同大小的輸入,實務上要嘛截斷(只看前 個),要嘛用一個能吃變長輸入的架構。截斷就是丟掉結構,而那是有價的(第二節)。
- 抽樣要跑 次,而且是序列的—— 要等 算完。訓練可以平行(前文都是已知的真實資料),抽樣不行。這是自回歸模型最貴的地方(第三節)。
- 你必須選一個順序。理論上任何順序都對,實務上不是(第四節)。
丟掉條件,就是丟掉結構
先把「丟掉條件的代價」量出來。
設定:長度 的二元序列,由一條馬可夫鏈生出來(明天的天氣只看今天:Markov Chain 與 Transition Matrix)——第一位是公平的,之後每一位有機率 翻面、 維持。 小表示序列傾向一整段一整段同色。
拿一個逐位置獨立的模型去配它:。由對稱性它會學到每一位都是 ,所以
實測():
q = 0.05 KL = 7.419 nats
q = 0.10 KL = 5.521 nats
q = 0.30 KL = 1.234 nats
q = 0.50 KL = 0.000 nats
最後一列是對照組: 時相鄰位置本來就獨立,所以獨立模型完全正確,KL 精確為零。這一列存在的意義是確認前三列的數字量的是「結構」而不是別的東西。
前三列是代價本身:結構越強( 越小),忽略它越貴。 時 nats——換算成每個位元約 nats,也就是每一位你都在浪費大半個位元的資訊。
抽樣看得更直接:
真實鏈抽出來的序列 相鄰位置的切換率 0.1006 (真值 0.10)
逐位置獨立抽出來的 相鄰位置的切換率 0.4979 (必然是 0.50)
同樣的邊際分布,完全不同的樣本。 兩個模型在「每一位是 0 還是 1 的比例」上一模一樣,但一個生出一段段的色塊、另一個生出雪花雜訊。
逐座標獨立保留了各座標的 marginal,卻丟掉了座標之間的相依關係。
圖說: 兩組序列的邊際完全相同,差別只在相鄰關係;結構越強,獨立假設的 KL 代價越高。
能不能一次生出好幾格?
如果逐格生成太慢,一個想法是每次產生 B 格。但「一次產生」不代表一定要把它們設為獨立:若能抽出正確的 block joint distribution,仍然能保留原分布。下面只分析一種較簡單的近似:各格都看已有前綴,卻不看這個 block 內剛生成的其他格。
在上面的對稱鏈裡,離 block 起點 j 步後,與前綴最後一格不同的機率是
第一格仍用 ;越後面的格子,因為看不到中途的值,conditional entropy 變成 ,而不是 。假設 L 能被 B 整除,這種近似的最佳 KL 為
第一項來自沒有前綴的第一個 block;第二項來自其餘 blocks。取 :
| B | 生成輪數 | KL(nats) |
|---|---|---|
| 1 | 16 | 0.0000 |
| 2 | 8 | 1.3922 |
| 4 | 4 | 3.0798 |
| 8 | 2 | 4.5815 |
| 16 | 1 | 5.5210 |
這個例子讓我們看見的是:省掉 block 內的 conditioning,會改變 joint distribution。它不是所有平行解碼方法的下界,生成輪數減半也不代表 wall-clock time 恰好減半。
補充反過來的切法:區塊內部精確、區塊之間獨立
上面那個模型是「看前綴、塊內獨立」。還有一個方向相反的切法:塊內精確建模,但塊與塊之間完全不看彼此。同一條鏈:
B = 1 16 個獨立區塊 斷掉 15 個 KL = 5.521 nats
B = 2 8 個獨立區塊 斷掉 7 個 KL = 2.576
B = 4 4 個獨立區塊 斷掉 3 個 KL = 1.104
B = 8 2 個獨立區塊 斷掉 1 個 KL = 0.368
B = 16 1 個獨立區塊 斷掉 0 個 KL = 0.000是逐位置獨立, 則保留整條鏈。在這個切法裡,增大 B 能減少被切斷的依賴;但要如何表示、抽樣 block joint,仍是另一個問題。若直接列出全部組合,有 個值;若利用自回歸等結構,未必需要這張完整表。
兩個切法省略的是不同依賴,不能把它們的 B 直接對照。完整自回歸則保留所有前綴 conditioning,每次只正規化一個位置的 K 個選項,代價是生成時需依序呼叫模型。
補充真實資料的相依關係,要另外檢查
在「塊內精確、塊間獨立」的補充例子中,每切開一個相鄰關係的代價相同,是因為這條鏈的切換率固定。保留前綴卻讓塊內獨立,則要用正文的 conditional entropy 計算,不能沿用同一個斷邊公式。
真實資料可能有強烈的局部關係,也可能有關鍵的長距離關係,例如一句話前面的人名決定後面的指涉。距離遠不代表一定可以忽略。
是否能縮短上下文,應在 held-out data 上量:把長度從 k 改成 ,NLL 增加多少?再檢查重要的長距離任務,而不是只由距離猜測。
順序有沒有差
乘法定則對任何順序都成立。所以理論上,順序不影響任何事。
實務上會,而且原因很具體:模型族是受限的。如果模型只能看前一個變數(或前 個),那麼「哪些依賴看得到」就取決於你把變數排成什麼順序。
實測。三個二元變數: 是公平硬幣, 是另一個完全獨立的公平硬幣, 有 的機率相同(也就是 只跟 有關)。模型族固定為「一階鏈」:。
順序 x1 → x2 → x3 :KL(真‖模型) = 0.368064 nats
順序 x1 → x3 → x2 :KL(真‖模型) = 0.000000 nats
順序 x2 → x1 → x3 :KL(真‖模型) = 0.000000 nats
參考:完全不看條件的獨立模型 KL = 0.368064 nats
第一列和參考列一模一樣。 把不相干的 夾在 和 中間,一階鏈就完全接不到那個依賴——它付了「有條件模型」的成本,卻得到「獨立模型」的結果。而只要把 移到 旁邊(或把 移開),同一個模型族就精確無誤。
順序不改變真相,但它決定你的模型看不看得到真相。
這在實務上怎麼出現。 文字有一個天然的順序,所以這個問題不明顯。圖片沒有——把二維像素排成一維要選一種掃法,而任何掃法都會把「垂直方向的鄰居」變成相隔一整列的遠親。表格資料更糟:欄位之間沒有任何自然順序,而不同的順序可以差很多。
展開細節為什麼順序無關的模型不容易做
一個自然的想法是:既然順序是任意的,那就對所有順序取平均,或者訓練一個對所有順序都成立的模型。
這條路是可行的(order-agnostic 的訓練、把「哪些位置已知」當成一個隨機的遮罩),但它把問題變難了:模型現在要在每一種前文組合下都給出正確的條件分布,而那是 種組合而不是 種。用固定順序訓練時,模型只需要學會 個「看前綴」的函數。
所以這是一個標準的取捨:固定順序 = 容量花在少數幾個條件上、學得好,但順序選錯就接不到依賴;隨機順序 = 通用,但同樣的容量要攤到指數多的條件上。 實務上的折衷通常是用一個能看全部前文的架構(讓「順序」只影響哪些位置算前文,不影響模型的表達力),再把順序選在資料的自然結構上。
每一步的小誤差,在 步之後有多大
最後一個代價和抽樣有關,而且它是自回歸模型最容易被低估的地方。
每一項條件機率都有一點誤差。實測:真實切換率 ,模型學成別的值:
模型用 0.105 單步 KL 0.000135 nats 整條 (L=16) 0.0020 nats 相對誤差 5%
模型用 0.110 單步 KL 0.000525 nats 整條 0.0079 nats 相對誤差 10%
模型用 0.120 單步 KL 0.001993 nats 整條 0.0299 nats 相對誤差 20%
模型用 0.150 單步 KL 0.010896 nats 整條 0.1634 nats 相對誤差 50%
模型用 0.200 單步 KL 0.036690 nats 整條 0.5504 nats 相對誤差 100%
單步的 KL 小得像捨入誤差( nats),但它要乘以 。把長度拉長(模型固定用 ):
L = 8 整條 KL = 0.0140 nats 每位元 0.001744
L = 16 整條 KL = 0.0299 nats 每位元 0.001869
L = 64 整條 KL = 0.1256 nats 每位元 0.001962
L = 256 整條 KL = 0.5083 nats 每位元 0.001986
L = 1024 整條 KL = 2.0393 nats 每位元 0.001991
右邊那一欄幾乎是常數,左邊那一欄線性成長。 這是本篇最實用的一句話:
這個例子的 sequence KL 是每步 conditional KL 的加總;KL 線性增加,不等於任務的錯誤率也線性增加。
上表已經是兩個完整序列分布之間的 KL,不是尚未計入抽樣的低估值。一般的 KL chain rule 是
另外,訓練常用真實前綴,生成卻用模型自己抽出的前綴;有限模型在不同前綴上可能表現不同。Ranzato 等人 [3] 討論了這種 exposure bias。它可能影響生成任務,但不能在上述完整 KL 上再憑空加一項「被放大的誤差」。
注意這解釋了幾個乍看無關的現象
「誤差沿著長度累加」這一件事,是下面幾個常見觀察的共同原因:
- 長文本會漸漸「走鐘」:開頭合理,越寫越偏。累積的偏差把狀態帶到訓練分布之外。
- 每位元與整段序列是不同尺度:每步約 nats,在 時累積約 nats;這描述完整 sequence KL,不自動決定體感品質或任務錯誤率。
- 取樣溫度會改變生成結果:降低溫度更偏向高機率 token,但不保證長文更好,也可能增加重複。應依任務同時檢查品質與多樣性。
長文失去連貫,也可能來自上下文限制或資料不足。比較真實前綴與生成前綴下的表現能提供線索,但一次比較不足以唯一診斷原因。
切幾刀、排什麼順序、走多長
互動 demo: 比較有限資料下,不同順序與上下文長度的測試 NLL。真模型的測試 NLL 是參考值,不是每份有限測試集上所有模型分數的下界。
什麼時候該用它
精確的模型 likelihood 可以用來比較 held-out NLL,或搭配 entropy coding 做壓縮;實際編碼長度還有 coding overhead。Conditional probability 也能用於預測,但一般的雙向填空不會自動由左到右模型直接得到。
它跟你要什麼。 次序列的模型呼叫。訓練時這不是問題——前文全部是已知的真實資料, 個位置可以一次算完(這就是 teacher forcing 之所以存在的理由)。抽樣時是問題,而且是無法用更多顯卡解決的問題: 必須等 。一段一千字的文字就是一千次序列呼叫。
這一切依賴什麼。 一,變數要能排成一個順序,而且那個順序最好對應資料的真實結構(第四節量過排錯的代價)。二,每一個條件分布要算得出來——離散變數用 softmax 很自然,連續變數要選一個分布族(Gaussian、混合、離散化),而那個選擇就是 要怎麼替「這個模型有多符合資料」打一個分數? 講的宣告。三,誤差會沿長度累加,所以在短序列上驗證過的模型,不保證在長序列上還好。
檢查理解
參考文獻
- Bengio, Y., Ducharme, R., Vincent, P. & Jauvin, C. A Neural Probabilistic Language Model. JMLR 3, 2003.(用神經網路參數化自回歸條件分布的起點,含局部正規化的成本分析。)
- van den Oord, A. et al. Pixel Recurrent Neural Networks. ICML 2016.(把自回歸分解套到沒有自然順序的資料上,以及掃描順序的選擇。)
- Ranzato, M., Chopra, S., Auli, M. & Zaremba, W. Sequence Level Training with Recurrent Neural Networks. ICLR 2016.(exposure bias 的系統性討論與幾種緩解方式。)