L5.2 21 分鐘閱讀 2026年9月

L5.2 一個高維的機率,能不能拆成一串一維的機率?

本篇重用M4.0明天的天氣只看今天:Markov Chain 與 Transition Matrix·M5.1用錯的機率表下注一年會多輸多少:KL Divergence 與 Cross-Entropy

起點:另一條路

當那個要加總的量算不出來,可以退到哪裡? 的路線是退讓:邊際算不出來,所以換一個算得出來的下界,並且接受一個大小不明的缺口。

還有第二條路,而且它一步都不退。機率的乘法定則(chain rule)說,對任何一組變數 x=(x1,,xL)x=(x_1,\dots,x_L) 與任何一個順序:

p(x1,,xL)=p(x1)p(x2x1)p(x3x1:2)p(xLx1:L1).p(x_1,\dots,x_L)=p(x_1)\,p(x_2\mid x_1)\,p(x_3\mid x_{1:2})\cdots p(x_L\mid x_{1:L-1}).

這是恆等式。 不是近似、不是下界、沒有任何條件——它只是條件機率定義的反覆套用。於是

logp(x)=l=1Llogp(xlx1:l1),\log p(x)=\sum_{l=1}^{L}\log p(x_l\mid x_{1:l-1}),

一個高維的對數機率變成 LL 個一維的對數機率相加。每一項都是一個普通的「給定一堆東西、預測下一個」的問題,也就是前面五個 class 的全部工具直接可用。

這看起來好得不像真的——一個恆等式不可能把難的問題變簡單。所以代價一定藏在某個地方。

乘法定則沒有任何近似,
可是它把一個做不到的問題變成了做得到的——
那個「變簡單」是從哪裡來的,代價又付在哪?

課堂提問Q1

p(x)p(x) 難在哪?具體地說:如果不用分解,直接讓一個網路輸出 xx 的機率,你會卡在哪一步?而分解之後那一步為什麼變得可行?把兩種做法的成本各算一次。

先想一想,再展開看整理後的答案

卡在正規化。 一個網路很容易輸出一個「分數」sθ(x)Rs_\theta(x)\in\mathbb R——越像真的資料分數越高。但分數不是機率。要變成機率必須除以一個總和:

pθ(x)=esθ(x)Zθ,Zθ=xesθ(x).p_\theta(x)=\frac{e^{s_\theta(x)}}{Z_\theta},\qquad Z_\theta=\sum_{x'} e^{s_\theta(x')}.

ZθZ_\theta 是對所有可能的 xx 加總。 LL 個位置、每個位置 KK 種取值,那是 KLK^L 項。L=16L=16K=2K=2 已經是 6553665536 項;L=1000L=1000K=50000K=50000(一段文字)是一個沒有名字的數。而且 ZθZ_\theta 依賴 θ\theta,所以每一步梯度下降都要重算一次。這就是能量模型難訓練的根本原因。

分解把這個和拆成 LL 個小和。 每一項 pθ(xlx1:l1)p_\theta(x_l\mid x_{1:l-1})單一個座標上的分布,正規化只要對那一個座標的 KK 種取值加總:

pθ(xlx1:l1)=esθ(xlx1:l1)k=1Kesθ(kx1:l1).p_\theta(x_l\mid x_{1:l-1})=\frac{e^{s_\theta(x_l\mid x_{1:l-1})}}{\sum_{k=1}^{K}e^{s_\theta(k\mid x_{1:l-1})}}.

這就是一個 softmax。成本從 KLK^L 變成 L×KL\times K——L=1000L=1000K=50000K=50000 時是五千萬,一張 GPU 的一個矩陣乘法。

而且乘積自動正規化。 每一項都是合法的分布,所以它們的乘積在整個 xx 空間上的總和必然是 11,不需要再做任何事。這是自回歸模型唯一但決定性的好處:似然是精確的、算得出來的、不需要下界。

代價在哪。 三個,本篇三節各處理一個。

  1. 每一項的條件是全部的前文。真的做到要 LL 個不同大小的輸入,實務上要嘛截斷(只看前 kk 個),要嘛用一個能吃變長輸入的架構。截斷就是丟掉結構,而那是有價的(第二節)。
  2. 抽樣要跑 LL,而且是序列的——x5x_5 要等 x4x_4 算完。訓練可以平行(前文都是已知的真實資料),抽樣不行。這是自回歸模型最貴的地方(第三節)。
  3. 你必須選一個順序。理論上任何順序都對,實務上不是(第四節)。

