JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

受限最佳化:拉格朗日乘子與 KKT 條件

前四篇指南讓你的最小化器愛去哪就去哪。但真實問題是被圍欄圈住的——預算、容量、必須精確成立的物理定律。這篇收尾的指南會示範拉格朗日乘子如何把一個帶等式約束的問題化成無約束問題、KKT 條件如何把它推廣到不等式約束,以及內點法與單純形法如何在電腦上真正解這類問題。

從自由的地形到圍起來的地形

本階至今所做的一切都在解 無約束最佳化:一路下坡,直到梯度消失,因為自由極小值的 一階條件 就只是 grad f = 0。但幾乎每個真實問題都被圍起來。你在固定預算下最小化成本;你在權重必須加總為一的限制下擬合模型;你設計一根梁,受限於應力不得超過某上限。你想要的那個最小值,可能根本不在自由地形的谷底附近——它坐落在你「不越過圍欄」所能抵達的最低點。

有兩種圍欄要緊。等式約束 g(x) = 0 把你釘在一條曲線或一個曲面上——想像一顆彈珠被迫精確地待在一根彎成環的鐵絲上。不等式約束 h(x) <= 0 則讓你在一個區域內部漫遊,卻永遠不能越過它的邊界——彈珠在桌面上自由移動,卻被圍欄擋住。受限最佳化的全部技藝,就是刻畫這些限制之下的最低點,然後把它算出來。拉格朗日的天才之處,在於把「在曲面上最小化」轉回那個熟悉的「令某個梯度為零」,而那正是前幾篇指南教你解的那種問題。

拉格朗日乘子:梯度必須對齊

想像在被約束於曲線 g(x) = 0 上的同時最小化 f(x)。沿著曲線走。只要你還能繼續下降——只要曲線在 f 上哪怕有一丁點朝下坡的方向——你就繼續走。你只有在「沿曲線往任一方向移動都不再使 f 減少」時才會卡在某個最小值。從幾何上看,這恰好發生在 f 的梯度與曲線垂直之時,也就是它的方向正好沿著約束本身的梯度。所以在受限的最小值處,這兩個梯度必須「平行」:grad f = lambda 乘以 grad g,其中 lambda 是某個單一數字。那個數字就是 拉格朗日乘子

讓這變得實用的記帳技巧是拉格朗日函數 L(x, lambda) = f(x) - lambda g(x)。令它對 x 的梯度為零,就重現了 grad f = lambda grad g;令它對 lambda 的導數為零,又恰好還回 g(x) = 0,也就是約束本身。於是一個帶單一約束的 n 變數問題,化成了一個 n + 1 個未知數(原本的 x 加上 lambda)的純無約束駐點問題。你把一場有圍欄的搜尋換成了單純的「令梯度為零」——可用 牛頓法 或前幾篇指南裡的任何工具來解。

minimize  f(x) = x^2 + y^2     subject to   g(x) = x + y - 1 = 0

Lagrangian:   L = (x^2 + y^2) - lambda (x + y - 1)

grad_x L = 0 :   2x - lambda = 0
grad_y L = 0 :   2y - lambda = 0
grad_lambda L = 0 :   x + y - 1 = 0

=>  x = y = lambda/2,   and   x + y = 1   =>   x = y = 1/2,  lambda = 1

(closest point of the line x+y=1 to the origin: (1/2, 1/2), as geometry predicts)
一個小小的範例:拉格朗日函數把一個受限問題化成三條平凡的方程式,一起求解。

不等式與 KKT 條件

等式是容易的那一半。大多數真實的圍欄是不等式:h(x) <= 0。這時出現了一個微妙之處。在最佳點,每個不等式都處於兩種狀態之一。要嘛它是 非作用的——最小值舒舒服服地待在區域內部,圍欄是鬆的,這個約束無關緊要,就彷彿它根本不存在。要嘛它是 作用的——最小值正好被壓在邊界 h(x) = 0 上,此處圍欄真正在出力,表現得像一個等式。難點在於你事先並不知道「哪些」約束會是作用的;那正是求解器必須找出來的。

KKT 條件(Karush–Kuhn–Tucker)把這套「作用或不作用」的邏輯打包成乾淨的代數,並把拉格朗日推廣到不等式。它們是受限問題的基石最優性條件,而每一個受限求解器,骨子裡都是一台滿足它們的機器。它有四個部分,而第三個是那個巧妙的。

  1. 駐點性:拉格朗日函數的梯度消失——grad f = 各個 mu_i 乘以 grad h_i 的總和——所以 f 的梯度被那些作用約束的梯度所平衡,就和等式的情形一樣。
  2. 原始可行性:這個點確實遵守每一個約束,h_i(x) <= 0。一個違反圍欄的答案,根本不是答案。
  3. 互補鬆弛性:對每個不等式,mu_i 乘以 h_i(x) = 0——所以要嘛乘子 mu_i 為零(約束非作用,忽略它),要嘛 h_i(x) 為零(約束作用,落在邊界上)。兩者不能同時非零。這條方程式單槍匹馬就編碼了「哪些圍欄要緊」這整個問題。
  4. 對偶可行性:每個不等式乘子都非負,mu_i >= 0。這個符號要緊——它表示一道作用的圍欄只能把解往「內」推,絕不能往外拉,而這正是受限最小值與最大值的分野。

