卷積神經網絡 + 機器視覺:L7_進階梯度下降_正則化_遷移學習 (斯坦福CS231n)

完整的視頻課堂鏈接如下:

完整的視頻課堂投影片連接:

前一課堂筆記連結:

 

Menu this round

  • Fancier Optimization
  • Regularization
  • Transfer Learning

如果一個神經網絡模型中,我們把學習效率 learning rate 總是調的很低,理論上只要時間允許的情況下,結果也總是可以達到預期的。但是現實很骨感,在迅速變遷的時代,學得不夠快的模型又怎麼能夠滿足以效率著稱的科技公司們的胃口呢?因此必須有一個更好的辦法加速這個學習過程,更快的找到 Hyperparameter 才行。

雖然前面說的 Gradient Descent 理論上很完美,總是沿着梯度不斷下滑,到最後就可以找到最小值,但是實際過程中越多維度越容易造成的坑坑巴巴路面總是讓 GD 的路徑扭來扭去,不直接快速的滑到低谷裏,因此這邊即將介紹一些方法來改進這個缺陷。

 

最簡單的 GD 長相如下

>>> while True:
        weight_grad = evaluate_gradient(loss_fun, data, weights)
        weights += -step_size * weight_grad        # perform parameter update

就如同前面一個章節提到的,如果沒有好的 normalization 過程,那麼在不同權重影響力偏差的情況下,再加上每次採樣都是 mini-batch 的方式只有局部數據的支持,就更容易走出歪歪斜斜的軌跡出來,如圖:

這只是一個二維的路徑波動,紅點表示 GD 的出發點,紅線表示波折的路徑,如果再把維度增加,那麼整個軌跡將會變得更加的混亂耗時,並且將出現更多可以被誤認爲最小值的窪地。

另一個問題是,圖裏面雖然單純的顯示了一個最低點(笑臉),但是實際情況可能是有各種各樣的坑洞與 “當個區域” 的最小值,甚至只是遇到了一個平原區域剛好沒有梯度,這些情況都不是整個方程式的最小值,如果初始位置放得不對,紅點將只能夠沿着梯度滑到 local minimum 而永遠卡死在 “該坑” 裏面萬劫不復超生。

 

Normal Momentum

爲了解決上述問題,原本的算法是專注在 “步數” 方面隨着梯度大小的增加與減少,取而代之的是使用速度的概念,根據當下給定的梯度值去預測未來(下一步)的速度該是如何前進的,由於速度有方向性,因此可以一起把方向和大小同時掌握在計算過程中,如圖:

對比於純粹的 SGD 方法,Momentum 項可以視爲是當前速度的 friction 摩擦力(修正方向與量的概念),藉由控制整個速度向量的步進,原本歪七扭八的路線就會得到很好的平滑修正,雖然可能已經抵達了極值點的時候還是會因爲一個慣性繼續前行,後面幾步再漸漸修正回極值點的位置上,但找極值的速度相比起來也還是可以更加有效率。

 

Nesterov Momentum

這個方法其實跟上一個一樣,都是 Momentum 系列的概念,唯一差別就是向量加法上的不同,如圖:

Normal(左)的做法是在當下的那一點基於先前梯度預測出來的速度,加上當下該點實際上的梯度,去加總出一個下一步的修正方向;反之 Nesterov(右)不同的地方在於它所加的梯度值是基於當下點預測未來 “一步” 會到達的那個新點的梯度,相加後得出下一步的修正方向。具體算法與代碼如下:

其實這兩個方法的出發點是類似的,所以結果上來看也沒有什麼太多的不同,差不多的效率。

一般來說,我們並不希望看到非常陡峭的最小值出現,因爲在實際應用中它可能就是一個過擬合的解,甚至可能等之後加入更多的數據一同訓練時,這個點就被平均掉了,flat minimum would be more robust!

 

AdaGrad

這是一個現在任職 Stanford 的教授它博士的時候提出的算法,特點在於每次從梯度給予步進方向和量的時候,總要除以歷史記錄中所有梯度平方的總和的開根號值,目的在於處理那些權重影響力不同的點的步進方向,給其中影響力大的權重除以相對大的值,和影響力小的權重除以相對小的值,就可以有效的消除 normalization 沒弄好的誤差。如圖公式:

要是走的步數越來越多了,分母項的加總項也會越來越大,計算的東西越來越多的同時,還降低了每次行走的步距,並且它不適合 “平原行走” ,會直接停在原地,只適用 Convex 地形,因此 RMSProp 就出來解救危難了。

 

RMSProp

如上圖的公式表示,它不像 AG 那樣總是拖着沉重的歷史包袱行走於梯度降低的路上,他學會了 “淡忘” 歷史信息,加了一個 decay_rate 項於其中。This small modification ended up like a momentum update except we are having a momentum square gradient rather than the momentum actual gradient.

但是爲了要讓同一個方法在不同的條件中都能夠最好的表現,把 learning rate 分開到不同的算式成爲了必須的過程。

 

Adam

說了那麼多好方法,何不讓他們取長補短合在一起用呢?這就來了個 Adam!
下面鏈接是 Adam 的論文講解
    o  https://arxiv.org/pdf/1412.6980.pdf

The code goes like this:

