主頁 >  其他 > 李宏毅深度學習2021春p5-9:神經網路訓練技巧

李宏毅深度學習2021春p5-9:神經網路訓練技巧

2021-09-24 07:42:47 其他

李宏毅深度學習2021春p5-9:神經網路訓練技巧

兄弟萌也可以到我的博客康康:冬于的博客

訓練遇到的問題

  1. 引數不斷的更新,training loss一開始下降,然后不會再下降,但距離0還有很遠的gap;
  2. 一開始model就train不起來,不管怎么update引數,loss一直比較大,

導致上述問題的原因可能有很多,我們先回憶一下梯度下降演算法在現實世界中面臨的挑戰:

  • 問題1:區域最優(Stuck at local minima)
  • 問題2:等于0(Stuck at saddle point)
  • 問題3:趨近于0(Very slow at the plateau)

img

像這種gradient為0的點,統稱critical point,我們先從問題1和問題2來看看如何“煉丹”,

區域最小值local minima和鞍點saddle point

Critical Point

gradient為0的點,

local minima

**現在所在的位置已經是區域loss最低的點,**往四周走 loss都會比較高,可能沒有路可以走,

saddle point

**saddle point從某個方向還是有可能到達loss更低的位置,**只要逃離saddle point,就有可能讓loss更低,

如何判斷某個位置是local minima還是saddle point?

通過泰勒級數展開估計(Tayler Series Approximation)loss function的形狀,