丟掉條件,就是丟掉結構

先把「丟掉條件的代價」量出來。

設定:長度 L=16L=16 的二元序列,由一條馬可夫鏈生出來(明天的天氣只看今天:Markov Chain 與 Transition Matrix)——第一位是公平的,之後每一位有機率 qq 翻面、1q1-q 維持。qq 小表示序列傾向一整段一整段同色。

拿一個逐位置獨立的模型去配它:p(x)=lp(xl)p(x)=\prod_l p(x_l)。由對稱性它會學到每一位都是 1/21/2,所以

KL(獨立)=(L1)(ln2H(q)),H(q)=qlnq(1q)ln(1q).\mathrm{KL}(\text{真}\Vert\text{獨立})=(L-1)\big(\ln 2-H(q)\big),\qquad H(q)=-q\ln q-(1-q)\ln(1-q).

實測(L=16L=16):

  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

最後一列是對照組q=0.5q=0.5 時相鄰位置本來就獨立,所以獨立模型完全正確,KL 精確為零。這一列存在的意義是確認前三列的數字量的是「結構」而不是別的東西。

前三列是代價本身:結構越強(qq 越小),忽略它越貴。q=0.05q=0.057.4197.419 nats——換算成每個位元約 0.460.46 nats,也就是每一位你都在浪費大半個位元的資訊。

抽樣看得更直接:

  真實鏈抽出來的序列   相鄰位置的切換率 0.1006  (真值 0.10)
  逐位置獨立抽出來的   相鄰位置的切換率 0.4979  (必然是 0.50)

同樣的邊際分布,完全不同的樣本。 兩個模型在「每一位是 0 還是 1 的比例」上一模一樣,但一個生出一段段的色塊、另一個生出雪花雜訊。

獨立假設不是省事的近似,它是把資料裡所有的結構丟掉;而邊際分布完全看不出這件事。

一次生幾格:省一半的時間要付多少

第二節是極端情形(一格都不看前文)。實務上真正會動的旋鈕是抽樣的次數:Q1 說過抽樣要序列地跑 LL 次,而那是自回歸模型最貴的地方。所以一個很自然的想法是一次多吐幾格——每次呼叫仍然看完整的前綴,但一口氣吐出 BB 格,而那 BB彼此之間只好假設獨立。呼叫次數從 LL 降到 L/BL/B

這正是各種平行解碼的骨架,而它的代價可以精確算出來:被切斷的依賴關係有 LL/BL-L/B 個,每一刀的價錢都是 ln2H(q)=0.368064\ln2-H(q)=0.368064 nats。實測(L=16L=16q=0.1q=0.1,全部結構值 5.5215.521 nats):

  B =  1   呼叫 16 次   斷掉  0 個依賴   KL = 0.000 nats   =   0.0% 的結構丟失
  B =  2   呼叫  8 次   斷掉  8 個依賴   KL = 2.945 nats   =  53.3%
  B =  4   呼叫  4 次   斷掉 12 個依賴   KL = 4.417 nats   =  80.0%
  B =  8   呼叫  2 次   斷掉 14 個依賴   KL = 5.153 nats   =  93.3%
  B = 16   呼叫  1 次   斷掉 15 個依賴   KL = 5.521 nats   = 100.0%

這張表最該記住的是它的形狀:第一次減半最貴。 呼叫次數從 1616 砍到 88(只省一半的時間)就丟掉了 53.3%53.3\% 的結構;接下來 848\to4 再丟 26.7%26.7\%424\to213.3%13.3\%212\to16.7%6.7\%每多砍一半,多丟的量減半,但你也只剩一半可以省。

理由不難看。斷掉的依賴數是 LL/BL-L/BB=2B=2 就已經把每一對相鄰位置裡的一半拆開了,而那是所有依賴中最強的那一半(在這條一階鏈裡,所有的結構都住在相鄰位置之間)。

平行解碼省的是時間,花的是「相鄰位置之間的關係」——而那通常正是資料裡最貴的那部分結構。

補充反過來的切法:區塊內部精確、區塊之間獨立

