卷積神經網絡 + 機器視覺: L6_初始化_激勵函數_BN_梯度下降 (斯坦福CS231n)

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

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

前一課堂筆記連結:

 

Menu this round:

  • activation function
  • data processing
  • weight initialization
  • batch normalization
  • babysitting the learning process
  • hyperparameter optimization

第六節主要討論的是如何讓神經網絡自動的去學習權重值 weight 該沿着怎麼樣的梯度下降去得到最優解。Gradient Descent (我自己簡稱 GD)通過微分取最小值的方式處理方程式,是目前最有效的找解方案,而這個找解的過程也有叫做 optimization。

而 GD 在這裏操作的整個過程全名又叫做 Mini-Batch sarcastic gradient descent (SGD),叫做 mini-batch 的原因是因爲每次都只找 “一小撮” 數據作爲參考去預測更優的值,雖然這樣不全面,但是可以很大的減小電腦計算資源和負擔,還是利大於弊的。方法步驟如下:
    1. 拿出一小撮數據作爲 sample
    2. 把這些數據逐一代入 Loss Function 模型中,得到 loss 值
    3. 反向傳播 Backpropagate 去算出梯度 gradient
    4. 沿着梯度 有效的更新參數

 

Activation Function

它就像一個自然界中的神經元原理,從外部接受了一個外界刺激,經過內部的激勵反應運作,最後從右邊得出一個輸出信號。

上圖是我們常用的激勵函數總覽,不同的情況適用不同的激勵方法取實踐,但是各個激勵函數也有彼此的優劣地方,以下介紹。

Sigmoid

從發展史來看,這個方法受歡迎的時間很久,可以很簡單的用一個 function 去描述一個 0 與 1 的開關,但是隨着運算的發展,它的問題也逐漸暴露:

  1. 一旦輸入值過大或是過小進入了圖中躺平的線段,它就扼殺了原本數據中應該呈現出來的梯度(或是可以說它抹平了數據本該有的差異),數據最珍貴的就是他們的差異啦,被這樣一抹還得了,要是多做幾次神經傳遞,那大家都一樣了,容易失真。
  2. 它不是一個 “zero-centered” 的函數類型,白話文就是,不論 x 值大於或是小於 0 ,輸出值都是正的,這件事情本身不是個問題,問題會在傳遞到下一個神經層的時候浮現,這一輪的 output 會作爲下一層的 input 被輸入,如果所有的 input 都是正的,那麼她們在做 GD 計算 Backprop 的時候肯定得出來的值要不全都是正的或是都是負的,造成權重值在更新的時候只能沿着一個維度做鋸齒狀步進,是個很沒效率的方式。
  3. 說到計算本身,實際應用中計算資源寶貴,Sigmoid 出現了 exp() 意味着它將佔據大量的資源和效率,當應用在龐大的深度學習的時候,差距就看出來了。

tanh

這個 function 跟 Sigmoid 類似,不過少了第二項的缺點,並且沒有 exp() 的運算,但是他仍然有抹平梯度的問題,需要很小心的做初始化 initialization 才能讓所有的 data 不陷入梯度消失的區域(initialization 後面提及)。

ReLU

前面幾堂課中使用的方法就是此法,它結合了幾種優點於一身,是一個目前我們最常用的激勵函數,原因如下:

  1. 它在 “第一象限” 中是不會出現梯度被磨平的情況的,保留數據之間最珍貴的差異化。
  2. 它計算的時候沒有 exp() 項,意味着不佔用資源,實際角度看它的速度是 sigmoid/tanh 的六倍快。
  3. 從仿生的生物角度來看,它也比 sigmoid 更有說服力

但是它還是有 Sigmoid 第二項缺點,這也意味着如果初始參數沒有妥善的被設定,或是學習效率調的太高了,那麼 ReLU 就會因爲這個缺點,慢慢的跳出數據分佈的地方,並且永遠無法隨着梯度更新回來,因此 Leaky ReLU 被髮明出來,一勞永逸。

Leaky ReLU

結合了上面的所有優點,並且屏蔽了所有的缺點,好處我重新列一遍:

  1. 它不抹平數據差異
  2. 計算起來非常高效迅速
  3. 它不會像 ReLU 那樣需要妥當的初始化,不然會直接死掉

