L3.1 15 分鐘閱讀 2026年9月

L3.1 同樣試一百次:排成格子,還是隨便丟?

起點:兩個旋鈕,一百次機會

你在調一台音響。面板上有兩個旋鈕,每個可以轉到 0011 之間的任何位置。你有一百次試聽的機會,每次可以任意設定兩個旋鈕。

最有條理的做法:每個旋鈕取十格(0.0,0.1,,0.90.0,0.1,\dots,0.9),兩兩組合剛好一百種,全部試一遍。每一種組合都被覆蓋到,聽起來無懈可擊。

最隨便的做法:一百次每次都把兩個旋鈕隨便轉到一個位置。

多數人會覺得第一種比較好——它有系統、不會漏掉、而且結果可以畫成一張整齊的表。

但如果其中一個旋鈕其實根本不影響音質呢?那麼格子搜尋實際上只試過重要那個旋鈕的十個不同位置(每個位置重複了十次,只是另一個不影響的旋鈕在變);隨機搜尋則試過一百個不同位置。

同樣的一百次,一個用在十個位置上,一個用在一百個位置上。

兩個旋鈕各試十格,還是隨便丟一百個點?
如果我事先不知道哪個旋鈕重要,
哪一種比較不會浪費?

課堂提問Q1

把兩種搜尋翻成數學:固定預算 BB、維度 dd,各自在每個維度上試過幾個不同的值?如果只有 kk 個維度真的影響結果,兩者實際上是在幾維的空間裡搜尋?

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

格子搜尋。 每個維度取 mm 格,總點數 md=Bm^d=B,所以

m=B1/d.m=B^{1/d}.

B=100B=100 時:d=1d=1m=100m=100d=2d=2m=10m=10d=3d=3m5m\approx5d=5d=5m3m\approx3每加一個維度,每個維度能分到的解析度就開一次根號。

隨機搜尋。 BB 個點的每一個座標都是獨立抽的,所以每個維度都試過 BB 個不同的值——與 dd 無關。

現在假設只有 kk 個維度真的影響結果。 把所有點投影到那 kk 個維度上:

  • 格子的 BB 個點塌成 mk=Bk/dm^k=B^{k/d}不同的位置,其餘 BBk/dB-B^{k/d} 次評估是重複的。
  • 隨機的 BB 個點仍然是 BB 個不同的位置(機率 1)。

浪費的比例是 1Bk/d11-B^{k/d-1} B=100B=100d=5d=5k=1k=1 時,格子只有 1000.22.5100^{0.2}\approx2.5、實際上 m=3m=3 個不同的位置——九成七的評估是重複的

兩個推論值得先記住。 一,k=dk=d(每個維度都重要)時 Bk/d=BB^{k/d}=B,兩者不相上下——隨機搜尋的優勢完全來自「有效維度低於名目維度」。二,你不需要知道哪些維度重要就能拿到這個好處;隨機搜尋對每一個維度都給了 BB 個值,所以它自動適應任何一個 kk。這是它最實用的性質:你事先不知道的那件事,不必事先知道。

投影下去就看得出來

把兩種搜尋的點畫在二維平面上,再把它們投影到橫軸(假設只有橫軸重要):

  • 格子的十行點投影下去完全重疊成十個位置。九十次評估對「找出橫軸的最佳值」沒有提供任何新資訊——它們只是在同一個橫座標上重複量了十次。
  • 隨機的一百個點投影下去是一百個不同的位置,鋪滿整條軸。

這張圖是 Bergstra 與 Bengio(參考文獻 1)那篇論文的核心,也是它為什麼改變了實務:它不需要更聰明的演算法,只需要不要把預算花在你自己造出來的重複上。

一個常見的反駁是「那我把格子設得不對齊不就好了」——沒錯,而把格子隨機擾動到極致,就是隨機搜尋。

差距有多大,以及它什麼時候消失

把上面的算式驗證一次。目標刻意設成只依賴前 kk 個維度:

