搜尋課程與筆記

搜尋筆記

輸入主題、關鍵字或單元編號,例如 Flow Matching、U4。

    按 Esc 關閉 · ⌘ / Ctrl K 開啟搜尋

    L4.5 15 分鐘閱讀 2026年10月

    L4.5 同一台機器要依指令做不同的事,指令從哪裡餵進去?

    本篇重用2 篇

    同一台機器,不同的指令

    前幾篇介紹了怎麼處理內容,但同一張照片可以要求修亮,也可以要求變成夜景。只看照片本身,不知道該做哪一種。額外的指令要在哪裡進入網路? 我們把它記成條件 cc:

    • 「把這張圖修成夜景」——條件是一個類別。
    • 「照這段文字生成」——條件是一串 token。
    • 「現在是流程的第 300 步,請做這一步該做的事」——條件是一個純量。

    最後一種不同的是,因為它不是使用者給的指令,而是演算法自己的狀態。同一組權重要在很多個不同的階段各做一件不同的事,於是「現在是第幾步」必須被餵進去。

    接法看起來很自由:接在輸入、接在中間某一層、或讓網路自己去查。但這幾種接法不是同一件事的幾種寫法——它們對不同形狀的條件有非常不同的成本。

    指令要從哪裡餵進去?
    接在輸入的一個維度上就好了嗎?
    如果那個指令是一個純量,會不會特別吃虧?

    課堂提問Q1

    把「依指令做不同的事」翻成數學:條件模型和無條件模型差在哪裡?把一個純量條件接成輸入的第二個維度,網路必須自己長出什麼東西——那件事對它來說容易嗎?

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

    先固定學習目標。 若 label YY 有有限二階矩、使用 L2 regression,理想條件模型學的是

    fθ(x,c) ≈ E[Y∣X=x, C=c].f_\theta(x,c)\ \approx\ \mathbb E[Y\mid X=x,\,C=c].

    多了一個條件,把輸入分得更細。條件變異數取期望後不會增大,但某一個特定桶子仍可能比原本更分散;有限模型與資料也不保證誤差一定下降。

    接成輸入維度之後,網路要自己長出什麼。 若 ff 對 cc 的依賴是高頻的——例如流程的第 3 步和第 4 步該做的事差很多——那麼把 cc 當成一個普通的輸入座標,就是要求網路在那個座標上表現出高頻的變化。

    而 什麼都能擬合,那為什麼還需要別的架構? 的頻率實驗量過這件事:同一個 64×6464\times64 的網路,目標從 1 個週期換到 32 個週期,訓練 MSE 從 0.00000.0000 變成 0.38750.3875。MLP 對高頻很不友善,而這個不友善不分輸入座標——xx 這一維吃虧,cc 這一維一樣吃虧。

    兩條出路,方向不同。

    • 把頻率直接給它:不要接 cc,接 (sin⁡(2πfjc),cos⁡(2πfjc))j\big(\sin(2\pi f_j c),\cos(2\pi f_j c)\big)_j 這一組不同頻率的特徵。網路要高頻時,它已經在輸入裡了,只需要線性組合。
    • 不要讓 cc 走同一條路:讓它去改變每一層的行為(尺度與偏移),而不是當成一個和 xx 平起平坐的座標。

    本篇會把第一條量出來(嵌入比加寬便宜也有效),並說清楚第二條在什麼形狀的條件上才划算。

    三種注入方式,三種「改變什麼」

    把接法按照「它改變了網路的哪一部分」排開:

    • concat(接在輸入):f([x,c])f([x,c])。最簡單,而且在條件和輸入是同一種東西時很自然(例如都是影像的像素)。缺點是條件的影響必須一路經過所有層才擴散開,而且它和 xx 共用同一條路。
    • FiLM(每一層的尺度與偏移):由 cc 算出一組 (γℓ,βℓ)(\gamma_\ell,\beta_\ell),在第 ℓ\ell 層做 h←γℓ⊙h+βℓh\leftarrow\gamma_\ell\odot h+\beta_\ell。條件不再是一個座標,而是直接調整每一層的行為。這對「全域性、影響整張圖」的條件特別合適——類別、時間步、風格。
    • cross-attention:由目前特徵提供 query,條件 token 提供 key 與 value,讓不同位置參考不同的條件部分。其他接法也能配合編碼器處理變長輸入,但 cross-attention 提供了直接的內容配對方式。

    三者不互斥,實務上常常同時出現(時間用 FiLM、文字用 cross-attention、低階的輔助輸入用 concat)。挑的依據是條件的形狀:

    條件長什麼樣適合的注入方式
    一個純量(時間、強度)嵌入 → FiLM(或 concat 嵌入)
    一個類別(有限選項)查一個 embedding 表 → FiLM
    一張同尺寸的圖(遮罩、邊緣圖)concat 在通道上
    一串長度可變的 tokencross-attention

    同一個條件,三個注入的位置

    圖說: 三種接法改變的運算不同;時間嵌入則是提供純量條件的一種表示選擇。

    為什麼純量條件要先做嵌入

    正弦嵌入把一個純量 c∈[0,1]c\in[0,1] 換成一組不同頻率的三角函數:

    emb(c)=(sin⁡(2πfjc), cos⁡(2πfjc))j=0J−1,fj=2 j.\mathrm{emb}(c)=\big(\sin(2\pi f_jc),\ \cos(2\pi f_jc)\big)_{j=0}^{J-1}, \qquad f_j=2^{\,j}.

    它在做的事可以用一句話說清楚:把「網路要自己長出高頻」換成「高頻已經在輸入裡,只需要把它們線性組合起來」。

    例如需要 sin⁡(16πc)\sin(16\pi c) 時,若這個頻率已在輸入裡,後面的線性層便能直接選用,不必先從原始純量形成這個振盪。這是 Tancik 等人 [2] 研究 Fourier features 的動機之一;不代表任意網路的第一層權重都必須是 O(k)O(k)。

    還有一個要檢查的限制:這裡全是整數頻率,所以 emb⁡(0)=emb⁡(1)\operatorname{emb}(0)=\operatorname{emb}(1)。若兩端需要不同答案,應另保留 cc、加入非整數頻率或使用其他能區分端點的嵌入,不能直接照搬這組示範頻率。

    fj=2jf_j=2^j 這個幾何級數也不是隨便挑的:它讓不同尺度的變化都被覆蓋到,而且只要 JJ 個維度就涵蓋 2J2^{J} 倍的頻率範圍。

    補充這和 Transformer 的位置編碼是同一個東西

    Transformer 的位置編碼用的是同一條式子(sin⁡/cos⁡\sin/\cos 配上幾何級數的頻率),解決的也是同一個問題:位置是一個純量,而網路需要對它有多尺度的敏感度。差別只在那裡的純量是「第幾個 token」,這裡是「第幾步」或「條件的強度」。

    同一個技巧在座標型網路(用網路表示一張圖或一個 3D 場景)上叫 Fourier features(參考文獻 2),那篇論文把「為什麼沒有嵌入就學不到高頻」用 neural tangent kernel 講清楚了:沒有嵌入時,網路的等效核對高頻成分的響應以指數衰減,於是那些成分在任何合理的訓練時間內都學不到。

    三個名字、三個領域、同一件事——可以把它記成一個通用的手法:當一個純量需要高頻的影響力時,先把它展開成多個頻率。

    三種接法在同一個任務上

    任務刻意設計成「對條件的依賴是高頻的」:

    y=sin⁡(2πx+2π⋅8⋅t),x,t∼U(0,1), n=800.y=\sin\big(2\pi x+2\pi\cdot 8\cdot t\big),\qquad x,t\sim U(0,1),\ n=800 .

    對 xx 的依賴是 1 個週期(很容易),對 tt 的依賴是 8 個週期(照 什麼都能擬合,那為什麼還需要別的架構? 的頻率表,這是要花點力氣的區域)。三個設定跑同樣的 6000 步、同樣的 Adam η=0.01\eta=0.01:

      concat 純量 t            輸入維度   2  h= 64  訓練 MSE 0.0018
      concat 正弦嵌入 t         輸入維度  13  h= 64  訓練 MSE 0.0004
      concat 純量 t(寬兩倍)    輸入維度   2  h=128  訓練 MSE 0.0010

    嵌入把誤差降到四分之一(0.0018→0.00040.0018\to0.0004),而它只多了 11 個輸入維度。 對照組更有說服力:把網路加寬兩倍(參數變成約四倍)只從 0.00180.0018 改善到 0.00100.0010——四倍的參數買到的,還不如 11 個不需要學的輸入維度。

    固定嵌入不需要學自己的頻率,但它仍改變輸入表示、後續參數數量與可表示的函數。改善來自哪裡,需用對照實驗確認。

    這也解釋了為什麼幾乎每一個需要「時間步」的模型都有一個正弦嵌入層,而且那一層通常沒有參數:它不是模型的一部分,是輸入的一種座標選擇——和 霧中下山,一步該走多大:梯度下降的一頁 裡「標準化改的是碗的形狀」是同一類的動作。

    「沒有條件」也必須被訓練過

    條件模型有一個很容易被忽略的需求:有時候你要它不要依照條件做事。

    • 想知道模型在「什麼都不指定」時的預設行為。
    • 想比較「有條件」與「無條件」的輸出差在哪裡(很多引導式的取樣做法都需要這兩個)。
    • 使用者就是沒有給條件。

    直覺的做法是留一個 null token:一個代表「沒有條件」的特殊輸入(例如把 one-hot 全部設成零)。問題是——如果訓練時條件永遠都在,那個 null token 從來沒有出現在訓練資料裡。

    任務是 y=sin⁡(2πx)+0.8cy=\sin(2\pi x)+0.8c,cc 與 xx 獨立且兩類等機率。L2 的無條件最佳答案因此是 E[Y∣X=x]=sin⁡(2πx)+0.4\mathbb E[Y\mid X=x]=\sin(2\pi x)+0.4。訓練時以獨立機率 pp 將條件換成 null,才能讓 null 分支看到這個邊際化的目標;一般情況要按 p(c∣x)p(c\mid x) 平均,不一定是各類一半。

    def feats(x, c, mask):                      # mask=0 表示這一筆的條件被丟掉
        oh = np.zeros((len(x), 2)); oh[np.arange(len(x)), c] = 1.0
        return np.c_[x, oh*mask[:,None]]
    
    mask = (rng.random(N) > p).astype(float)    # p 是條件 dropout 的機率
      條件 dropout p=0.0   用 null token 預測「兩類平均」的 MSE 中位數 1.3908
      條件 dropout p=0.1   用 null token 預測「兩類平均」的 MSE 中位數 0.0660
      條件 dropout p=0.3   用 null token 預測「兩類平均」的 MSE 中位數 0.0225
      (對照:直接輸出 0 的 MSE = 0.6575)

    這次 p=0p=0 的 null 表現很差,因為訓練目標沒有約束這個輸入的答案。函數仍有定義,只是沒有保證它等於兩類平均;其他初始化或模型不一定同樣差。

    只要 10%10\% 的條件 dropout,誤差就掉到 0.0660.066——二十一倍。 p=0.3p=0.3 再降到 0.02250.0225,但代價是三成的訓練樣本沒有用到條件資訊,條件本身的品質會開始下降。實務上 10%10\% 左右是常見的折衷。

    「沒有條件」不是一個預設狀態,它是一個要被訓練的輸入。

    刻意違反:把 null token 換成一個「沒用過的」向量。 如果不是用全零,而是隨便挑一個訓練時沒出現過的向量(例如 one-hot 的第三格),結果和 p=0p=0 那一列一樣糟——問題不在「用哪個向量代表沒有條件」,而在「那個向量有沒有被訓練過」。 這也是為什麼實務上一律用「訓練時真的餵過的那個」當 null,而不是任何看起來比較中性的東西。

    這一切依賴什麼。 一,上面的數字是在一個純量/類別條件、小網路上量的;條件是長序列時 dropout 的做法不同(丟整串、還是丟其中幾個 token,會影響模型學到的東西)。二,pp 是一個要調的超參數,而它同時影響「無條件有多準」與「有條件有多準」——兩者用同一組權重。三,這裡量的是「無條件輸出對不對」,不是「有條件輸出有沒有變差」;完整的評估要兩個都看。

    三種接法、一個頻率設定、一個 dropout 設定

    互動 demo:把條件頻率 k 拉大,「純量」那條訓練曲線整條抬高而「嵌入」那條幾乎不動。

    檢查理解

    想一想

    一個模型需要知道「現在是流程的第幾步」,團隊把步數除以總步數變成一個 [0,1][0,1] 的純量接在輸入上,發現模型在相鄰步數之間的行為幾乎一樣。最直接的處方是:

    想一想

    一個條件模型在訓練時每一筆資料都有條件。上線後有人問「不給條件時模型會輸出什麼」,團隊把條件向量設成全零去問。根據本篇的實測,最可能的結果是:

    想一想

    關於 FiLM(用條件算出每一層的 γℓ,βℓ\gamma_\ell,\beta_\ell)與 concat,下列哪一個判斷比較合理?

    想一想

    下列哪一句不對?

    參考文獻

    1. Perez, E. et al. FiLM: Visual Reasoning with a General Conditioning Layer. AAAI 2018.(把「條件改變每一層的尺度與偏移」抽象成一個通用層,並比較它與 concat 的差別。)
    2. Tancik, M. et al. Fourier Features Let Networks Learn High Frequency Functions in Low Dimensional Domains. NeurIPS 2020.(用 NTK 說明沒有嵌入時高頻為什麼學不到——本篇 Remark 的來源。)
    3. Ho, J., Salimans, T. Classifier-Free Diffusion Guidance. 2022.(條件 dropout 與 null token 的標準做法;本篇最後一段實驗的實務對應。)