1.梯度的概念
梯度是一個矢量,表示某一函數在該點處的方向導數沿着該方向取得最大值,即函數在該點處沿着該方向變化最快。html
在微積分裏面,對多元函數的參數求∂偏導數,把求得的各個參數的偏導數以向量的形式寫出來,就是梯度。好比函數f(x,y), 分別對x,y求偏導數,求得的梯度向量就是(∂f/∂x, ∂f/∂y)T,簡稱grad f(x,y)或者▽f(x,y)。git
問 1)梯度的公式是什麼?github
(要記得是極限的形式)
問 2)曲線有斜率嗎?
沒有,曲線上的點的切線纔有斜率。曲線有梯度。算法
2.梯度降低的概念
問:爲何 反方向更新?
參數的更新公式爲網絡
當梯度(導數)爲負數的時候(降低),θ增長,即往曲線的下方移動
當梯度爲正,θ減少後並以新的θ爲基點從新求導,一直迭代機器學習
在不斷迭代的過程當中,梯度值會不斷變小,因此θ的變化速度也會愈來愈慢,因此在這裏其實並不須要使學習率的值隨着時間愈來愈小函數
值得注意的是步長的大小,過小,則會迭代不少次才找到最優解,若太大,可能跳過最優,從而找不到最優解。這個時候,學習率衰減就起到相當重要的做用了性能
Python 示例: @ Standford CS231n [Optimization Note](http://cs231n.github.io/optimization-1/) /** * 如下代碼以基礎梯度公式爲例 */ def eval_numerical_gradient(f, x): """ 一個f在x處的數值梯度法的簡單實現 - f是隻有一個參數的函數 - x是計算梯度的點 """ fx = f(x) # 在原點計算函數值 grad = np.zeros(x.shape) h = 0.00001 # 對x中全部的索引進行迭代 it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) while not it.finished: # 計算x+h處的函數值 ix = it.multi_index old_value = x[ix] x[ix] = old_value + h # 增長h fxh = f(x) # 計算f(x + h) x[ix] = old_value # 存到前一個值中 (很是重要) # 計算偏導數 grad[ix] = (fxh - fx) / h # 坡度 it.iternext() # 到下個維度 return grad
該代碼中h根據微分原理取值應該越小越好,建議值爲1e−5左右。並且中心差值梯度效果也確定比基礎梯度效果好,可是相應的計算量也會增大。學習
3.梯度降低的數學描述優化
參考:
http://www.cnblogs.com/pinard/p/5970503.html
4.隨機梯度降低
假如咱們要優化一個函數 f(x),即找到它的最小值,經常使用的方法叫作 Gradient Descent (GD)。提及來很簡單, 就是每次沿着當前位置的導數方向走一小步
GD 算法至少有兩個明顯的缺陷。
首先,在使用的時候, GD須要計算f(x)的精確導數,每每意味着咱們要花幾個小時把整個數據集都掃描一遍,而後還只能走一小步,通常 GD 要很長時間才能收斂。
其次,若是咱們不當心陷入了鞍點,或者比較差的局部最優勢,GD 算法就跑不出來了,由於這些點的導數是 0。什麼是鞍點:鞍點是函數上的導數爲零但不是軸上局部極值的點
因而Stochastic Gradient Descent (SGD) 算法被提出,解決GD的缺陷。
雖然SGD的降低方向包含必定的隨機性,可是從期望上來看,它是等於正確的導數的。
因爲它對導數的要求很是低,能夠包含大量的噪聲,只要指望正確就行,因此導數算起來很是快
除了算得快,SGD 有很是多的優良性質。它可以自動逃離鞍點,自動逃離比較差的局部最優勢,並且,最後找到的答案還具備很強的通常性(generalization),即可以在本身以前沒有見過可是服從一樣分佈的數據集上表現很是好
問:什麼是鞍點?
首先,咱們考慮的狀況是導數爲0的點。這些點被稱爲 Stationary points,即穩定點。穩定點的話,能夠是(局部)最小值,(局部)最大值,也能夠是鞍點。如何判斷呢?咱們能夠計算它的 Hessian 矩陣 H。
- 若是 H 是負定的,說明全部的特徵值都是負的。這時,不管往什麼方向走,導數都會變負,也就是說函數值會降低。因此,這是(局部)最大值。
- 若是 H 是正定的,說明全部的特徵值都是正的。這時,你不管往什麼方向走,導數都會變正,也就是說函數值會上升。因此,這是(局部)最小值。
- 若是H既包含正的特徵值,又包含負的特徵值,那麼這個穩定點就是一個鞍點。具體參照以前的圖片。也就是說有些方向函數值會上升,有些方向函數值會降低。
- 雖然看起來上面已經包含了全部的狀況,可是其實不是的!還有一個很是重要的狀況就是 H 可能包含特徵值爲0的狀況。這種狀況下面,咱們沒法判斷穩定點到底屬於哪一類,每每須要參照更高維的導數才行。想一想看,若是特徵值是0,就說明有些方向一馬平川無邊無際,函數值一直不變,那咱們固然不知道是怎麼回事了:)
上面第四種,是被稱爲退化了的狀況,這裏只關注前幾種非退化狀況。
在這種非退化的狀況下面,咱們考慮一個重要的類別,即 strict saddle 函數。這種函數有這樣的特色:對於每一個點 x
- 要麼 x 的導數比較大
- 要麼 x 的 Hessian 矩陣包含一個負的特徵值
- 要麼 x 已經離某一個(局部)最小值很近了
爲何咱們要 x 知足這三個狀況的至少一個呢?由於
- 若是 x 的導數大,那麼沿着這個導數必定能夠大大下降函數值(咱們對函數有光滑性假設)
- 若是 x 的 Hessian 矩陣有一個負的特徵值,那麼咱們經過加噪聲隨機擾動,跑跑就可以跑到這個方向上,沿着這個方向就可以像滑滑梯同樣一路滑下去,大大下降函數值
- 若是 x 已經離某一個(局部)最小值很近了,那麼咱們就完成任務了,畢竟這個世界上沒有十全十美的事情,離得近和精確跑到這個點也沒什麼區別。
因此說,若是咱們考慮的函數知足這個 strict saddle 性質,那麼 SGD 算法實際上是不會被困在鞍點的.那麼 strict saddle 性質是否是一個合理的性質呢?
實際上,有大量的機器學習的問題使用的函數都知足這樣的性質。好比 Orthogonal tensor decomposition,dictionary learning, matrix completion 等等。並且,其實並不用擔憂最後獲得的點只是一個局部最優,而不是全局最優。由於實際上人們發現大量的機器學習問題,幾乎全部的局部最優是幾乎同樣好的,也就是說,只要找到一個局部最優勢,其實就已經找到了全局最優,好比 Orthogonal tensor decomposition 就知足這樣的性質,還有小馬哥 NIPS16 的 best student paper 證實了 matrix completion 也知足這樣的性質。我以爲神經網絡從某些角度來看,也是(幾乎)知足的,只是不知道怎麼證。
下面討論一下證實,主要討論一下第二篇。第一篇論文其實就是用數學的語言在說"在鞍點加擾動,可以順着負的特徵值方向滑下去"。第二篇很是有意思,我以爲值得介紹一下想法。
首先,算法上有了一些改動。算法再也不是 SGD,而是跑若干步 GD,而後跑一步 SGD。固然實際上你們是不會這麼用的,可是理論分析麼,這麼考慮沒問題。何時跑 SGD 呢?只有當導數比較小,並且已經很長時間沒有跑過 SGD 的時候,纔會跑一次。也就是說,只有確實陷在鞍點上了,纔會隨機擾動一下下。
由於鞍點有負的特徵值,因此只要擾動以後在這個方向上有那麼一點點份量,就可以一馬平川地滑下去。除非份量很是很是小的狀況下才可能會繼續陷在鞍點附近。換句話說,若是加了一個隨機擾動,其實大機率狀況下是可以逃離鞍點的!
雖然這個想法也很直觀,可是要嚴格地證實很不容易,由於具體函數多是很複雜的,Hessian 矩陣也在不斷地變化,因此要說明"擾動以後會陷在鞍點附近的機率是小几率"這件事情並不容易。
做者們採起了一個很巧妙的方法:對於負特徵值的那個方向,任何兩個點在這兩個方向上的投影的距離只要大於 u/2,那麼它們中間至少有一個點可以經過多跑幾步 GD 逃離鞍點。也就是說,會持續陷在鞍點附近的點所在的區間至多隻有 u 那麼寬!經過計算寬度,咱們也就能夠計算出機率的上屆,說明大機率下這個 SGD+GD 算法可以逃離鞍點了。
5.隨機梯度降低的數學描述
參考:https://www.cnblogs.com/ooon/p/5485231.html
這裏貼上著名的幾個動圖,以示幾種梯度降低法的性能差別。
(搬運自水印)
參考:
https://blog.csdn.net/u010248552/article/details/79764340
https://www.cnblogs.com/ooon/p/4947688.html
https://blog.csdn.net/u013709270/article/details/78667531