數值計算小結
1、上溢和下溢
計算機無法通過有限多的位來表示無限多的實數,當我們在計算機中表示一個實數時,幾乎總會存在一些誤差,在許多情況下,這被稱為舍入誤差(指運算得到的近似值和精確值之間的差異)。舍入誤差會導致一些問題,特別是進行多次運算的時候。即使是理論上可行的算法,如果在設計時沒有考慮最小化攝入誤差的累積,在實踐時也可能導致算法失效。
1.1、下溢
當接近與0的數被四舍五入為0時發生下溢,這可能造成算法失效,把該接近於0的數當做分母就會發生。舉個例子,在機器學習中經常會遇到概率預算,而概率都是介於0和1之間的數,假如一個事件發生的概率為0.1,則10個0.1相乘就非常接近於0了。
1.2、上溢
當非常大的數被認為是\(+\infty\)
1.3、一個例子:softmax函數
必須對上溢或者下溢進行數值穩定的一個例子是softmax函數。softmax 函數經常用於預測與 Multinoulli 分布相關聯的概率,其定義為:
從理論上來講,該函數值應該為1/n
。但當x中的值\(x_i\)都為很小的負數時,\(exp(x_i)\)的值就會接近0,從而發生下溢,這意味著softmax函數的分母會變成0,出現除0的錯誤;當x中的值\(x_i\)都為很大的正數時,\(exp(x_i)\)也會變得非常大,可能會超出計算機所能表示的最大數,從而發生上溢,導致最後的結果未定義。
該函數的上溢和下溢問題可以通過softmax(z),其中\(z=x-max(x)\)
2、病態條件
條件數用來衡量函數相對於輸入的微小變化而變化的快慢程度。高條件數的問題被稱為病態的。輸入被輕微擾動而迅速改變的函數對於科學計算來說可能是有問題的,因為輸入中的舍入誤差可能導致輸出的巨大變化。
考慮函數\(f(x)=A^{-1}x\),當\(A∈\mathbb(R)^m×n\)具有特征分解時,其條件數定義為:
含義是最大和最小特征值的模之比。當該數很大時,矩陣求逆對輸入誤差特別敏感,如果輸入數據有誤差,矩陣會放大誤差。
3、基於梯度的優化算法
3.1、最優化問題
大多數深度學習算法都涉及到某種形式的優化。優化是指改變x以最小化或最大化函數f(x)的任務。我們通常最小化f(x)指代大多數最優化問題,最大化可以通過最小化-f(x)得到。
我們把要最小化或最大化的函數稱為目標函數(objective function)或準則(criterion)。當我們對其進行最小化時,我們也把它稱為代價函數(cost function)、 損失函數(loss function)或誤差函數(error function)。
我們通常使用一個星號上標*
來表示最小化或最大化函數的x值,如\(x^*=arg\;min\;f(x)\),arg
的意思是獲取參數,所以該式的意義是獲取f(x)取最小值時的x值。
3.2、微積分相關內容
3.2.1、導數與偏導數
函數\(y=f(x)\)的導數記為f‘(x)或者dy/dx。導數f‘(x)代表f(x)在x處的斜率。在二元函數z=f(x,y)中,把y固定(也就是把y看成常數),這時對x求導,稱為z對x的偏導數,記為\(?z/?x\)或者\(?f/?x\)或者\(▽_xf(x)\)。
3.2.2、梯度
在微積分裏面,對多元函數的參數求?偏導數,把求得的各個參數的偏導數以向量的形式寫出來,就是梯度。比如函數f(x,y)的梯度為\([?f/?x, ?f/?y]^T\),簡寫為\(grad f(x,y)\)或者\(▽f(x,y)\)。在點(\(x_0,y_0)\))處的梯度就是\(▽f(x_0,y_0)\)。梯度從幾何意義上講,就是函數增加最快的方向。
3.3、梯度下降
導數對於最小化一個函數很有用,因為它告訴我們如何更改 x 來略微地改善 y。例如,我們知道對於足夠小的 ? 來說,f(x??sign(f′(x))) 是比 f(x) 小的(sign函數定義)。因此我們可以將 x 往導數的反方向移動一小步來減小 f(x)。這種技術被稱為梯度下降 (gradient descent),下圖給出了梯度下降的一個例子:
當 f′(x) = 0,導數無法提供往哪個方向移動的信息。f′(x) = 0 的點稱為臨界點(critical point)或駐點(stationary point)。一個局部極小點(local minimum) 意味著這個點的 f(x) 小於所有鄰近點,因此不可能通過移動無窮小的步長來減小 f(x)。一個局部極大點(local maximum)意味著這個點的 f(x) 大於所有鄰近點,因此不可能通過移動無窮小的步長來增大 f(x)。有些臨界點既不是最小點也不是最大點,這些點被稱為鞍點(saddle point)。下面是各種臨界點的例子:
使 f(x) 取得絕對的最小值(相對所有其他值)的點是全局最小點(global minimum)。函數可能只有一個全局最小點或存在多個全局最小點,還可能存在不是全局最優的局部極小點。在深度學習的背景下,我們要優化的函數可能含有許多不是最優的局部極小點,或者還有很多處於非常平坦的區域內的鞍點。尤其是當輸入是多維的時候,所有這些都將使優化變得困難。因此,我們通常尋找使 f 非常小的點,但這在任何形式意義下並不一定是最小。下面是一個例子:
我們經常最小化具有多維輸入的函數:\(f : \mathbb(R)^n →\mathbb(R)\)。為了使 ‘‘最小化’’ 的概念有意義,輸出必須是一維的 (也就是標量)。
針對具有多維輸入的函數,我們需要用到偏導數(partial derivative)的概念。 偏導數上面已經講過,另一個概念是梯度(gradient),對於f(x)來講,如果所有的變量使用向量x來表示的話,梯度就是包含所有偏導數的向量,記為\(▽_xf(x)\),梯度的第i個元素時f關於\(x_i\)的偏導數。在多維情況下,臨界點是梯度中所有元素都為零的點。
在 u(單位向量)方向的方向導數(directional derivative)是函數 f 在 u 方向的斜率。換句話說,方向導數是函數 f(x+ αu) 關於 α 的導數(在 α = 0 時取得)。 使用鏈式法則,我們可以看到當 α = 0 時, \(\frac{?f}{?α}f(x+αu)=u^T▽_xf(x)\)。
為了最小化 f,我們希望找到使 f 下降得最快的方向。計算方向導數:
其中 θ 是 u 與梯度的夾角。將 \(∥u∥_2 = 1\) 代入,並忽略與 u 無關的項,就能簡化得到 \(min cosθ\)。這在 u 與梯度方向相反時取得最小。換句話說,梯度向量指向上坡, 負梯度向量指向下坡。我們在負梯度方向上移動可以減小 f,這被稱為最速下降法 (method of steepest descent) 或梯度下降(gradient descent)。
最速下降建議新的點為:
其中 ? 為學習率(learning rate),是一個確定步長大小的正標量。我們可以通過幾種不同的方式選擇 ?。普遍的方式是選擇一個小常數。有時我們通過計算,選擇使方向導數消失的步長。還有一種方法是根據幾個 ? 計算 \(f(x???_xf(x))\),並選擇其中能產生最小目標函數值的 ?,這種策略被稱為線搜索。
3.4、Jacobian矩陣(雅克比矩陣)
有時我們需要計算輸入和輸出都為向量的函數的所有偏導數。包含所有這樣的偏導數的矩陣被稱為 Jacobian矩陣。。具體來說,如果我們有一個函數: \(f : \mathbb{R}^m →\mathbb{R}^n\),f的雅克比矩陣 \(J∈\mathbb{R}^{n×m}\) 定義為: \[J_{i,j}=\frac{?}{?x_j}f(x)_i\]
也就是說,雅可比矩陣是函數的一階偏導數以一定方式排列成的矩陣。舉個例子,有\(\mathbb{R}^4\)的f函數:
則其雅克比矩陣為:
3.5、Hessian矩陣(海森矩陣)
當函數具有多維輸入時(有很多變量),函數有很多二階偏導數,我們可以將這些二階偏導數合並成一個矩陣,稱之為Hessian矩陣(海森矩陣)。Hessian 矩陣 \(H(f)(x)\) 定義為 :
展開就是:
海思矩陣等價於梯度的雅克比矩陣。
微分算子在任何二階偏導連續的點處可交換,也就是它們的順序可以互換:
這意味著\(H_{i,j}=H_{j,i}\),因此 Hessian 矩陣在這些點上是對稱的。在深度學習背景下, 我們遇到的大多數函數的 Hessian 幾乎處處都是對稱的。因為 Hessian 矩陣是實對稱的,我們可以將其分解成一組實特征值和一組特征向量的正交基。在特定方向 d 上的二階導數可以寫成 \(d^?Hd\)。當 d 是 H 的一個特征向量時,這個方向的二階導數就是對應的特征值。
3.5.1、最優步長
我們可以通過(方向)二階導數預測一個梯度下降的步驟表現的有多好。我們在當前點\(x^{(0)}\)處作\(f(x)\)的近似二階泰勒級數展開:
其中\(g\)是梯度,\(H\)是\(x^{(0)}\)點處的海思矩陣。如果我們使用學習率ε,那麽新的點為\(x^{(0)}-εg\),代入上面的公式可得:
當上式的最後一項太大時,梯度下降實際上是可能向上移動的。當 \(g^?Hg\)(二階導數) 為零或負時,近似的泰勒級數表明增加 ? 將永遠使 f 下降。在實踐中,泰勒級數不會在 ? 大的時候也保持準確,因此在這種情況下我們必須采取更啟發式的選擇。當 \(g^?Hg\) 為正時,通過計算可得,使近似泰勒級數下降最多的最優步長為:
最壞的情況下,\(g\) 與 \(H\) 最大特征值 \(λ_{max}\) 對應的特征向量對齊,則最優步長是\(1/λ_{max}\)。
3.5.2、二階導數測試
我們可以根據二階導數的正負情況來判斷一個臨界點是局部極大值點、局部極小值點或者鞍點,這就是所謂的二階導數測試。當\(f'(x)=0\)時,說明x是一個臨界點,若二階導數\(f''(x)>0\),則說明\(f'(x)\)在x的右邊是遞增的,因為\(f'(x)=0\),所以x右邊的導數均為正,所以\(f(x)\)在x右邊單調遞增,x左邊的導數為負,所以\(f(x)\)在x左邊遞減,則x為局部極小值點;同理當二階導數\(f''(x)<0\)時,x為\(f(x)\)的局部極大值點;當二階導數\(f''(x)=0\)時,x可以是一個鞍點或平坦區域的一部分。
上面討論的函數只有一個未知數,我們通過函數二階導數的正負即可判斷臨界點的情況。當函數有多個參數時,我們需要檢查該函數所有的二階導數,也就是海思矩陣(Hessian矩陣)。一元函數二階導數的正負對應海思矩陣特征值的正負。所以有:在臨界點處(梯度\(▽_xf(x)\)=0),若海思矩陣的特征值全為正(正定的),則該臨界點是局部極小值點;若海思矩陣的特征值全為負(負定的),則該臨界點是局部極大值點;如果海思矩陣的特征值中至少有一個正的並且至少有一個負的,那麽 x 是 f 某個橫截面的局部極大點,卻是另一個橫截面的局部極小點,見下圖:
最後,多維二階導數測試可能像單變量版本那樣是不確定的。當所有非零特征值是同號的且至少有一個特征值是 0 時,這個檢測就是不確定的。這是因為單變量的二階導數測試在零特征值對應的橫截面上是不確定的。
3.6、牛頓法
多維情況下,單個點處每個方向上的二階導數是不同的。Hessian 的條件數(在上文中,矩陣條件數定義為最大和最小特征值之比)衡量這些二階導數的變化範圍。當 Hessian 的條件數很差時,梯度下降法也會表現得很差。這是因為一個方向上的導數增加得很快,而在另一個方向上增加得很慢。梯度下降不知道導數的這種變化,所以它不知道應該優先探索導數長期為負的方向。病態條件也導致很難選擇合適的步長。步長必須足夠小,以免沖過最小而向具有較強正曲率的方向上升。這通常意味著步長太小,以致於在其他較小曲率的方向上進展不明顯。我們可以使用牛頓法來解決這個問題。
先來看一下使用牛頓法求解一元函數的零點。首先我們選擇一個接近\(f(x)\)零點的值\(x_0\),計算\(f(x_0)\)和\(f'(x_0)\),然後求出過點\((x_0, f(x_0))\)且斜率為\(f'(x_0)\)的直線與x軸的交點坐標,也就是求如下方程的解:
我們將新求得的點的x坐標命名為 $ x_1$,通常 \(x_1\)會比 \(x_{0}\)更接近方程 \(f(x)=0\)的解,因此我們現在可以利用\(x_1\)開始下一輪叠代。叠代公式為:
不停的叠代,最後求得的x會越來越接近f(x)=0的解,如下圖(圖來自維基百科)
推廣到多維變量,牛頓法基於一個二階泰勒展開來近似 \(x^{(0)}\) 附近的 \(f(x)\):
令\(f'(x)=0\),我們可以得到這個函數的臨界點:
當 f 是一個正定二次函數時,牛頓法只要應用一次上式就能直接跳到函數的最小點。如果 f 不是一個真正二次但能在局部近似為正定二次,牛頓法則需要多次叠代應用上式。叠代地更新近似函數和跳到近似函數的最小點可以比梯度下降更快地到達臨界點。這在接近局部極小點時是一個特別有用的性質,但是在鞍點附近是有害的。當附近的臨界點是最小點(Hessian 的所有特征值都是正的)時牛頓法才適用,而梯度下降不會被吸引到鞍點(除非梯度指向鞍點)。
僅使用梯度信息的優化算法被稱為一階優化算法 (?rst-order optimization algorithms),如梯度下降。使用 Hessian 矩陣的優化算法被稱為二階最優化算法 (second-order optimization algorithms),如牛頓法。
4、約束優化
有時候,在 \(x\) 的所有可能值下最大化或最小化一個函數 \(f(x)\) 不是我們所希望的。相反,我們可能希望在 \(x\) 的某些集合 \(\mathbb{s}\) 中找 \(f(x)\) 的最大值或最小值。這被稱為約束優化(constrained optimization)。在約束優化術語中,集合 S 內的點 x 被稱可行點(feasible point)。
5、參考
5.1、《深度學習》中文版
數值計算小結