天天看點

模型訓練與測試 -----BN層()

Feature normalization Feature scaliing

首先是為什麼要歸一化或者标準化,從下面可以看出來如果我們的輸入的樣本或者特征值,他們之間的差異比較大,那麼其實我們的梯度下降圖是畸形的。比如下面因為x1比x2小太多,是以梯度沒有x2 那麼浮誇。但是如果他們是一樣的話,那麼他們就有右邊這樣的東西了。是以為了好的梯度下降,我們需要針對不同的參數用不同的learning rate。這一個是已經有實作的就是我們自适應優化器的出現,但是其實優化器對他們的影響還是有限的,但是如果我們在處理前,将圖變成右邊那樣呢?那是不是其實我們就可以更好的做梯度下降了,是以到這裡我們可以看到了BN層或者歸一化的作用力。

模型訓練與測試 -----BN層()
模型訓練與測試 -----BN層()

其他原因呢?

之是以就會研究BN層是因為,我在用pytorch寫模型的時候,會發現pytorch給了兩個東西一個叫做model.train()

一個叫做model.eval().這兩者的差別在于如果你要訓練模型那麼你要用第一句,如果你是測試模型那麼你要用第二句。而兩者的差別在于他們對BN層和dropout層的處理是不一樣的。是以我們發現訓練和測試的過程,我們看待BN層也是不一樣的。也因為好奇,是以我們去深入看看BN層在訓練的過程的作用。要不也不會叫做batchnormalization了,因為和batch有關啊

圖中 的幾個點:

第一個是因為模型在訓練是以每次的output的數值都是有變化的, 而BN層的辦法就是讓他們歸一化。減少對下一層的影響。

第二個就是internal covariate shift的想象在于,前面的變化會導緻後面的變化,有時候變化不統一出現的結果。大家都動結果容易壞掉。

模型訓練與測試 -----BN層()

左下面是GPU實際上的batch操作。

模型訓練與測試 -----BN層()

下面是BN層的計算:

  1. 關于均值和方差我們是對每個訓練的batch來求的,這裡意味着如果我們訓練的過程中batch太小?你算毛方差和均值,是以batch不能太小。是以我們測試的時候,我們一般都是單張圖的話,我們的BN層需要固定住,這也是為什麼有了上面兩種模式了。但是如果你是多張同時的話估計沒啥問題。
    模型訓練與測試 -----BN層()
    接下來呢?有了方差和均值,肯定要歸一化啦。下面就是進行歸一化了,這樣一看感覺BN層好像不需要進行訓練吧?不過就是一個歸一化的操作?但實際上BN層也是有參數需要訓練的。而實際上還有另外兩個是用來訓練的參數,這個參數可以讓我們的BN層不局限于目前的batch也會和之前的有些關系。
模型訓練與測試 -----BN層()
模型訓練與測試 -----BN層()

上面的後面兩個就是我們訓練的參數,其實這兩個有時候會讓BN層失效,但是這就符合我們模型本身,讓自由度更加高。但是如何做反向傳播呢?下面是公式的推導:

https://zhuanlan.zhihu.com/p/26138673

https://blog.csdn.net/kevin_hee/article/details/80783698

通過上面就可以知道推導的過程。知道BN層的反向傳播,其實也是更加有利于我們知道深度學習反向傳播的本質,就是不斷的求梯度往下走。然後到達一個終點的路有很多,那麼我們也要注意路上的反向傳播。這裡說下大疆的筆試題目,有涉及到這一部分,很多面試題目都有要求BN層的反向傳播,是以建議非常熟悉這一部分的推導

然後就是測試的時候,如何算均值和方差呢?因為我們大部分測試的時候都是一張圖的,這也是我們pytorch為什麼在測試和訓練會給出兩個不同的模式,因為我們的BN層的處理是不一樣的,訓練的時候我們用batch的均值和方差。但是測試的時候呢,我們做下面說的操作。

模型訓練與測試 -----BN層()

BN層的好處:

第1個可以用大的learning rate,因為我們BN了啦,是以大家的梯度都很漂亮呀

第2個是減少covariate shift,

第3個是可以減少梯度消失的問題,特别是用了sigmoid這樣的函數在womendemoxing

第4個減少因為初始化模型參數帶來的影響。參數的變化,那麼輸出也發生變化,那麼歸一化呢?一起大一起小,什麼事情都沒發生。

第5個可以減少噪聲帶來的影響呀,據說可以避免overfitting

模型訓練與測試 -----BN層()

雲從筆試題有問到:BN層與EWA的關系

模型訓練與測試 -----BN層()

pytorch中的BN層:看到了EWA了,個人了解之是以用Momentum是在測試時候需要用到均值和方差,這時候通過EWA可以記錄過去最好的,這時候就可以用上了,這也就是雲從科技的筆試題問到了BN層在訓練和測試的時候會做什麼,分别是計算目前的,和累加出最好的,前者就是統計計算,後者就是EWA也就是滑動平均 ,model.eval() 和model.train() 在預訓練中是非常重要的。

The running mean and variances are computed using an exponential moving average with smoothing factor 0.1. i.e running_mean[t] = running_mean[t-1]*0.9 + batch_mean[t]*0.1

track_running_stats – a boolean value that when set to True, this module tracks the running mean and variance, and when set to False, this module does not track such statistics and always uses batch statistics in both training and eval modes. Default: True

————————————————

trainning=True, track_running_stats=True。這個是期望中的訓練階段的設定,此時BN将會跟蹤整個訓練過程中batch的統計特性。

trainning=True, track_running_stats=False。此時BN隻會計算目前輸入的訓練batch的統計特性,可能沒法很好地描述全局的資料統計特性。

trainning=False, track_running_stats=True。這個是期望中的測試階段的設定,此時BN會用之前訓練好的模型中的(假設已經儲存下了)running_mean和running_var并且不會對其進行更新。一般來說,隻需要設定model.eval()其中model中含有BN層,即可實作這個功能。[6,8]

模型訓練與測試 -----BN層()

BN層的作用

1.防止過拟合,可以用來替代drop out層

2.可以防止梯度彌散

3.其能夠讓優化空間(optimization landscape)變的平滑

模型訓練與測試 -----BN層()

N可以提高訓練時模型對于不同超參(學習率、初始化)的魯棒性進而避免了過拟合、可以讓大部分的激活函數能夠遠離其飽和區域防止梯度爆炸或彌散

對于沒有BN的神經網絡,其loss函數是不僅非凸,并且還有很多flat regions、sharp minimal。這就使得那些基于梯度的優化方法變得不穩定,因為很容易出現過大或者過小的梯度值。觀察上圖,可以發現,在使用了BN後,loss的變化變得更加穩定,不會出現過大的跳動;同樣,梯度也變得更加平滑。

參考原文連結:

https://blog.csdn.net/LoseInVain/article/details/86476010

https://blog.csdn.net/xiaojiajia007/article/details/90115174

https://zhuanlan.zhihu.com/p/68863894

https://zhuanlan.zhihu.com/p/33173246

繼續閱讀