f(h)=j=1k(hj0.3)2,f(h)=\sum_{j=1}^{k}\big(h_j-0.3\big)^2 ,

最小值是 00(越小越好)。預算固定 B=100B=100;格子每維取 m=B1/dm=\lceil B^{1/d}\rfloor 格;隨機搜尋重複 300 次取中位數:

維度 d   有效維度 k        格子         隨機   格子每維幾格
     1          1     0.00001     0.00001           100
     2          1     0.00111     0.00001            10
     3          1     0.00250     0.00001             5
     5          1     0.04000     0.00001             3
     2          2     0.00222     0.00220            10
     4          2     0.08000     0.00230             3

四件事,一件一件讀。

d=k=1d=k=1 時兩者相同(都是 0.000010.00001)。一維沒有「浪費在不重要的維度上」這回事,格子的一百格與隨機的一百點覆蓋一樣密。這一列是對照組:它說明差距不是來自「隨機比較好」這種抽象優勢。

只有一維重要時,差距隨 dd 爆開0.001110.00111d=2d=20.00250\to0.00250d=3d=30.04000\to0.04000d=5d=5),而隨機那一欄完全不動0.000010.00001)。五維時是四千倍。原因就在最右欄:格子每維只剩 3 格,而重要那一維的最佳值 0.30.3 落在 0.0/0.5/1.00.0/0.5/1.0 之間,最近的一格差 0.20.2,平方是 0.040.04——表格裡那個 0.040000.04000 不是抖動,是格子解析度直接算出來的。

所有維度都重要時兩者打平d=k=2d=k=20.002220.002220.002200.00220)。這一列很重要,因為它劃出了隨機搜尋優勢的邊界:

隨機搜尋贏的不是「隨機」,是「不要把預算花在自己造出來的重複上」——而只有在有效維度低於名目維度時,那些重複才存在。

最後一列是最接近真實情況的d=4d=4k=2k=2):0.080000.080000.002300.00230,三十五倍。真實的超參數空間大多長這樣——十幾個旋鈕,其中兩三個真的決定成敗。

補充log 尺度比線性尺度更常是對的

上面的模擬用的是線性的 [0,1][0,1],但真實的超參數多半該用 log 尺度抽:學習率、weight decay、ϵ\epsilon 這些跨好幾個數量級的量,「10410^{-4}10310^{-3}」和「10110^{-1}11」在實務上是同樣大的一步,而在線性尺度上後者大了一千倍。

判準很簡單:這個旋鈕的「差一倍」和「差一個固定的量」哪一個比較有意義? 前者就用 log(學習率、λ\lambda、batch size),後者用線性(dropout 率、動量的 β\beta——不過 β\beta 常常改抽 1β1-\beta 的 log,因為 一個 η 不夠用:動量與 Adam 各買到什麼 說它的記憶長度是 1/(1β)1/(1-\beta))。

抽錯尺度的後果和格子解析度不足是同一種:你的一百個點裡有九十九個擠在一個沒有用的區域。

比隨機更聰明的兩個方向

隨機搜尋把「不浪費」做到了,但它有一個明顯的缺點:它不從前面的結果學習。第一百次評估和第一次一樣盲目。

兩個方向各補一塊:

Bayesian optimization:用已經試過的點擬一個「目標函數長什麼樣」的機率模型(常用 Gaussian process 或樹模型),再用它挑下一個點——挑「預期會好」與「還沒探索過」之間權衡最佳的位置。它買到的是樣本效率,代價是多一層自己的超參數(核函數、取樣準則),以及在高維、有類別型旋鈕、或評估很吵的時候容易失靈。

Hyperband / successive halving:換一個方向——不減少試的點數,而是減少每個點的成本。先用很小的預算(少量 epoch 或少量資料)跑很多組設定,把明顯爛的砍掉,再把預算加倍給活下來的。它買到的是在同樣的總計算量下試更多組,前提是「小預算下的排名和大預算下的排名相關」——這個前提在多數任務上大致成立,但對「要訓很久才分得出勝負」的設定會失效。