也就是,雖然無法完整、準確寫出 L ( θ ) L(\theta) L(θ),但如果給定某一組引數 θ ′ \theta' θ,在 θ ′ \theta' θ附近的loss function可以通過泰勒級數展開來估計:

  • 第一項 L ( θ ′ ) L(\theta') L(θ):當 θ \theta θ θ ′ \theta' θ很近的時候, L ( θ ) L(\theta) L(θ) L ( θ ′ ) L(\theta') L(θ)比較靠近,但還有一些差距;
  • 第二項 ( θ ? θ ′ ) T g (\theta-\theta')^Tg (θ?θ)Tg是一個向量,這個 g g g是gradient,這個gradient會來彌補 θ ′ \theta' θ θ \theta θ之間的差距,有時候gradient會寫成 ? L ( θ ′ ) \nabla L(\theta') ?L(θ)它的第 i i i個component,就是 θ θ θ的第 i i i個component對 L L L的微分,加上這一項之后仍然還有差距;
  • 第三項中 ( θ ? θ ′ ) T H ( θ ? θ ′ ) (\theta-\theta')^TH(\theta-\theta') (θ?θ)TH(θ?θ):其中 H H H跟Hessian有關,是一個矩陣,第三項會再補足與真正的L(θ)之間的差距, H H H是L的二次微分構成的矩陣,它第 i i i個row,第 j j j個column的值 H i j H_{ij} Hij?,是把 θ θ θ的第 i i i個component,對 L L L作微分,再把 θ θ θ的第 j j j個component,對 L L L作微分,也就是做兩次微分以后的結果

總的來說, L ( θ ) L(\theta) L(θ)跟兩個東西有關,跟gradient有關,跟hessian有關,gradient就是一次微分,hessian是內含二次微分的專案

如果我們今天走到了一個critical point,意味著上式中 g = 0 g=0 g=0,只剩下 L ( θ ′ ) L(\theta') L(θ)和紅色的這一項:

于是可以通過紅色這一項判斷 θ ′ \theta' θ附近的error surface長什么樣,從而判斷現在是在local minima、local max還是saddle point,

通過Hession矩陣判斷 θ ′ \theta' θ附近的error surface

( θ ? θ ′ ) (\theta-\theta') (θ?θ)用向量 v v v來表示,根據 v T H v v^THv vTHv的值來判斷:

線性代數中,如果所有的 v v v帶入 v T H v v^THv vTHv的值都大於零,那 H H H叫做positive definite 正定矩陣,所以我們不需要通過窮舉所有的點來判斷 v T H v v^THv vTHv是大于零還是小于零,而是直接利用 H H H是否正定來判斷,而判斷 H H H是否是正定矩陣可以通過求解 H H H的特征值來判斷,如果所有的eigen value特征值都是正的,那么 H H H就是positive definite 正定矩陣

所以判斷條件就轉化為:

如何逃離saddle point?

** H H H不只可以幫助我們判斷,現在是不是在一個saddle point,還指出了引數可以update的方向,**注意這個時候 g = 0 g=0 g=0

根據 λ x = A x \lambda x=Ax λx=Ax,可以對式子進行轉化:

于是如果 λ < 0 λ<0 λ<0(eigen value<0),那 λ ‖ u ‖ 2 < 0 λ‖u‖2<0 λu2<0,所以eigen value是負的,那這一整項就會是負的,也就是 u T H u u^THu uTHu是負的,也就是紅色整項是負的,于是 L ( θ ) < L ( θ ′ ) L(\theta)<L(\theta') L(θ)<L(θ),也就是說令 θ ? θ ′ = μ \theta-\theta'=\mu θ?θ=μ θ ′ θ' θ的位置加上 μ \mu μ,沿 μ \mu μ的方向做update得到 θ θ θ,就可以讓loss變小

這個方法也有一點問題: H H H的運算量非常非常的大,還需要算其特征值和特征向量,運算量驚人,實際操作中還有其他方法可以逃離saddle point,在最糟糕的情況下還有這種方法可以逃離,

Saddle Point v.s. Local Minima

**事實上Local Minima沒有那么常見,**一個可能的解釋是:在低維的空間中,低維的一個引數的error surface,好像到處都是local minima,但是在高維空間來看,它可能只是一個saddle point,

如下圖所示,幾乎找不到完全所有eigen value都是正的critical point,下圖這個例子種,minimum ratio代表正的eigen value的數目占總數的比例,最大也在0.5~0.6,代表只有一半的eigen value是正的,還有一半的eigen value是負的,

在這個圖上,越往右代表critical point越像local minima,但是它們都沒有真的,變成local minima

batch/mini-batch和動量Momentum

batch/mini-batch

Optimization with Batch

每次在 Update 引數的時候,拿一個batch出來,算個 Loss,算個 Gradient,Update 引數,然后再拿另外個batch,再算個 Loss,算gradient,更新引數,以此類推,

mini-batch就是不把所有訓練資料拿出來一起算loss,而是分小塊,

所有的 Batch 訓練過一遍,叫做一個 Epoch,

在生成batch的時候長春會做shuffle,

Shuffle 有很多不同的做法,常見的一個做法是在每一個 Epoch 開始之前,會分一次 Batch,每一個 Epoch 的 Batch 都不一樣

為什么要batch

直接上對比圖:

之前提到,更大的batch在看完更多的example后才會更新一次引數,但更新方向可能比小batch更準確(powerful,而小batch可能更noisy)如果都是串行的話,看上去更大的batch的引數更新速度更慢,

但實際上,在有并行計算條件下,比較大的 Batch Size算 Loss再進而算 Gradient所需要的時間,不一定比小的 Batch Size 要花的時間長而更小的batch一個epoch的時間更長,(一個用于MINIST資料集上的實驗如下圖,)

所以看上去big batch的時間劣勢消失了,那是不是big batch更好呢?

答案是否定的,神奇的地方是 Noisy 的 Gradient,反而可以幫助 Training

同一個model,batchsize過大效果反而更差?

用過大的batch size optimizer可能會有問題,

拿不同的 Batch 來訓練模型,可能會得到下圖的結果:

Batch Size 越大,Validation Acc 上的結果越差,但這個不是 Overfitting,因為如果 Training也是 Batch Size 越大,Training 的結果越差,

現在用的是同一個模型,它們可以表示的 Function 就是一模一樣的,所以這個不是 Model Bias 的問題,這個是 Optimization 的問題,代表當用大的 Batch Size 的時候, Optimization 可能會有問題,小的 Batch Size,Optimization 的結果反而是比較好的

為什么小的 Batch Size在 Training Set 上會得到比較好的結果?

一個可能的解釋是這樣子的,如下圖所示:

  • 假設是 Full Batch,沿著一個 Loss Function 來 Update 引數,走到一個 Local Minima/saddle Point,顯然就停下來了,Gradient 是零,可能就沒辦法更新引數了;
  • 假如是 Small Batch 的話,因為**每次挑一個 Batch 出來算它的 Loss,所以每一次 Update 你的引數的時候,用的 Loss Function 都是略有差異的,**選到第一個 Batch 的時候,,是用 L1 來算 Gradient;選到第二個 Batch 的時候,用 L2 來算Gradient,**假設用 L1 算 Gradient 的時候,發現 Gradient 是零,卡住了,但 L2 它的 Function 和 L1 又不一樣,L2 就不一定會卡住,**所以在某一個batch卡住了沒關系,還是有辦法 Training Model,還是有辦法讓 Loss 變小,所以mini-batch這種 Noisy 的 Update 的方式,結果反而對 Training是有幫助的,

image-20210315155345489

另外一個神奇的事:小的batch在testing也有幫助

論文On Large-Batch Training For Deep Learning,Generalization Gap And Sharp Minima中,就做了這樣一個實驗:努力的調big- Batch 的 Learning Rate,然后想辦法把big-Batch的訓練模型,跟small-Batch 訓練得得一樣好,結果發現small-Batch在 Testing 的時候是比較好的

注意這個時候big-batch在訓練集中表現和small-batch性能相似,但在測驗集表現更差說明的問題才是over fitting,

為什么會這樣呢?文章也給了一個解釋:

假設這個實線是 Training Loss,那在這個 Training Loss 上面,可能有很多個 Local Minima,這些 Local Minima 它們的 Loss 都很低,它們 Loss 可能都趨近于 0,但是 Local Minima還是有好 Minima 跟壞 Minima 之分,

  • 好的Local Minima:在一個平原上(左邊的);
  • 壞的Local Minima:在一個峽谷里面(右邊的),

為什么這么判定呢?

假設現在 Training 跟 Testing 中間,有一個 Mismatch,Training 的 Loss 跟 Testing 的 Loss,它們的Function 不一樣,導致這種mismatch的原因可能有兩個:

  1. 可能是本來 Training 跟 Testing 的 Distribution就不一樣;
  2. 那也有可能是因為 Training 跟 Testing都是從 Sample 的 Data 算出來的,也許 Training 跟 Testing Sample(采樣)到的 Data 不一樣,那它們算出來的 Loss,自然有一點差距,

那我們就假設這個 Training 跟 Testing的差距就是把 Training 的 Loss,這個 Function 往右平移一點(上圖虛線為testing loss),這時候會發現,對左邊這個在一個盆地的 Minima 來說,它的在 Training 跟 Testing 上面的結果,不會差太多;但是對右邊這個在峽谷的 Minima 來說,就差別很大,

它在這個 Training Set 上算出來的 Loss 很低,但是因為 Training 跟 Testing 之間的mismatch,所以 Testing 的時候,這個 Error Surface 變化后,算出來的 Loss 就變得很大,所以猜想這個大的 Batch Size,會讓模型傾向于走到峽谷里面,而小的 Batch Size,傾向于讓模型走到盆地裡面

  • 因為小的 Batch有很多的 Loss,每次 Update 的方向都不太一樣,所以如果這個峽谷非常地窄,可能一個不小心就跳出去了,因為每次 Update 的方向都不太一樣,它的 Update 的方向也就隨機性,所以一個很小的峽谷,沒有辦法困住小的 Batch,如果峽谷很小,它可能動一下就跳出去,之后如果有一個非常寬的盆地,它才會停下來;
  • 而對于大的 Batch Size,就是順著規定 Update,它就很有可能,走到一個比較小的峽谷里面,

但這只是一個解釋,實際上這個還是一個尚待研究的問題

總結batch/mini-batch

總的來說,大的 Batch 跟小的 Batch,它們各自有它們擅長的地方,**Batch Size,變成另外一個需要去調整的 Hyperparameter,**一些論文也討論了如何兼顧魚和熊掌,需要用一些特殊的方法來解決大的Batch Size 可能會帶來的劣勢:

Momentum

Momentum是另外一個有可能可以對抗 Saddle Point,或 Local Minima 的技術,

傳統的梯度下降

Gradient Descent + Momentum

加上 Momentum 以后,每一次在移動引數的時候,不是只往 Gradient 的反方向來移動引數,是 Gradient 的反方向+前一步移動的方向去調整去到引數

具體來看步驟如下:把藍色的虛線加紅色的虛線,前一步指示的方向跟 Gradient 指示的方向,當做引數下一步要移動的方向,

下面有一個例子來展示:

在第三步,Gradient 變得很小,但是沒關系,如果有 Momentum 的話,根據上一步的Momentum 可以繼續往前走;

甚至走到第四步時,Gradient 表示應該要往左走了,但是如果前一步的影響力,比 Gradient 要大的話,還是有可能繼續往右走,甚至翻過一個小丘,可能可以走到更好 Local Minima,

自動調整學習率Adaptive Learning Rate

critical point不一定是訓練程序中最大的阻礙,思考一個問題:

loss不再下降的時候,gradient真的很小嗎?

并不是的,如下圖所示雖然loss不再下降,但是這個gradient的大小并沒有真的變得很小,它可能在error surface山谷的兩個谷壁間,不斷的來回的震蕩

所以有的時候訓練不下去的原因不是critical point,而是其他的原因,

舉個例子:

在下面這個error surface中,縱軸的引數變化很小就會導致結果變化很大,而橫軸引數變化很大結果變化很小,

如果兩個引數使用同一個學習率,當學習率調的過大,在縱軸方向可能直接震蕩:

如果學習率調的很小,在縱軸可以逐漸找到好的引數,但是在橫軸更新時,由于學習率過小,更新速度太慢,也很難找到最優解,

所以可以考慮為不同的引數和不同的iteration設定不同的learning rate

上面的案例展示了學習率選擇的兩個大原則:

  1. 如果在某一個方向上,gradient的值很小,非常的平坦,那learning rate調大一點;
  2. 如果在某一個方向上非常的陡峭,坡度很大,那其實learning rate可以設得小一點

learning rate自動調整策略:為不同的引數和不同的iteration設定不同的learning rate

以一個引數 θ i \theta_i θi?為例:

原始策略:
θ i t + 1 ← θ i t ? η g i t \theta_i^{t+1}\leftarrow \theta_i^{t}-\eta g_i^t θit+1?θit??ηgit?
不同的引數和不同的iteration自動調整策略:
θ i t + 1 ← θ i t ? η σ t t g i t \theta_i^{t+1}\leftarrow \theta_i^{t}-\frac{\eta}{\sigma_t^t} g_i^t θit+1?θit??σtt?η?git?
上式中 σ i t \sigma_i^t σit?下標 i i i代表它是depend on i i i的,也就是不同引數有不同的 σ \sigma σ,而上標 t t t表示它是iteration dependent的,不同的iteration會有不同的σ,因此 η σ t t \frac{\eta}{\sigma_t^t} σtt?η?變成parameter dependent的learning rate,

那么如何計算 σ \sigma σ呢?

常見的計算 σ σ σ可以用gradient的Root Mean Square,這種計算方法也被用于Adagrad這一優化器中,

用于Adagrad中的Root mean square

Root mean square計算 σ σ σ是通過求歷史梯度的均方根得到的,計算步驟如下圖所示:

image-20210319150808494

為什么Root mean square可以做到坡度比較大的時候,learning rate就減小,坡度比較小的時候,learning rate就放大呢?

看看下面這個例子:

現在我們有兩個引數: θ ? 1 θ?1 θ?1 θ ? 2 θ?2 θ?2 θ ? 1 θ?1 θ?1坡度小 θ ? 2 θ?2 θ?2坡度大,

θ ? 1 θ?1 θ?1因為坡度小,所以在 θ ? 1 θ?1 θ?1這個引數上面,算出來的gradient值都比較小,那么 σ σ σ也比較小, η σ \frac{\eta}{\sigma} ση?就比較大,

所以有了 σ σ σ這一項以后,就可以隨iteration gradient的不同,每一個引數的gradient的不同,來自動的調整learning rate的大小,

但是,就算是同一個引數,它需要的learning rate,也可能會隨時間而改變,于是還有進階版的策略自適應learning rate,

RMSProp

同一個引數同一個方向也希望可以自適應調整,比如下面這個新月形的error surface,

在水平方向(同一引數同一方向)在綠色箭頭這個地方坡度比較陡峭,需要比較小的learning rate,走到了中間這一段,到了紅色箭頭坡度又變得平滑,需要比較大的learning rate,

RMSProp和Apagrad在計算 σ \sigma σ時,第一步時一樣的,在第二步更新時,通過一個超引數 α \alpha α賦予了歷史梯度和當前梯度不一樣的權重(而Apagrad中是一樣的權重,也就是每一個gradient同樣重要),

計算程序如下圖所示:

α就像learning rate一樣是一個hyperparameter,需要自己調整

  • 如果α設很小趨近于0,就代表我覺得** g ? 1 g?1 g?1相較于之前所算出來的gradient而言,比較重要**;
  • α設很大趨近于1,那就代表現在算出來的 g ? 1 g?1 g?1比較不重要,之前算出來的gradient比較重要

舉個例子看一下RMSProp的效果:

下圖中,一開始梯度很小,學習率較大;

到第三步時,梯度變大,原來的Adagrad反應比較慢,可能還會用比較大的學習率,但如果用RMS Prop,把α設小一點,也就是讓新的gradient影響比較大,可以很快的讓σ的值變大,于是很快的讓學習率變小

還記得前面提到了momentum這個方法,RMSProp+momentum就得到了一個高級版的策略:Adam,

Adam論文鏈接

tips

這些優化器在pytorch等框架中都寫好了,其中也包括很多超引數,李宏毅老師還提到往往用默認的超引數就夠好了,自己調有時候反而會調到比較差的,煉丹玄學~

learning rate scheduling

現在讓我們回到前面提到的error surface上,加上Adagrad方法后,訓練效果如下圖右下角的子圖所示:

加了Adagrad以后,在橫軸方向learning rate會自動變大,從而能盡快接近最優解,但我們可以看到一個奇怪的現象,走到非常接近終點的位置,梯度突然爆炸了,這是為什么呢?

從Adagrad的 σ \sigma σ計算方式可以回答這個問題,計算 σ σ σ時,把過去所有看到的gradient,都拿來作平均:

  • 所以這個縱軸的方向,在初始的時候gradient很大,學習率比較小;

  • 可是繼續走了很長一段路以后,gradient算出來都很小,于是y軸的方向就開始積累很小的σ;

  • 累積到一個地步以后,學習率就變很大,于是發生爆炸;

  • 爆炸后其實也沒關系,因為爆炸后就走到gradient比較大的地方,于是σ又慢慢的變大,引數update學習率又慢慢的變小,

  • 但是累計一段時間又會爆炸,然后恢復,反復,

解決這種問題的策略是learning rate scheduling,這里介紹兩種:

  1. Learning Rate Decay(學習率衰減策略)
  2. warm up

Learning Rate Decay(學習率衰減策略)

在前面使用的Adagrad中, η \eta η被當作一個固定的值,而learning rate scheduling是指讓 η \eta η和時間有關,常見的策略為:Learning Rate Decay(學習率衰減策略),隨著訓練不斷進行,引數不斷更新, η \eta η越來越小,

于是:一開始距離終點很遠,隨著引數不斷update,距離終點越來越近,把learning rate減小,讓引數更新減速,所以前面的那個問題,加上Learning Rate Decay可以解決,

warm up

Warm Up的方法是讓learning rate,要先變大后變小,**其中變大到多大、變大速度、變小到多小、變小速度都是超引數,**如下圖所示:

但是為什么需要Warm Up,為什么Warm Up有效都是待研究的問題,但在很多文獻中,它就是work了,比如BERT、transformer等等模型中都用到了warm up這個技術,

李宏毅老師提到了一個可能的解釋:

? 當我們在用Adam RMS Prop,或Adagrad的時候,需要計算σ,它是一個統計的結果,σ告訴我們,某一個方向它到底有多陡,或者是多平滑,這個統計的結果,要看得夠多筆資料以后才比較精確,所以一開始我們的統計是不精確的,于是我們一開始不要讓引數走離初始的地方太遠,先讓它在初始的做一些探索,所以一開始learning rate比較小,是讓它探索 收集一些有關error surface的情報,先收集有關σ的統計資料,等σ統計得比較精準以后,在讓learning rate呢慢慢地增大

自動調整學習率方法總結

我們逐步將原始梯度下降方法進行優化:

  1. 加入momentum;
  2. 加入自適應iteration和引數的 σ \sigma σ
  3. 使用自適應iteration的 η \eta η

注意:momentum和 σ σ σ雖然都與過去所有的gradient有關,一個放在分母,一個放在分子,但是momentum考慮了方向,而 σ σ σ只考慮了gradient的大小,

另一個角度-鏟平error surface?

之前考慮的常見都是假設error surface非常崎嶇情況下怎么找到比較好的引數,但其實我們可以從error surface出發,考慮如何把error surface變成一個比較平坦的,好訓練的error surface,如下圖所示:

通過修改損失函式和batch normalization可能可以做到修改error surface,讓模型更好訓練,

損失函式loss function

在講分類模型的時候,李宏毅老師解釋了為什么cross entropy更常用在分類上 ,并且用一個例子展示了loss function對error surface的影響,

我們這里直接看這個例子:

現在我們用下面這個模型做一個3個Class的分類任務,下面兩個坐標系中的圖是當loss function分別設定為Mean Square Error和Cross-entropy的時候,算出來的Error surface( y ? 、 y ? y?、y? y?y?的變化對loss的影響),在紅色部分(左上角)loss很大,藍紫色部分(右下角)loss比較小,所以我們希望在訓練后,引數走到右下角的地方,

image-20210320205913652

假設我們開始的地方,都是左上角

  • 如果loss function 是Cross-Entropy,那么error surface的左上角這個地方是有斜率的,所以可以通過gradient descent一路往右下的地方走;
  • 如果loss function 是Mean square error的話,Mean square error在左上角這種Loss很大的地方,是非常平坦的,也就是說它的gradient是非常小趨近于0的,如果初始的時候在這個地方,離目標非常遠,它gradient又很小,就會沒有辦法用gradient descent順利的走到右下角的地方去(當然用Adam還是有可能可以成功訓練起來的,不過訓練起步比較慢,訓練更困難),

總結loss function

由此例可以發現,Loss function的定義也可能影響error surface從而影響Training,選一個合適的loss function可以改變optimization的難度,

這里補充一個資料,對于一些常見任務應該選擇什么樣的loss function進行了總結,深度學習中常見的激活函式與損失函式的選擇與介紹

batch normalization

Batch Normalization是修改error surface,讓模型更好訓練的其中一個方法,

比如現在有兩個引數,它們對 Loss 的斜率差別非常大,在 w 1 w_1 w1?這個方向上面斜率變化很小,在 w 2 w_2 w2?這個方向上斜率變化很大,如下圖左邊所示,

之前提到用daptive 的 learning rate,比如Adam 等等比較進階的 optimization 的方法去更新引數,其實另一個角度就是**把這種很難訓練的error surface改掉,**改成下圖中右邊所示,

于是我們需要思考:斜率差很多的這種狀況,到底是哪里來的?

假設我們的模型上圖中下半部分的簡單模型:

  • 輸入的 x 1 x_1 x1?很小, w 1 w_1 w1?有小小的改變,對輸出 y y y的影響比較小,對 L L L的影響也小;
  • 如果 x 2 x_2 x2?取值很大, w 2 w_2 w2?變化很小也會造成 y y y很大的變化,于是對 L L L的影響也大;
  • 所以如果 x 1 , x 2 x_1,x_2 x1?,x2?的取值范圍差別過大(每一個 dimension 的值scale 差距很大)會導致不同方向斜率差別很大,

因此,**希望給不同的 dimension,同樣的數值范圍(轉為上圖右邊部分),將原本的error surface變成比較好訓練的error surface,**可以完成這個操作的方法統稱為feature normalization,

feature normalization

feature normalization可以讓Loss 收斂更快一點,讓梯度下降更順利一點,

下面舉一個常用的feature normalization方法:利用均值和方差進行標準化standardization,

假設 x 1 x^1 x1 x R x^R xR是所有的訓練資料的 feature vector,把所有訓練資料的 feature vector ,統統都集合起來, x 1 1 x_1^1 x11?代表 x 1 x_1 x1?的第一個 element, x 1 2 x_1^2 x12?就代表 x 2 x_2 x2?的第一個 element,以此類推,

不同樣本即不同 feature vector,同一個 dimension 里面的數值計算均值mean m i m_i mi?,并且計算第 i i i 個 dimension 的標準差standard deviation σ i \sigma_i σi?

然后用下式進行標準化standardization,然后用標準化后的 x ~ i r \tilde x_i^r x~ir?作為模型的輸入,
x ~ i r ← x i r ? m i σ i \tilde x_i^r \leftarrow \frac{x_i^r-m_i}{\sigma_i} x~ir?σi?xir??mi??
示意圖如下:

做完 normalize 以后,這個 dimension 上面的數值平均是 0, variance是 1,所以一排數值的分布就都會在 0 上下,對每一個 dimension都做一樣的 normalization,就會發現所有 feature 不同 dimension 的數值都在 0 上下,那可能就可以構造比較好的 error surface

feature normalization for deep learning

我們先用feature normalization對最原始的輸入做了處理得到 x ~ \tilde x x~,那么經過第一層引數時,我們的輸入各個維度的scale就是差不多的,但是深度學習的模型都是有很多層的,像下圖這樣**:上一層的輸出是下一層的輸入,那么經過了一層神經網路的特征(輸出 z 1 z^1 z1或經過sigmoid層的輸出 a 1 a^1 a1)各個維度可能又會有不同的scale,**

所以我們可以對 z z z或者 a a a做normalization,這里也有一個tips:

  • 一般來說,這個 normalization,要放在 activation function 之前,或之后都是可以的,在實操上,可能沒有太大的差別
  • 不過,如果選擇的是 Sigmoid作為激活函式,那可能比較推薦對 z z z 做 Feature Normalization因為Sigmoid 是一個 s 的形狀,它在 0 附近斜率比較大,所以如果對$ z$ 做 Feature Normalization,把所有的值都挪到 0 附近,算 gradient 的時候值會比較大,
  • 因為激活函式不一定是選 sigmoid,所以也不一定要對 z z z做 Feature Normalization,如果是選別的激活函式,也許對 a a a做normalization可能會有好的結果,

我們這邊假設對 z z z做feature normalization,舉個例子

和之前對 x x x做的操作類似,對 z z z也是計算均值和方差,然后進行歸一化:

這里有個地方需要特別注意:

上圖中的 μ \mu μ σ \sigma σ ,它們其實都是根據 z 1 , z 2 , z 3 z^1,z^2,z^3 z1,z2,z3算出來的,那么:

  • 如果沒有做feature normalization,因為 x ~ \tilde x x~是處理后單獨輸入的,修改 z 1 z^1 z1只會影響 z ~ 1 \tilde z^1 z~1 a 1 a^1 a1
  • 做了feature normalization后,修改 z 1 z^1 z1會影響 μ \mu μ σ \sigma σ,進而不僅影響 z ~ 1 \tilde z^1 z~1 a 1 a^1 a1,還會影響 z ~ 2 \tilde z^2 z~2 a 2 a^2 a2 z ~ 3 \tilde z^3 z~3 a 3 a^3 a3
  • 于是這三個 example,它們變得彼此關聯了,如下圖所示:

因為彼此關聯,于是整個process(包括根據feature算均值方差)就變成了network的一部分,所以現在變成一個比較大的network,如下圖所示,

  • 之前的 network,都只輸入一個 input,得到一個 output;
  • 現在有一個比較大的 network是輸入一堆 input,用這堆 input 在這個 network 里面,要算出均值和方差,然后輸出一堆 output,

自然而然地產生一個問題,是不能一次性把很大的一個訓練集全部輸入網路中訓練的,因為記憶體有限,

再自然而然地就可以考慮不輸入全部的資料,而是輸入一部分(batch),每次只考慮一個batch里的樣本,所以在實際操作中,是對一個batch做normalization,于是這個方法叫batch normalization,

normalization in each batch - batch normalization

顯然一定要有一個夠大的 batch,才算得出均值和方差,假設batch size=1,那么均值和方差就沒啥好算的,

所以Batch Normalization適用于 batch size 比較大的時候相當于我們用一個batch size的訓練資料分布估計整個資料集的資料分布,如果 batch size 比較大,也許這個 batch size 里的 data足以表示整個 corpus 的分布,這個時候就可以把對整個 corpus做 Feature Normalization改成只在一個 batch做 Feature Normalization,

進階的batch normalization

在做 Batch Normalization 的時候,往往還會對計算出來的 z ~ \tilde z z~進行下一步操作,得到最終的 z ^ \hat z z^
z ^ i = γ ⊙ z ~ i + β \hat z^i=\gamma \odot \tilde z^i+\beta z^i=γz~i+β
其中 γ \gamma γ β \beta β是 network 的引數,在訓練程序中被學習到的,如下圖所示:

image-20210427090245986

為什么要加上$\beta 和 和 \gamma$?

有一種猜測是,做 normalization 以后feature的平均就一定是 0,這可能會給 network 一些限制,也許這個限制會帶來什麼負面的影響,所以在訓練的時候,將$\beta 和 和 \gamma$作為訓練引數,重新調整其分布,讓它的 hidden layer 的 output平均不是 0 ,

如果是這樣,那可能又會問:上一步做Batch Normalization 就是要讓每一個不同的 dimension的 range 都是一樣的,現在如果做這一步,不是又讓 dimension 的分布不一樣了嗎?

答案是:確實有可能,以我們**在初始的時候,將$\beta 內 的 元 素 都 設 置 為 1 , 內的元素都設定為 1, 1\gamma 內 的 元 素 都 設 置 為 0 , ? ? 于 是 n e t w o r k 在 一 開 始 訓 練 的 時 候 , 每 一 個 d i m e n s i o n 的 分 布 , 是 比 較 接 近 的 , 也 許 訓 練 到 后 來 , 已 經 找 到 一 個 比 較 好 的 e r r o r s u r f a c e , 走 到 一 個 比 較 好 的 地 方 以 后 , 再 慢 慢 調 整 內的元素都設定為0,**于是 network 在一開始訓練的時候,每一個 dimension 的分布,是比較接近的,也許訓練到后來,已經找到一個比較好的 error surface,走到一個比較好的地方以后,再慢慢調整 0??network,dimension,errorsurface調\beta 和 和 \gamma$,

batch normalization for testing/inference

之前說的都是training的時候要做什么,在testing(inference)的時候,想用batch normalization會有什么問題呢?

batch normalization需要一個batch的資料計算 μ \mu μ σ \sigma σ,在testing的時候,首先遇到的問題是,可能輸入不夠一個batch size,因為在工程上不可能等資料攢到一個batch size才開始計算輸出,

也就是可能根本就不是一個batch的輸入,應該怎么獲得 μ \mu μ γ \gamma γ呢?

在實際操作中,如果是PyTorch 的話,Batch Normalization 在 testing 的時候,其使用的 μ \mu μ γ \gamma γ是通過:如果training的時候有做 Batch Normalization 的話,在 training 的時候,每一個 batch 計算出來的 μ \mu μ σ \sigma σ 都計算moving average,然后得到平均值( μ ˉ \bar \mu μˉ? σ ˉ \bar \sigma σˉ),將這兩個值作為testing的 μ \mu μ σ \sigma σ,如下圖所示,

moving average的計算程序是:每一次取一個 batch 出來的時候,就會算一個 μ 1 \mu^1 μ1,取第二個 batch 出來的時候算 μ 2 \mu^2 μ2 ,一直到取第 t 個 batch 出來的時候算 μ t \mu^t μt,利用 μ 1 . . . μ t ? 1 \mu^1...\mu^{t-1} μ1...μt?1算一個平均值得到 μ ˉ \bar \mu μˉ?然后結合一個超引數 p p p更新 μ ˉ \bar\mu μˉ?

看看加了batch normalization的訓練效果:橫軸是訓練程序,縱軸是在驗證集上的精度,

  1. 訓練速度變快,收斂速度變快;
  2. 更好訓練(sigmoid比較難訓練,但是加入batch normalization后成功訓練起來了);
  3. 如果做 Batch Normalization 的話,error surface 會比較平滑 比較容易訓練,所以可以把 learning rate 設大一點,(但是這里有個問題是:learning rate 設 30 倍的時候比 5 倍差,作者也沒有解釋為什么),

internal covariate shift

在原始的 Batch Normalization那篇 paper 作者提出來一個概念,叫做 internal covariate shift,(友情先提醒這個猜測已經被推翻了)

其中covariate shift是本身存在的概念:訓練集和預測集樣本分布不一致的問題就叫做“covariate shift”現象

internal covariate shift指的是:當我們在計算 B,update 到 B′ 的 gradient 的時候,這個時候前一層的引數是 A (或者說是前一層的 output 是a),那當前一層從 A 變成 A′ 的時候,它的 output 就從 a 變成 a′ ,但是我們計算這個 gradient 的時候,我們是根據這個 a 算出來的,所以這個 update 的方向,也許它適合用在 a 上,但不適合用在 a′ 上面

所以如果每次都有做 normalization,可能就會讓 a 跟 a′ 的分布比較接近,也許這樣就會對訓練有幫助,

如下圖所示:

但是!

有一篇 paperHow Does Batch Normalization,Help Optimization就推翻了internal covariate shift 的這一個觀點

作者從各種各樣的角度說明internal covariate shift它不一定是 training network 的時候的一個問題,且Batch Normalization會比較好不一定是因為解決了 internal covariate shift問題

作者通過比較訓練時a 分布的變化發現:

  1. 不管有沒有做 Batch Normalization,它的變化都不大
  2. 就算是變化很大,對 training 也沒有太大的傷害;
  3. 不管你是根據 a 算出來的 gradient,還是根據 a′ 算出來的 gradient,方向都差不多,

這篇 How Does Batch Normalization,Help Optimization 論文中從實驗上、也從理論上至少支持了 Batch Normalization,可以改變 error surface,讓 error surface 比較不崎嶇這個觀點,并且說:如果我們要讓 network的error surface 變得比較不崎嶇,不一定要做 Batch Normalization,還有很多其他的方法(作者也試了一些其他的方法,見原文實驗),batch normalization只是一個serendipitous(意料之外的發現),恰好work了而已,

其他normalization的方法

主要包括以下幾種方法:BatchNorm(2015年)、LayerNorm(2016年)、InstanceNorm(2016年)、GroupNorm(2018年),這幾個方法在之前總結Transformer時簡單總結過了,可以參考:Transformer相關——(6)Normalization方式

img

normalization方法和paper原文如下:

Batch Renormalization

Layer Normalization

Instance Normalization

Group Normalization

Weight Normalization

Spectrum Normalization

參考資料

[李宏毅深度學習2021春季筆記](https://unclestrong.github.io/DeepLearning_LHY21_Notes/Notes_html/05_Batch and Momentum.html)

(強推)李宏毅2021春機器學習課程

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302424.html

標籤:AI

上一篇:VulnHub-Gigachad

下一篇:TensorFlow 從入門到精通(-1)—— 源代碼

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more