first_moment = 0
second_moment = 0
while True:
    dx = compute_gradient(x)
    # here comes the method of SGD momentum
    first_moment = B1 * first_moment + (1 - B1) * dx
    # here comes the method of AdaGrad/RMSProp
    second_moment = B2 * second_moment + (1 - B2) * dx * dx
    first_unbias = first_moment / (1 - B1 ** t)
    second_unbias = second_moment / (1 - B2 ** t)
    # two of these codes above are used to prevent the beginning stride from too big value
    x -= learning_rate * first_moment / ((np.sqrt(second_moment) + 1e-7))

如代碼所描述的那樣,這個方法就如同 RMSProp + Momentum,具有兩者的特徵,不僅保持了原本 Momentum 的衝勁,也有 RMSProp 的冷靜。

不過需要注意 second_moment 的初始值,如果分母的值一開始很小,就會從數學算法上造成很大的步進(非地形梯度產生),這個情況可能讓第二步跑到一個意想不到的位置,使得收斂無法控制。爲此代碼中添加了保護措施,如 # 標記。

Adam 是老師的 default method,並且 B1 = 0.9;B2 = 0.999;learning_rate = 1e-3 or 5e-4 通常是個好的開頭!

以上所有的方法 learning_rate 都是一個 hyperparameter ,意味着最恰當的值只能靠人的經驗去輸入。

 

Second-Order Optimization

上面介紹的所有算法都是基於一階的梯度計算,不過如果把一階的梯度方程作爲一個原始的方程再次尋求其梯度,好處就是可以直接一步到位梯度的最小值的位置(飛躍式),並且不需要 learning rate 這個參數的介入,公式如下:

又名爲 “second-order Taylor expansion“,雖然這方法理論上很完美,但在骨感的現實面前還是一樣的無力,因爲當這個方法應用在 deep learning 的時候,沒有那麼多的計算機內存去緩衝這些待處理數據和節點。

另外,整體表現看來,這個方法並不是很穩定,所以就簡單介紹到這裏。
對於 local minimum 的問題,採用的方式可以是多幾個測試點,從該些測試點開始做梯度運算,最後做交叉對比看誰的值最恰當。

 

Regularization - Single model improvement

前面的課程中介紹過 L2 的方法,然而它實際應用在 CNN 的模型中時沒起到什麼顯著的效果,Regularization 的公式如下:

因此這邊介紹一個非常非常實用且常用的方法:Dropout

Dropout

關於 dropout 的兩篇論文網址如下:
    o  https://pdfs.semanticscholar.org/58b5/0c02dd0e688e0d1f630daf9afc1fe585be4c.pdf

    o  https://www.cs.toronto.edu/~hinton/absps/JMLRdropout.pdf

不像 L2 那樣在每個項後面都加上一些東西,這個方法隨機的把每層 neural network 設定爲 0 的輸出,讓他們不被 activated,像這樣:

dropout 成爲一個 good idea 的理由:

  • 它避免了 neural network 過於依賴某些特徵去判斷事情,剛好這方法提供了一個途徑去分散那些特徵的凸顯程度,讓整個 model 不要那麼較真。
  • 這有點 cross validation 的味道,隨機的挑選某些神經元去 fit model,看這些 “sub neural network” 擬合效果是否具有一定水準。

但是 dropout 也是有缺點的,這般隨機的歸零會增加整個 model 運算的時間,不過爲了拿到更好的結果,那是值得的。更多的代碼範例請自行查閱課堂講義。

 

除了 dropout 之外,尚有很多好的方法值得被運用在 nerual network 裏面提升分辨效能:

  • Batch Normalization
    前面介紹過了,這已經可以算是 NN 裏面的標配
  • Data Augmentation
    Color Jitter 可以強化顏色分辨的能力
  • DropConnect
    類似Dropout歸零的作用,但是歸零的東西時權重值 weight,而非 activation function 的結果
  • Fractional Max Pooling
    不像一般的 pooling 每個 dataset 的區域按照一定的面積和區域去做 pooling,而是隨機挑選區域去 pooling
  • Stochastic Depth
    這個方法只有在多層的神經網絡中才能被使用,他直接隨機的跳過某些層

 

Transfer Learning 遷移學習

站在巨人的肩膀上就是這個概念,我們可以利用別人已經訓練好的龐大 neural network,經過簡單的修改後定製化的爲我所用。過程如下:

  1. Train on ImageNet
  2. Reinitialize the small dataset and freeze the rests
  3. 如果過程中有更多的 data 需要參與訓練,可以增加幾層神經網絡去把新的數據更新到整個 dataset 中

Here is the strategy when encountering different situations:

  Very similar dataset Very different dataset
Very little data 用線性分選器套在現有的 model 上即可 那麻煩大了,選一個像一點的 net 再嘗試吧
Quite a lot of data 基於已有的神經網絡,增加幾層新神經層把新的數據融入網絡中 多加幾層神經層,把新的數據融入其中外,整個 initialization 的過程與參數設置可能都要重新調整

If we are facing a problem without a corresponding dataset to train with, go to find some pre-trained dataset so that we can only change a little bit of parameters based on that what we called "model-zoo".

The list of model-zoo for those in different frameworks:

 

下節鏈接:卷積神經網絡 + 機器視覺:L8_Static_Tensorflow_Dynamic_Pytorch (斯坦福課堂)

發佈了43 篇原創文章 · 獲贊 33 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章