Exopnential Linear Units (ELU)

這個方法介於 ReLU 與 Leaky ReLU 之間,用上了 exp() 拖慢了速度,並且雖然它也是 zero-centered 的特徵,但負得太離譜的情況差異還是被抹平了,因此主要還是看實際應用情況而選擇方法。

Maxout

從公式看上去,它結合了兩種方法,經過兩種方法得出來的值比較後,取其中最大的值作爲結果輸出,雖然這樣也有效的結合了各種方法的優點,但是對於一個數據來說,算兩遍意味着 “吃資源” 不是我們鼓勵的做法,速度也是直接砍一半。

經驗總結

    1. 一般適用 ReLU,但是小心調整學習效率 learning rate 的參數。
    2. 搭配着可以試試看 Leaky ReLU / ELU / Maxout 看哪一個方法在當下模型表現最好
    3. 可以試試看 tanh 但是別期待什麼好結果,而 sigmoid 就別用了哈

 

Data Preprocessing

當我們面對一些數據要用到 machine learning 的方法處理時,我們一般會先讓數據整體分佈對齊座標軸中心,再 normalize 這些數據(把原本離散的數據點,濃縮到 0 與 1)的範圍。

對於圖片 pixel 的數據而言,雖然我們也做 zero-centered 的處理,但是一般不做太複雜的事前處理,包含了 normalization,因爲對於圖片處理,我們使用的是 Convolution 的方式,並得出 local 的空間結構與特徵。

再者,不做過於複雜的預處理原因是我們不希望讓 pixel value 被投射到一個低維度的空間去,損失特徵對圖像識別來說不是什麼好事。因此,對於圖片的 normalization 我們只做到讓不同權重之間的影響因子大小一樣,如圖:

可以想象成 normalization 這個動作就是從集權走向共和的過程,不要讓其中一個人的權利過於凸顯,導致它做一個小的改變就足以撼動世界,中庸之道的綠色同心圓將會是個更好的訓練模型。做法如下:

不過訓練數據與測試數據的時候,毋庸置疑的都會用上 zero-centered 的方法,並且提取 mean image 到下一個層去處理。做了 zero-center 後,可以讓參數對於數據不那麼敏感,因爲 f(x)=Wx+b,數據越接近中間,作爲斜率的 W 變化的時候,相對於不在中間的情況,影響就會小很多。

 

Weight Initialization

訓練總要有個起點,那麼這個起點設置的位置就成爲了一個重要的探討話題,總不可能把 W=0 作爲起點,讓全部的 neuron 做一樣的事情,那有做等於沒做,一個無法創造差異的做法總是最壞的做法。

方法 1 :小的隨機數

>>> W = 0.01 * np.random.randn(Rows, Columns)
# this formula generates the random number based on normal distribution
# the number of the rows and columns for the generated array should be set in these parameters

更多的 numpy 補充可以參考:
    o  https://blog.csdn.net/zenghaitao0128/article/details/78556535

 

但是問題來了,如果這個參數過於小,經過多層的神經網絡傳遞後,梯度就消失了,因爲所有 activation function 得出來的結果都貼近 0 ,加上常態分佈下的小的隨機數初始化無疑是個必須捨棄的方法。

 

方法 2 :大一些的隨機數(-1~1 之間)

>>> W = np.random.randn(Rows, Columns) * 1.0

然而,這個方法在多層神經網絡傳遞後,所有 neuron 的數值也幾乎都 saturate 了,原因是放入 activation function 裏面後,大的數值都落入了方程式兩極的位置,也是個不好的傳遞過程。

方法 3 :Xavier Initialization

爲了解決上面兩個方法經過多層神經網絡傳遞產生的 saturated 問題,這個方案誕生了。
附贈兩篇解釋原理的論文鏈接:
    o  http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf
    
o  https://arxiv.org/pdf/1607.02488.pdf

>>> W = np.random.randn(rows, columns) / np.sqrt(rows)

當輸出的數小了的話,那就也除以一個小的數去挽回持續縮小的局面,但是這個方法遇到了 nonlinear function 像是 ReLU 的話也會出問題,因爲 ReLU 把接近一半的數據變化抹平了,導致經過不斷的傳遞後,還是會出現 saturation 的情況(詳情見論文)。