實務上的順序是:先隨機、後聰明。隨機搜尋的三十到五十次評估會告訴你哪幾個旋鈕真的重要、大致的範圍在哪,而那正是 Bayesian optimization 需要的起點——直接讓它在一個十幾維、範圍全開的空間裡冷啟動,通常比隨機還慢。

回到情境:一個可以照著做的流程

  1. 列出所有旋鈕,各自標好尺度(log 或線性)與一個寬鬆的範圍。寧可範圍設寬——範圍設錯會讓最佳值落在邊界外,而那是隨機搜尋救不了的。
  2. 隨機抽三十到五十組,全部跑完。
  3. 看哪幾個旋鈕真的有影響:把每個旋鈕對驗證分數畫一張散點圖,有明顯趨勢的就是重要的(這一步本身就是報酬——你學到了 kk 是多少)。
  4. 在重要的那幾個旋鈕上收窄範圍,再抽一輪,或換 Bayesian optimization。
  5. 誠實記錄你總共試了幾組——那個數字是下一篇要用的 mm

這一切依賴什麼。 一,每一組設定的評估要用同一份驗證資料、同一個流程(否則比較的不是超參數)。二,評估本身有抖動(只有三十筆資料:交叉驗證 量過,小資料時抖動可能和被估的量同數量級),所以「最好的那一組」有一部分是運氣——這正是下一篇的主題。三,上面的模擬用的是無噪聲的目標;評估有噪聲時,隨機搜尋的優勢仍在,但「最好的那一組真的最好嗎」會變成一個獨立的問題。

回到情境:把第 3 步跑出來

第 3 步值得單獨示範,因為它是整個流程裡唯一會產生知識的一步——其他步驟都只是在找一個設定。

做法:把隨機搜尋的每一組設定畫成一個點,橫軸是某一個超參數的值、縱軸是它的驗證分數。重複 dd 次,每個超參數一張圖。

  • 重要的旋鈕:散點有明顯的趨勢或明顯的谷底。
  • 不重要的旋鈕:散點是一片均勻的雲——縱軸的變化完全來自其他旋鈕。

在本篇的模擬設定(d=4d=4k=2k=2)上,前兩張圖會看到清楚的 U 形,後兩張是均勻的雲。而一旦你看出 k=2k=2,下一輪就可以把範圍收在那兩個旋鈕上——Bk/dB^{k/d} 那個懲罰項消失了,因為你把 dd 降成了 kk

這也解釋了為什麼「格子搜尋」在只剩兩個旋鈕時又變回一個合理的選擇。

格子搜尋的問題從來不是格子,是維度。

同樣的預算,兩種撒點方式

互動 demo:把名目維度拉到 5,格子搜尋在每個軸上的不同值從 B 塌到 B^(1/5),隨機那一欄完全不動。

先消化一下

想一想

一個團隊有 6 個超參數,預算是 64 次評估,打算用格子搜尋。每個維度他們能分到幾格,以及最合理的建議是:

想一想

在模擬裡 d=k=2d=k=2(兩個維度都重要)時,格子 0.002220.00222、隨機 0.002200.00220,幾乎相同。這一列說明:

想一想

關於 Hyperband(先用小預算跑很多組、砍掉爛的、再把預算加倍給活下來的),它的關鍵前提是:

想一想

下列哪一句不對

參考文獻

  1. Bergstra, J., Bengio, Y. Random Search for Hyper-Parameter Optimization. JMLR 2012.(本篇投影論證與「低有效維度」的原始來源,含真實任務上的實證。)
  2. Li, L. et al. Hyperband. JMLR 2018.(successive halving 的預算配置與理論保證,以及它的前提。)
  3. Snoek, J., Larochelle, H., Adams, R. Practical Bayesian Optimization of Machine Learning Algorithms. NeurIPS 2012.(GP-based BO 的標準做法與它自己的超參數。)