一個關鍵的誠實之處:KKT 條件對最佳點而言是「必要的」(在對約束的一個溫和正則性假設下),但一般而言它們並不「充分」——一個滿足它們的點可能是最小值、最大值,或一個 鞍點,正如在無約束情形裡,單憑 grad f = 0 從來定不了案。但有一個美麗的例外,那正是下一節的主題。

凸性:當 KKT 就是全部答案

回想梯度下降與牛頓法那兩篇指南裡,為什麼 凸性 是如此一份禮物:一個凸函數有著沒有假谷底的碗狀,所以任何梯度消失之處都是「全域」最小值,而不只是局部最小值。同樣的魔法延續到約束上。當目標函數是凸的、可行區域也是凸的(每個約束都凸、等式都線性)時,KKT 條件就從「僅僅必要」翻轉為完全「充分」:任何滿足它們的點都是保證的全域最佳解。你可以在 KKT 一成立的當下就停手,並確知自己真正贏了。

這就是為什麼實務工作者如此費力地把問題鑄成凸的。兩個凸族佔了主導。線性規劃(LP) 在線性約束之上最小化一個線性目標——可行區域是一個多面體,一塊多面的水晶,而最佳解總是坐落在它的某個角(頂點)上。二次規劃(QP) 則允許一個凸的二次目標搭配線性約束——它是支援向量機、投資組合最佳化,以及你先前見過的信賴域子問題背後的主力。對兩者而言,KKT 加上凸性,意味著找到的解就是被證明過的解。

在電腦上求解:障壁、內點與單純形

你究竟要怎麼讓電腦真的找到 KKT 點?最直觀的想法是 懲罰法:每當約束被違反時,就替目標函數加上一個大大的懲罰,於是被懲罰函數的無約束最小值就會往可行區域漂移。它簡單又管用,但有個缺陷——要把答案緊緊地壓上約束,你必須把懲罰權重轉得很大,而一個巨大的權重會讓問題變得兇猛地病態,於是 條件數 暴增,而(如條件性那一階所警告的)你會流失準確度,每加一個十的倍數,就大約損失一位數字。

現代的修正是 內點法,它用一個障壁取代懲罰,從內部逼近邊界。加上一個對數障壁項,當你靠近任何圍欄時它就長到正無窮大,於是迭代點被排斥、嚴格地待在內部。接著逐漸把障壁的強度縮向零;這一系列內部最小值描出一條平滑的「中心路徑」,滑向那個正好落在邊界上的真正 KKT 點。每一步本質上是對 KKT 方程組做一次牛頓步,而整個方法以一個驚人地小、幾乎與問題無關的迭代次數收斂——這正是讓巨大 LP 與 QP 變得家常便飯的突破。

對線性規劃還有經典的 單純形法,其幾何截然不同。既然 LP 的最佳解住在可行多面體的某個頂點上,單純形法就乾脆沿著邊從一個角走到另一個角,每一步移到一個能改善目標的相鄰頂點,直到沒有任何鄰居更好為止。它優雅,且在實務上快得出奇——可是這裡有一樁著名的誠實:在最壞情況下,它可能被迫造訪指數多個頂點,所以它「並非」多項式時間,儘管這種最壞情況在現實生活中幾乎從不出現。相對地,內點法帶著多項式時間的保證。兩者都久經沙場;誰勝出,取決於問題本身。

為本階收尾

退一步看看整個本階。你學會了透過梯度與黑塞矩陣來讀地形、用梯度下降一路下坡並在病態的碗裡感受它的鋸齒、用牛頓法縱身一躍並透過擬牛頓法廉價地逼近黑塞矩陣、用隨機梯度下降在帶雜訊的小批次上訓練——而現在,在圍欄之內最佳化。把這一切串起來的橋樑是一個想法:受限的最優性,不過就是某個增廣函數的無約束最優性。拉格朗日為等式造出那個函數;KKT 把它推廣到不等式;障壁與單純形則是把那個點追捕到手的引擎。

並把這個領域永久的告誡帶在身邊。求解器回傳的每個數字都是在有限的浮點數算術中找到的「近似值」,從不是精確的實數算術;一個穩定的內點步,仍然救不了一個極度病態的約束幾何。牛頓味的步只在靠近一個好的迭代點時才收斂得快。KKT 只有在問題是凸的時候才認證全域最佳解;在那個世界之外,「一個解」指的是局部解。對這些極限誠實,並非數值最佳化的弱點——它正是讓你能信任它所給出的那些答案的東西。