教學投影片裏尚有一頁論文集推薦選讀,可自行查找。

 

Batch Normalization

推薦論文讀物(HW 之一):
    o  http://proceedings.mlr.press/v37/ioffe15.pdf
臺灣大學 NTU 視頻講解:
    o  https://www.youtube.com/watch?v=BZh1ltr5Rkg

主要是爲了解決 internal covariate shift 產生的問題,問題產生的原因如下描述:
    我們都知道一個原始數據作爲 input 在 neural network 裏面傳遞,經過 activation function 得到的輸出結果會再作爲下一層 network 的 input 繼續傳下去,那爲了更好的使 data 傳遞到最後還保有特徵不 saturate,每次每個 neuron 傳遞前都會做前面介紹的 data preprocessing,讓數據更好的被傳遞。但是問題來了!每次傳遞過程的同時,我們也不斷依據 Loss function 的反向傳播回來的結果修正原本傳遞下去的數據,修正前的數據 normalized 的結果是當時的最優傳遞狀態,但是我們卻無法保證是不是修改過後,這個上次傳遞的結果還是現在的最優(基本已經不是最優),這種情況發生在每一層,因此我們永遠也無法很有效率的讓層跟層之間好好的嫁接。因此新的技術:Batch Normalization 因應而生。

這個過程放在 activation function 前面後面都可以,不過比較建議放在前面,因爲這樣可以更加確定的讓 data 不要落在會 saturate 的區域,降低初始值設定的困難度意味着整體的學習效率參數可以調得更高,也提升整體學習效率。

整體流程如上圖,先求得小撮 data 的平均值(一小撮數據好掌控的同時計算資源也不會佔用太多),在用求得的平均值計算標準差,接着進入 normalization 真正環節,最後給 normalize 好的結果套上一個屬於 neural network 參數一部分的 gama 和 beta 值。在每次反向傳播的時候,平均值與標準差是深受其影響的參數,可以有效扣住於變化中數據的關聯,讓不論怎麼跑的數據最後面都可以正確被 normalized。

有了這個方法,多了很多好處:

  • 它提升了梯度運算的有效性
  • 它解放了更大的 learning rate 使用的可能性
  • 它讓 weight initialization 的重要性降低,降低門檻
  • 它可以稍微減小 dropout 方法的需要性
  • 最後一個階段中,我們還可以控制 beta 和 gama 兩個獨立不受 dataset 影響的參數來更好的調整 saturation 程度,根據不同情況的需求可以非常客製化的給予響應。

因爲 BN 只是重新按照一定的規則排布了神經網絡的資料結構,並不會對數據本身造成任何的改動,所以是個沒有情況限制的通用方法。

Babysitting the learning process

數據預處理 >>> 選擇模型結構 >>> 初始化 network >>> 確保 loss 在合理範圍

一般來說 learning rate 設定在 1e-3 ~ 1e-5 的範圍內,太小的話會造成修正的速度很慢,就像蝸牛爬行那樣,耗時耗力。其他代碼的部分自行到投影片裏面去理解咯~

 

Hyperparameter Optimization

Cross validation 是一個找出 Hyperparameter 的好方法,之前章節裏面有介紹過(https://blog.csdn.net/qq_37165755/article/details/79874875),這個優化參數的過程過程需要時間去跑模型,是不可避免的過程。

When finding the hyperparameters, there are two ways to sample the values: random search and grid search. It turns out that the random one takes a better performance. For starter, the range to find out those proper hyperparameters must be wide in space. random space distribution can help us finding out which regions could perform better so that we can further narrow down the original wide range. By times of iteration, the region would be focused onto a precise location, and the hyperparameters would be found.

一般來說,在找尋 Hyperparameter 的過程中,需要無數次的人工調整過程,就像一個 DJ 調整各種音效控制一樣尋找最完美的搭配輸出,這個過程像是一門藝術,下面是調出來的結果比較圖例:

爲了更好的可視化理解數據變化的過程,非常建議使用 matplotlib 裏面的話圖功能,實時監控當下動態。

 

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

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