最佳化的地形:目標與可行域
前面十二關都在「算」——給你資料,算出一個數字。這一關開始「選」: 在一片有高有低的地形上,找最低的那個點;而且有人在地上畫了圍欄,你只能在圍欄裡面找。
① 這關在解什麼問題
機率統計 05 關教你拿 C 當一把尺, 去量一個點離中心有多遠。機率統計 01 到 05 關都在做同一件事:給你資料,算出一個數字。
但 最佳化 03 關(有效邊界)做的是另一件事。它從第一句話就開始講 「可行域」「最優解」「兩條線相切的地方就是答案」,還直接寫下 min wTCw。
問題是:整套教材從來沒教過「目標函數」是什麼、「凸」是什麼、 「為什麼最低點的梯度是 0」。這一關就是把這些字補齊。這一關完全不碰金融, 金融留給最佳化 03 關;這裡只用兩個旋鈕跟一片地形。
一個很具體的困擾
你負責一個線上服務,p99 延遲太高。你手上能動的旋鈕只有兩個:
- x —— 快取大小,單位 GB。太小 → 一直 miss,延遲高; 太大 → GC 壓力上來,延遲又高。
- y —— 工作執行緒數。太少 → 排隊;太多 → context switch 打架。
所以「延遲」是這兩個旋鈕的函數,寫成 f(x, y)。 你要找的是讓 f 最小的那組 (x, y)。
但機器的記憶體是固定的。假設每 1 GB 快取吃 1 單位記憶體、每 1 條執行緒吃 2 單位, 你總共只有 5 單位:
於是整件事變成一句話:
在圍欄裡面,找地形最低的那個點。
「地形」= 目標函數 f(②)。 「圍欄」= 可行域(③)。 「這片地形是碗還是蛋盤」= 凸性(④)。 「站在最低點時你腳下有什麼特徵」= 一階條件(⑤)。
四個字,四個小節,玩完你就能讀懂最佳化 03 關的每一句話。
② 目標函數 = 地形的高度
先從你已經會的東西開始:地圖上的等高線
國中地理課的地形圖:一圈一圈的細線,每一圈上面標一個數字(100 公尺、200 公尺…)。 規則只有兩條,你早就會了:
- 同一圈上的每一個點,高度完全一樣。沿著等高線走,你是在平地上繞。
- 線擠在一起 = 坡很陡(走一小步就掉一層);線很疏 = 平緩。
最佳化用的就是這張圖,一個字都不用改。唯一的差別是「高度」不是海拔,而是 你想要最小化的那個東西——延遲、誤差、成本、風險。
(x, y) —— 你手上兩個旋鈕的設定值,也就是地圖上的位置。
「最佳化」= 在這張地圖上找 f 最小的位置。要找最大就把 f 加負號,同一件事。
拖藍點。提示:試著沿著同一圈繞一圈, 看高度條會不會動。紫點是這片地形的臨界點(梯度為 0 的地方, 見 ⑤)。
—
三片地形分別是什麼
三個選項不是隨便挑的,每一片都在後面的關卡出現過:
| 地形 | 式子 | 等高線長相 | 它在哪裡出現過 |
|---|---|---|---|
| 碗 | f = ½[(x−1.2)² + (y−0.8)²] | 同心圓 | 最單純的最佳化:「離目標多遠」的平方,也就是最小平方法在做的事 |
| 拉長的碗 | f = ½ (v−c)TC−1(v−c) | 斜的同心橢圓 | 機率統計 05 關那顆橢圓, C = [[4, 3.6], [3.6, 4]]。這片地形的高度就是 ½ ×(馬氏距離)² |
| 馬鞍點 | f = ½[(x−1.2)² − (y−0.8)²] | 雙曲線,中間交叉成一個 × | 本關 ⑧ 踩坑 的主角:梯度是 0,卻不是最低點 |
三片地形我故意讓它們的臨界點都在同一個地方 c = (1.20, 0.80), 這樣你切換地形時,紫點不會亂跑,你可以專心看「等高線的形狀」怎麼變。
圖上會多出一條紫色虛線橢圓,標著 f = 0.5。 那一圈就是 機率統計 05 關的 1σ 橢圓—— 因為 f = ½ × 馬氏距離²,馬氏距離 = 1 的那一圈就是 f = 0.5。
同一顆橢圓,兩種讀法:機率統計 05 關讀它是「等機率的一圈」,這關讀它是「等高度的一圈」。 這不是兩個概念,是同一個東西換一個問題問。
所以這一段的結論是:目標函數就是一張地形圖, f(x, y) 是海拔,等高線是「高度一樣的點連起來」, 而「最佳化」就是在這張圖上往低處走。
本頁符號對照表
下面這張表會跟著上面那張圖一起變。畫面上出現過的每一個符號都在這裡。
| 符號 | 白話:它是什麼 | 現在的值 |
|---|---|---|
| f(x, y) | 目標函數,本關就是「地形高度」。你要讓它最小 | — |
| (x, y) | 你手上兩個旋鈕的設定值 = 地圖上的位置 | — |
| v | 把 (x, y) 寫成一個向量的寫法,v = (x, y)。跟 (x, y) 是同一個東西 | — |
| c | 臨界點:梯度剛好 = 0 的位置。碗的臨界點就是谷底 | (1.20, 0.80) |
| A | 地形的「形狀矩陣」(2×2 對稱)。它決定碗是圓的、斜的、還是馬鞍 | — |
| L | 等高線的高度值。「L = 3 那一圈」= 所有 f = 3 的點 | — |
| Δ | 相鄰兩圈的高度差。全圖固定,所以「線越密 = 坡越陡」 | — |
| ∇f | 梯度:站在這一點,往上最陡的方向(讀作 nabla f)。見 ⑤ | — |
| ‖∇f‖ | 梯度的長度=坡有多陡。谷底的特徵就是這個數 = 0 | — |
| b, r, s | 圍欄的大小:直線的 b、圓盤的半徑 r、盒子的半邊長 s。見 ③ | 見 ③ |
| α | 學習率:梯度下降一步要跨多大(讀作 alpha)。見 ④ | 見 ④ |
| t̂ | 等高線在這一點的切線方向(單位向量,帽子就是「長度 1」)。見 ⑤ | 見 ⑤ |
| · | 內積。兩個方向垂直 ⟺ 內積 = 0 | 見 ⑤ |
③ 可行域 = 地上的圍欄
如果沒有圍欄,最佳化很無聊:往低處走,走到谷底,結束。 真實世界從來不是這樣——你的錢有限、記憶體有限、CPU 核心是整數、比例加起來要是 100%。 這些「你不能違反的規定」寫成數學就是約束,而所有滿足約束的點合起來叫可行域。
約束有兩種寫法:等式(=,必須剛好落在線上)與 不等式(≤,落在區域裡面就好)。
下面三種圍欄,是實務上 90% 的情況:
| 圍欄 | 式子 | 形狀 | 真實世界對應 |
|---|---|---|---|
| 直線等式 | x + 2y = b | 一條線(可行域是「線上」,不是「線的一邊」) | 預算剛好花完;最佳化 03 關的 Σw = 1(錢全部投出去) |
| 圓盤不等式 | x² + y² ≤ r² | 一個實心圓 | 「總量不要超過」;也是 L2 regularization 的可行域寫法 |
| 方形盒子 | |x| ≤ s 且 |y| ≤ s | 一個正方形(其實是 4 條不等式) | 每個旋鈕各自有上下限:執行緒 1~8、快取 0~4 GB、最佳化 03 關的 w ≥ 0(不准做空) |
灰掉的區域=不合法,不管那裡多低都不能選。 值得試:把圍欄慢慢放大,看兩個答案什麼時候會合成一個。
—
三個一定要試的設定
- 圍欄什麼時候「不咬人」:選圓盤,把 r 從 1.40 拉到 1.45。 谷底離原點的距離是 √(1.2² + 0.8²) = 1.44,所以 r 一超過它, 谷底就落進圍欄裡,兩個答案合成同一個,代價變 0。這種約束叫 inactive(沒被咬到)。
- 同一道圍欄、不同地形,答案不同:圍欄固定選直線 b = 5, 地形在「碗」和「拉長的碗」之間切。碗給你 (1.64, 1.68),拉長的碗給你 (1.92, 1.54)。 圍欄沒變,答案卻變了——因為最優解是「地形」跟「圍欄」兩邊夾出來的,不是任何一邊單獨決定的。
- 角落解:選盒子,把 s 縮到 0.60。 這時 x 和 y 兩邊都被夾住,答案跑到正方形的角上。 「同時有兩個約束被咬到」是 最佳化 02 關 KKT 最愛舉的例子。
有約束的最低點幾乎永遠在邊界上。道理很白話:如果你現在站的地方四周都還在圍欄裡, 那你一定還能往下坡方向再挪一小步——除非你已經站在谷底了。所以能停下來的地方只有兩種: 真正的谷底(圍欄沒咬到你),或被圍欄擋住的邊界。
老實說:暴力掃描邊界。沿著圍欄邊界取 720 個點,挑最低的那個, 再用黃金分割法在它左右微調 60 次。圓盤掃一圈、盒子掃四條邊加四個角、直線掃畫面內那一段。
能這樣幹是因為這裡只有兩個變數、邊界是一維的。換成 500 個變數就完蛋了。 最佳化 02 關會教你怎麼寫一條方程式直接解出來,不用掃。
④ 凸性:這片地形是「碗」還是「蛋盤」
假設你不知道地形長什麼樣(真實情況通常如此:你只能量某一點的高度跟坡度), 那你只能用最笨的辦法:站在原地量哪邊往下最陡,往那邊走一步,重複。 這就是梯度下降,一行式子:
∇f —— 梯度,往上最陡的方向(⑤會拆給你看)。前面加負號就是往下。
α —— 學習率:一步跨多大。太小走不完,太大會飛出去。
下標「新 / 舊」= 第 k 步跟第 k+1 步,就只是這樣。
問題來了:這樣走一定會走到最低點嗎?答案是「看地形」。而分界線就叫凸性。
凸的:一個碗(f = ½ vTAv,A 正定)
非凸的:蛋盤(f = 0.1(x²+y²) − 0.8[cos 1.8x + cos 1.8y])
| # | 起點 | 左(凸碗)走到 | f | 右(蛋盤)走到 | f |
|---|
—
「凸」到底在保證什麼
「凸」的意思不是「很好算」,是「往下走一定到得了終點;局部最低就是全域最低」。
換句話說:在凸地形上,你永遠不需要擔心起點選錯。 你在任何一點停下來(梯度 = 0、走不動了),那個點就是全世界最低的點,不用再找。 這是一個非常強的保證——非凸地形完全沒有這種東西。
白話的判斷法,跟國中畫圖一樣:
- 凸= 在地形上任意挑兩點,拿一條直線把它們連起來,這條線永遠在地形上方(或貼著)。 碗是這樣;蛋盤不是(跨過一個凸起時,直線會鑽到地形下面去)。
- 二次地形 f = ½(v−c)TA(v−c) 的凸性完全由 A 的特徵值決定: 兩個特徵值都 > 0 → 正定 → 碗; 都 ≥ 0 → 半正定 → 碗,但可能有一整條「平底」; 一正一負 → 馬鞍(② 的第三個選項就是 A = [[1, 0], [0, −1]],特徵值 +1 與 −1)。
最佳化 03 關會直接寫下投資組合的風險 σp² = wTCw,然後說「這是個凸問題,所以有唯一解」。 為什麼可以這樣說?
因為 C 是共變異數矩陣,而共變異數矩陣永遠半正定—— 理由一句話就講完:wTCw 的意思是 「把資產按 w 混起來之後的變異數」, 而變異數是平方的平均,不可能是負的。
半正定 ⟹ 那片地形一定是碗(最壞情況是有一條平底),不可能是蛋盤、不可能是馬鞍。 所以最佳化 03 關才敢直接解一條方程式就收工,不必擔心「卡在局部最低」。 這是整套教材裡「凸」這個字唯一真正付錢的地方。
所以這一段的結論是:凸地形上梯度下降是「保證會到」的; 非凸地形上它只保證「會停」,停在哪要看你從哪裡出發、一步跨多大。
⑤ 一階條件:梯度是什麼,為什麼谷底的梯度是 0
偏導數與梯度的完整版(∂ 為什麼是「其他變數當常數」、 ∇f(v) = A(v − c) 怎麼算出來)在 微積分 · 多變量關 ②; 更前面的一維基礎(差商怎麼變成切線)在 導數關 ②。 不讀也能玩這一節,卡住再去。
「梯度」聽起來很兇,它其實只是兩個偏微分擺成一個向量:
∂f/∂y —— 反過來,只動 y。
∇ —— 讀作 nabla(或 del)。∇f 讀作「f 的梯度」,它是一個向量,不是一個數字。
兩個必須記住的性質,其中第二個是本節的重點:
- ∇f 指向往上最陡的方向。所以下坡方向是 −∇f。
- ∇f 一定垂直於等高線。
第二點為什麼?一句話:沿著等高線走,高度不變;不變就代表「往那個方向的斜率是 0」; 而斜率 = 梯度跟走的方向做內積。內積是 0,就是垂直。 下面那張圖就是在現場驗這件事。
橘箭頭已按 0.5 倍畫(不然會衝出畫面),但長度仍與 ‖∇f‖ 成正比。 桃紅切線是我沿著同一個高度量出來的, 完全沒有用到梯度——所以「內積 = 0」是真的在驗證,不是套套邏輯。
小圖:沿著「紫點 → 藍點」這條射線走, 橫軸是走了多遠,縱軸是那裡的 ‖∇f‖。 射線起點(也就是臨界點)上,梯度長度掉到 0。
—
把「谷底」翻譯成一條方程式
現在可以下定義了。如果 v* 是無約束問題的最低點,那麼:
這一行叫一階條件(first-order condition),因為它只用到一次微分。
白話:站在谷底,四面八方都不往下。哪個方向都沒有下坡,坡度就只能是 0。
「∇f = 0 只是候選人、還要看二階才知道是谷底或山頂」的一維代數版, 在微積分 · 多變量關 ③(那裡有一條兩個谷底夾一個山頂的曲線可以拖); 多維版的判別法(Hessian 的行列式與跡)在同關 ④。
這條式子很好用,因為它把「找最低點」變成「解方程式」。以本關的二次地形為例, 整個推導只有兩行:
∇f = 0 ⟹ A(v − c) = 0 ⟹ v = c (A 是對稱矩陣時才這麼乾淨,本關三片地形的 A 都對稱。) 所以「臨界點就在 c」不是我硬塞的,是解出來的。
∇f = 0 只對無約束問題成立。
回去看 ③:只要圍欄咬到你,答案就在邊界上,而邊界上的點 梯度根本不是 0——你明明還感覺到下坡(往谷底那邊),只是那個方向被圍欄擋住了,走不過去。
拿 ③ 的預設值:碗 + 直線 b = 5,有約束最低點是 (1.64, 1.68), 在那裡 ∇f = (0.44, 0.88),長度 0.98,離 0 差得遠。
但仔細看那個梯度:(0.44, 0.88) 剛好是 (1, 2) 的 0.44 倍,而 (1, 2) 正是圍欄 x + 2y = 5 的法向量。梯度不是 0,但它剛好完全垂直於圍欄。
那個「0.44」就是 最佳化 02 關的 Lagrange 乘子 λ。 下一關整關都在講這一件事。
⑥ 數學長怎樣(可以照著寫成程式的版本)
先給能跑的程式碼,五十行內把這一關全部裝完:
// 地形:f(v) = ½ (v − c)ᵀ A (v − c),A 對稱
const A = [[1, 0], [0, 1]], c = { x: 1.2, y: 0.8 };
function f(x, y) {
const dx = x - c.x, dy = y - c.y;
return 0.5 * (A[0][0]*dx*dx + 2*A[0][1]*dx*dy + A[1][1]*dy*dy);
}
// 梯度:對稱 A 的時候剛好就是 A(v − c)
function grad(x, y) {
const dx = x - c.x, dy = y - c.y;
return { x: A[0][0]*dx + A[0][1]*dy, y: A[1][0]*dx + A[1][1]*dy };
}
// 梯度下降:往 −∇f 走 α 步,重複
function descend(start, alpha, steps) {
let v = { ...start };
for (let i = 0; i < steps; i++) {
const g = grad(v.x, v.y);
v = { x: v.x - alpha * g.x, y: v.y - alpha * g.y };
}
return v; // 凸地形:不管 start 是什麼,都會回到 c
}
// 有約束:這一關用暴力法 —— 沿著圍欄邊界掃,挑最低的
function minOnCircle(r, n = 720) {
let best = null;
for (let i = 0; i < n; i++) {
const a = 2 * Math.PI * i / n;
const p = { x: r * Math.cos(a), y: r * Math.sin(a) };
const v = f(p.x, p.y);
if (!best || v < best.v) best = { ...p, v };
}
return best; // 最佳化 02 關會教你怎麼「解」而不是「掃」
}
符號版,每個字母都翻譯:
f —— 目標函數(你想壓低的數字)。
F —— 可行域(feasible set),所有合法的 v 合起來的集合。
整行讀作:「在 F 裡面挑一個 v,讓 f(v) 最小」。這就是最佳化問題的標準寫法。
A 的特徵值全 > 0 → 正定 → 凸(碗);有正有負 → 馬鞍;全 ≥ 0 → 半正定(碗,可能有平底)。
½ 是慣例:放了它,梯度才乾淨地等於 A(v − c),不會多一個 2。
注意它是必要條件不是充分條件:馬鞍點也滿足 ∇f = 0,卻不是最低點。
二次地形上收斂的條件是 α < 2 / λmax(A);本關「拉長的碗」的 λmax = 2.5, 所以 α 超過 0.8 就會震盪發散 —— 上面的滑桿可以拉到 1.1,自己去把它弄爆。
⑦ 工程師的「原來如此」
訓練一個模型就是:目標函數= loss(預測錯多少),決策變數= 幾億個權重, 方法= 梯度下降(SGD / Adam 都是它的變種)。地形維度是幾億,而且非凸。
「非凸」這一件事直接解釋了三個你天天在做卻覺得很玄的動作:
- 為什麼要在意初始化(Xavier、He initialization)—— 起點決定你滾進哪個坑, 就是 ④ 右邊那張圖,只是換成幾億維。
- 為什麼學習率要調、還要 warmup + decay —— α 太大在山谷裡彈來彈去(甚至 loss 變 NaN), 太小跑三天還沒到。④ 的 α 滑桿拉到 1.1 就是 NaN 的那個現場。
- 為什麼同一份 code 跑兩次結果不一樣 —— 不同的隨機起點 / 不同的 batch 順序 = 不同的坑。 凸問題不會有這種事,換十個起點都給你同一個答案。
Kubernetes 的 request / limit、雲端帳單優化、CDN 節點放哪、DB 連線池開多大—— 全部是同一個模板:
而 ③ 那個結論——最優解幾乎永遠貼在邊界上——就是為什麼 容量規劃的答案總是「剛好把預算花完」而不是留一半。這也是為什麼調參老是感覺 「多給一點就好一點,直到某條線被撞到」:你正在沿著可行域的邊界爬。
(「某些是整數」是這片地形上最惡毒的約束:可行域從一片連續區域變成一堆孤立的點, 梯度完全失效。那是整數規劃的領域,本教材不碰。)
⑧ 踩坑
「梯度下降跑完、loss 不動了」只代表你走不動了,不代表那是最低點。 ④ 右邊五條軌跡,落點的 f 分別是 −1.60、−0.47、−0.47、+0.66、+0.66—— 五個都是合法的「梯度 = 0、走不動」的點,但只有一個是真正的最低。
唯一能讓你安心說「停下來就是答案」的情況,是你證明了地形是凸的。
在 ② / ⑤ 選「馬鞍點」,把藍點拖到 c = (1.20, 0.80): 梯度長度真的是 0,但那裡不是最低點——沿著 y 方向走,f 一路往下沒有底。
所以「解 ∇f = 0」找到的是候選人名單(最低點、最高點、馬鞍點都在裡面), 要分辨是哪一種,得看二次微分 A 的特徵值正負。 順帶說:高維空間裡馬鞍點遠比局部最低點多,這是深度學習訓練卡住的主要原因之一。
③ 最刺眼的一組對照:圍欄一模一樣(x + 2y = 5), 地形從「碗」換成「拉長的碗」,答案就從 (1.64, 1.68) 跳到 (1.92, 1.54)。
換句話說:你把目標寫成什麼,就會得到什麼。 把「延遲」寫成平均延遲、p99、還是 p99.9,最優配置會落在完全不同的地方; loss 從 MSE 換成 MAE,模型學到的東西就不一樣。最佳化只會忠實地執行你寫下的那句話, 不會執行你心裡想的那句。
目標寫錯,你通常看得出來(答案很怪)。約束寫錯的症狀比較陰險,通常是這三種:
- 可行域是空的——約束互相矛盾,solver 回 infeasible,而你以為是 bug。
- 可行域太大——忘了寫某個限制(例:忘了 x ≥ 0), 答案跑到「快取大小 −3 GB」這種物理上不存在的地方,數學上卻完美。
- 可行域太小——多寫了一個沒必要的約束,你拿到一個「合法但明顯不夠好」的答案, 而且完全看不出哪裡不對,因為 solver 不會抱怨。
檢查法:解完之後看哪些約束是「被咬到的」(active,答案貼在它的邊界上)。 如果一個你隨手加的約束居然是 active,那它正在替你決定答案,你最好回去確認它是真的。 這件事在 最佳化 02 關會變成一個可以直接讀的數字。
⑨ 這關回答了什麼
目標函數是什麼?
就是「你想要壓到最小的那個數字」,寫成 f(x, y): 把你能動的旋鈕餵給它,它吐出一個數。
本關把它想成地形的高度——旋鈕的設定值是地圖上的座標,f 是那個點的海拔。 延遲、成本、預測誤差、投資組合的風險,全都可以當 f。
兩件事值得記住:① 要「最大化」就把 f 加負號,完全一樣的問題; ② f 寫成什麼,你就會得到什麼(坑 3)。
等高線怎麼讀?
跟地理課的地形圖一模一樣,兩條規則:
① 同一圈上的點高度完全一樣。沿著等高線走,f 不變(② 那張圖可以直接驗:沿一圈拖,右邊高度條不動)。
② 線越密 = 坡越陡。因為相鄰兩圈的高度差 Δ 是固定的, 水平距離越短卻掉同樣的高度,當然更陡。
再加一條這關新學的:梯度一定垂直穿過等高線,指向線變密的那一邊 (⑤)。
可行域為什麼重要?
因為它會直接改掉答案,而且改得很多。
沒有圍欄時答案就是谷底,一個。加上圍欄之後, 谷底可能根本不在圍欄裡,這時真正的答案是「圍欄上最低的那個點」, 而它幾乎永遠貼在邊界上(③)。
理由很白話:如果你四周都還在圍欄裡,你一定還能往下坡挪一步; 會被迫停下來,就是因為想走的那個方向被牆擋住了。
這也是為什麼容量規劃 / 預算配置的答案總是「剛好把資源用完」。
凸到底在保證什麼?
保證兩件事,而且都很強:
① 局部最低就是全域最低。你隨便停在一個「走不動」的點,那就是答案,不用再找。
② 往下走一定到得了。起點怎麼選都不影響最後的落點 (④左邊五條軌跡收在同一點)。
注意它不是在保證「很好算」或「算得快」—— ④ 左邊那個碗很扁(A 的特徵值 2.5 與 0.13,差 19 倍), 梯度下降在裡面會 zigzag 走很久。凸只保證「到得了」,不保證「很快到」。
怎麼確認地形是凸的?二次地形就看 A 的特徵值是不是都 ≥ 0 (半正定)。共變異數矩陣 C 永遠滿足這條, 所以 最佳化 03 關的 wTCw 一定是碗。
梯度是什麼方向?
∇f 指向往上最陡的方向(不是往下!下坡是 −∇f, 所以梯度下降的式子裡有個減號)。
它的長度 ‖∇f‖ 就是那個方向有多陡; 它一定垂直於等高線。
垂直這件事在 ⑤ 是現場驗的:我沿著同一個高度量出等高線的切線 t̂(過程完全沒用到梯度),再跟 ∇f 做內積,結果永遠是 0.0000、夾角 90°。
直覺版:沿著等高線走,高度不變 ⟹ 那個方向的斜率是 0 ⟹ 梯度在那個方向上沒有分量 ⟹ 垂直。
為什麼有約束時「梯度 = 0」失效?
因為「梯度 = 0」的意思是「四面八方都不往下」,而有圍欄時你不需要四面八方都不往下—— 你只需要「所有還走得過去的方向都不往下」。
具體看 ③ 的預設值:碗 + 直線 x + 2y = 5, 答案在 (1.64, 1.68),那裡 ∇f = (0.44, 0.88),長度 0.98, 完全不是 0。你在那裡確實感覺到下坡(往谷底 (1.20, 0.80) 那個方向), 但那個方向會讓你穿牆,所以不能走。
那新的停止條件是什麼?答案已經藏在數字裡了: (0.44, 0.88) = 0.44 × (1, 2),而 (1, 2) 正是那道圍欄的法向量。梯度不是 0,但它完全垂直於圍欄—— 意思是「剩下的下坡力氣全部被牆頂住了,沒有一絲一毫沿著牆的方向」。
把這句話寫成方程式,就是 最佳化 02 關的 Lagrange 乘子; 那個 0.44 就是 λ。
那我到底該用梯度下降,還是解方程式?
看你有什麼。
解方程式(∇f = 0)需要你「寫得出 f 的式子並且解得開」。 二次地形可以,最佳化 03 關的投資組合也可以—— 所以那一關直接給你封閉解。
梯度下降只需要你「在任一點量得出坡度」,f 長什麼樣不用知道。 代價是:非凸地形上它只保證「會停」,不保證「停在最低點」(坑 1), 而且要調 α。幾億個參數的神經網路只剩這條路。
兩者共用的都是同一個一階條件。差別只在「解它」還是「逼近它」。
本關的答案有一半是掃出來的:沿著圍欄邊界取 720 個點,挑最低的。 兩個變數可以這樣幹,兩百個變數不行。
而且 ⑤ 最後那個觀察太漂亮了不能放著: 有約束的最低點上,梯度不是 0,但它完全垂直於圍欄;換句話說, 等高線跟圍欄在那一點剛好相切。
最佳化 02 關:Lagrange 乘子與 KKT會把這句幾何觀察變成一條可以解的方程式, 並回答「不等式約束怎麼辦」(≤ 到底有沒有被咬到?)。 那一關做完,最佳化 03 關的每一個式子都會變成理所當然。