上面那個模型是「看前綴、塊內獨立」。還有一個方向相反的切法:塊內精確建模,但塊與塊之間完全不看彼此。同一條鏈:

  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=1B=1 這一列就是第二節的逐位置獨立模型,B=16B=16 這一列是精確。但這個方向的成本結構完全不同:BB 越大越準,而「模型要能表達一個 BB 維的聯合分布」本身越貴——BB 個二元位置有 2B2^B 種組合,B=16B=16 就回到 Q1 那個 KLK^L 的問題。

把兩張表擺在一起,自回歸分解的特別之處就清楚了:它是「一個依賴都不切」(上表的 B=16B=16而且每一步只要一個 KK 維的 softmax(下表的 B=1B=1 的成本)。它同時拿到兩張表的好的那一端,換來的是 LL 次序列呼叫。

補充這條取捨在真實資料上會彎,而且是往有利的方向彎

上面那個「每一刀等價」是這個特定鏈的性質:它是一階的,所有依賴都在相鄰位置之間,而且強度一致。

真實資料通常不是這樣。一段文字裡,相鄰兩個字的依賴遠強於相隔五十個字的依賴;一張圖片裡,相鄰像素幾乎決定彼此。這表示切在遠處的刀比切在近處的便宜,於是那條曲線會彎——保留局部的依賴、放掉遠處的依賴,可以用很少的代價省下很多呼叫。

這就是為什麼「只看前 kk 個」的截斷在實務上常常夠用,也是為什麼各種平行解碼的方法會先切最不痛的地方。但這是一個關於資料的經驗事實,不是定理——要用它之前,值得在自己的資料上量一次:把上下文長度從 kk 砍到 k/2k/2,每位元的 NLL 掉多少。

順序有沒有差

乘法定則對任何順序都成立。所以理論上,順序不影響任何事。

實務上會,而且原因很具體:模型族是受限的。如果模型只能看前一個變數(或前 kk 個),那麼「哪些依賴看得到」就取決於你把變數排成什麼順序。

實測。三個二元變數:x1x_1 是公平硬幣,x2x_2 是另一個完全獨立的公平硬幣,x3=x1x_3=x_190%90\% 的機率相同(也就是 x3x_3 只跟 x1x_1 有關)。模型族固定為「一階鏈」:p(v1)p(v2v1)p(v3v2)p(v_1)p(v_2\mid v_1)p(v_3\mid v_2)

  順序 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

第一列和參考列一模一樣。 把不相干的 x2x_2 夾在 x1x_1x3x_3 中間,一階鏈就完全接不到那個依賴——它付了「有條件模型」的成本,卻得到「獨立模型」的結果。而只要把 x3x_3 移到 x1x_1 旁邊(或把 x2x_2 移開),同一個模型族就精確無誤。

順序不改變真相,但它決定你的模型看不看得到真相。

這在實務上怎麼出現。 文字有一個天然的順序,所以這個問題不明顯。圖片沒有——把二維像素排成一維要選一種掃法,而任何掃法都會把「垂直方向的鄰居」變成相隔一整列的遠親。表格資料更糟:欄位之間沒有任何自然順序,而不同的順序可以差很多。

展開細節為什麼順序無關的模型不容易做

一個自然的想法是:既然順序是任意的,那就對所有順序取平均,或者訓練一個對所有順序都成立的模型。

這條路是可行的(order-agnostic 的訓練、把「哪些位置已知」當成一個隨機的遮罩),但它把問題變難了:模型現在要在每一種前文組合下都給出正確的條件分布,而那是 2L2^L 種組合而不是 LL 種。用固定順序訓練時,模型只需要學會 LL 個「看前綴」的函數。

所以這是一個標準的取捨:固定順序 = 容量花在少數幾個條件上、學得好,但順序選錯就接不到依賴;隨機順序 = 通用,但同樣的容量要攤到指數多的條件上。 實務上的折衷通常是用一個能看全部前文的架構(讓「順序」只影響哪些位置算前文,不影響模型的表達力),再把順序選在資料的自然結構上。

每一步的小誤差,在 LL 步之後有多大

最後一個代價和抽樣有關,而且它是自回歸模型最容易被低估的地方。

每一項條件機率都有一點誤差。實測:真實切換率 0.100.10,模型學成別的值:

  模型用 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 小得像捨入誤差(0.0020.002 nats),但它要乘以 L1L-1。把長度拉長(模型固定用 0.120.12):

  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

右邊那一欄幾乎是常數,左邊那一欄線性成長。 這是本篇最實用的一句話:

自回歸模型的誤差是每個位置累加的,所以「每位元的 NLL」看起來很穩,而整條序列的錯誤率隨長度線性惡化。

而且這還是低估。上表算的是「模型對真實前文的條件機率有偏差」,但抽樣的時候前文是模型自己生的——一旦某一步抽到一個真實資料裡不太會出現的值,接下來每一步都在一個訓練時沒見過的前文上做預測,誤差不再只是相加,而是會被放大。這個落差有一個名字:exposure bias(訓練時看的是真實前文,推論時看的是自己生的前文)。

注意這解釋了幾個乍看無關的現象

「誤差沿著長度累加」這一件事,是下面幾個常見觀察的共同原因:

  • 長文本會漸漸「走鐘」:開頭合理,越寫越偏。累積的偏差把狀態帶到訓練分布之外。
  • 每位元 NLL 的微小改善對應到很大的體感差異:上表的 0.0020.002 nats/bit 在 L=1024L=1024 時是整整 22 nats。用 同一個實驗跑三次結果都不同,該報哪一個? 的語言:這個指標的解析度和你在乎的東西的尺度差了三個數量級。
  • 降低取樣溫度會讓長文變好:溫度低表示每一步更貼近高機率區,比較不容易踏出訓練分布——代價是多樣性,而那正是下一篇的主題。

需要小心的是不要把它當成唯一的解釋。長文本走鐘也可能是模型的上下文長度不夠、或是資料本身就沒有那麼長的連貫樣本。分辨的方法是拿真實前文餵進去看它接得好不好:接得好就是 exposure bias,接不好就是模型本身的問題。

切幾刀、排什麼順序、走多長

互動 demo:容量夠的時候 120 個順序塌成同一個高度;容量不夠的時候差 1.08 nats。

回到情境:什麼時候該用它

它給你什麼。 精確的似然。這聽起來抽象,但它有三個很具體的用途:拿兩個模型的測試集 NLL 直接比較(不像 ELBO 有大小不明的缺口);拿模型去做無損壓縮(NLL 就是編碼長度);拿條件機率去做異常偵測或填空。這些事情在只有下界的模型上都做不了,或者做得很勉強。

它跟你要什麼。 LL 次序列的模型呼叫。訓練時這不是問題——前文全部是已知的真實資料,LL 個位置可以一次算完(這就是 teacher forcing 之所以存在的理由)。抽樣時是問題,而且是無法用更多顯卡解決的問題:x5x_5 必須等 x4x_4。一段一千字的文字就是一千次序列呼叫。

這一切依賴什麼。 一,變數要能排成一個順序,而且那個順序最好對應資料的真實結構(第四節量過排錯的代價)。二,每一個條件分布要算得出來——離散變數用 softmax 很自然,連續變數要選一個分布族(Gaussian、混合、離散化),而那個選擇就是 要怎麼替「這個模型有多符合資料」打一個分數? 講的宣告。三,誤差會沿長度累加,所以在短序列上驗證過的模型,不保證在長序列上還好。

先消化一下

想一想

Q1 說自回歸分解把正規化的成本從 KLK^L 降到 L×KL\times K。最準確的說法是:

想一想

第三節的平行解碼表裡,呼叫次數從 1616 砍到 88 丟掉 53.3%53.3\% 的結構,而從 22 砍到 11 只多丟 6.7%6.7\%。這個形狀說明:

想一想

順序實驗裡,x1x2x3x_1\to x_2\to x_3 的 KL 是 0.3680640.368064,恰好等於完全獨立模型的 KL。這個「恰好相等」說明:

想一想

下列哪一句不對

參考文獻

  1. Bengio, Y., Ducharme, R., Vincent, P. & Jauvin, C. A Neural Probabilistic Language Model. JMLR 3, 2003.(用神經網路參數化自回歸條件分布的起點,含局部正規化的成本分析。)
  2. van den Oord, A. et al. Pixel Recurrent Neural Networks. ICML 2016.(把自回歸分解套到沒有自然順序的資料上,以及掃描順序的選擇。)
  3. Ranzato, M., Chopra, S., Auli, M. & Zaremba, W. Sequence Level Training with Recurrent Neural Networks. ICLR 2016.(exposure bias 的系統性討論與幾種緩解方式。)