神經網絡中還有一些激活函數,池化函數,正則化和歸一化函數等。須要詳細看看,啃一啃吧。。html
1. 激活函數算法
1.1 激活函數做用網絡
在生物的神經傳導中,神經元接受多個神經的輸入電位,當電位超過必定值時,該神經元激活,輸出一個變換後的神經電位值。而在神經網絡的設計中引入了這一律念,來加強神經網絡的非線性能力,更好的模擬天然界。因此激活函數的主要目的是爲了引入非線性能力,即輸出不是輸入的線性組合。app
假設下圖中的隱藏層使用的爲線性激活函數(恆等激活函數:a=g(z)),能夠看出,當激活函數爲線性激活函數時,輸出不過是輸入特徵的線性組合(不管多少層),而不使用神經網絡也能夠構建這樣的線性組合。而當激活函數爲非線性激活函數時,經過神經網絡的不斷加深,能夠構建出各類有趣的函數。dom
1.2 激活函數發展機器學習
激活函數的發展過程:Sigmoid -> Tanh -> ReLU -> Leaky ReLU -> Maxout (目前大部分backbone中都採用ReLU或Leaky ReLU)。還有一個特殊的激活函數Softmax,但通常只用在網絡的最後一層,進行最後的分類和歸一化。借一張圖總結下:ide
sigmoid函數:能將輸入值映射到0-1範圍內,目前不多用做隱藏層的激活函數,用在二分類中預測最後層輸出機率值。函數特色以下:函數
存在問題:性能
tanh雙曲正切函數:將輸入值映射到-1—1範圍內,目前不多用作隱藏層激活函數。學習
Tanh解決了Sigmoid的輸出是否是零中心的問題,但仍然存在飽和問題。
(爲了防止飽和,如今主流的作法會在激活函數前多作一步batch normalization,儘量保證每一層網絡的輸入具備均值較小的、零中心的分佈。)
ReLU函數(Rectified Linear unit):相較於sigmoid和tanh函數,計算比較簡單,收斂速度較快,是目前主要的激活函數。
對比sigmoid類函數主要變化是:1)單側抑制;2)相對寬闊的興奮邊界;3)稀疏激活性。
存在問題:ReLU單元比較脆弱而且可能「死掉」,並且是不可逆的,所以致使了數據多樣化的丟失。經過合理設置學習率,會下降神經元「死掉」的機率。
Leaky ReLU:相比於ReLU,使負軸信息不會所有丟失,解決了ReLU神經元「死掉」的問題。
PReLU(Parametric ReLU): Leaky ReLU函數中的a,在訓練過程當中固定不變,常取值爲0.01,而PReLU函數的a是一個學習參數,會隨着梯度變化而更新。
ELUs函數(Exponential Linear Units):負半軸爲指數函數,使x=0時的導數變化更加平滑
softmax: 用於多分類網絡的輸出,預測每一類的機率值,目的是讓大的更大。
參考:https://www.jianshu.com/p/0cf1aff51117
https://www.cnblogs.com/lliuye/p/9486500.html
https://zhuanlan.zhihu.com/p/32610035
2. Batch Normalization(批量歸一化)
論文:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
2.1 背景
神經網絡越深時,出現了兩個問題,一是網絡十分難訓練,二是梯度消失。
而容易訓練的數據,具備以下特徵:獨立同分布(Independent Identical Distribution); 不存在內部協方差偏移現象(Internal Covaraiant Shift)。
所以人們推測:在進行網絡訓練時,參數的變化致使每一層的輸入分佈會發生改變,進而上層的網絡須要不停地去適應這些分佈變化,使得咱們的模型訓練變得困難,而且這種微弱變化隨着網絡層數的加深而被放大(相似蝴蝶效應),這種現象便被稱爲Internal Covaraiant Shift。
Batch Normalization的原論文做者給了Internal Covariate Shift一個較規範的定義:在深層網絡訓練的過程當中,因爲網絡中參數變化而引發內部結點數據分佈發生變化的這一過程被稱做Internal Covariate Shift。這句話該怎麼理解呢?,咱們定義每一層的線性變換爲 ,其中
表明層數;非線性變換爲
,其中
爲第
層的激活函數。隨着梯度降低的進行,每一層的參數
與
都會被更新,那麼
的分佈也就發生了改變,進而
也一樣出現分佈的改變。而
做爲第
層的輸入,意味着
層就須要去不停適應這種數據分佈的變化,這一過程就被叫作Internal Covariate Shift。
總結Internal Covariate Shift帶來的問題有兩個:
(1)上層網絡須要不停調整來適應輸入數據分佈的變化,致使網絡學習速度的下降
(2)網絡的訓練過程容易陷入梯度飽和區,減緩網絡收斂速度
(如採用飽和激活函數sigmoid時,數據分佈落在了|x|>4.6的梯度飽和區域,即梯度爲0)
2.2 解決思路
ICS(Internal Covariate Shift)產生的緣由是因爲參數更新帶來的網絡中每一層輸入值分佈的改變,而且隨着網絡層數的加深而變得更加嚴重,所以咱們能夠經過固定每一層網絡輸入值的分佈來對減緩ICS問題。
(1)白化whitening: 主要是PCA白化與ZCA白化
PCA白化保證了全部特徵分佈均值爲0,方差爲1;而ZCA白化則保證了全部特徵分佈均值爲0,方差相同。
白化是對輸入數據分佈進行變換,進而達到如下兩個目的:使得輸入特徵分佈具備相同的均值與方差;去除特徵之間的相關性。
(2)Batch Normalization:Batch Normalization是對白化的簡化版,從而減小計算量和易於實現。這是由於白化存在兩個問題:
白化過程計算成本過高,而且在每一輪訓練中的每一層咱們都須要作如此高成本計算的白化操做
白化過程因爲改變了網絡每一層的分佈,於是改變了網絡層中自己數據的表達能力。底層網絡學習到的參數信息會被白化操做丟失掉。
Batch Normalization實現算法:
(1) 白化計算量大,因此簡化爲對每一個特徵維度進行Normalization,讓每一個特徵均值爲0, 方差爲1。 同時只是對每個Mini-Batch進行Normalization
(2) 白化削弱了網絡中每一層輸入數據表達能力,因此Normalization後再加一個線性變換,儘量恢復數據的表達能力。
論文中的算法公式以下:(注意求均值時是一個mini-batch上,同一個維度特徵中數據的均值)
用pytorch使用了下BN方法, 並本身實現BN計算過程,代碼以下:
#coding:utf-8 import torch import torch.nn as nn m = nn.BatchNorm2d(num_features=3, momentum=1) #默認的momentum=0.1,不設爲1時,計算結果會和本身計算的不同 input = torch.randn(4,3,4,4) #能夠理解爲batch爲4, 3個channel, feature map尺寸爲4*4 output = m(input) print(output) print(m.running_mean) #3個channnel的mean print(m.running_var) #3個channnel的var print(list(m.parameters())) #3個channel依次採用的γ 、β #本身計算BN weights = list(m.parameters()) output2 = torch.zeros(input.size()) me, va = [], [] for i in range(3): m = input[:, i, :, :].mean() #m1 = input[:, 0, :, :].sum()/(4*4*4), 四個batch,每一個batch的feature map尺寸爲4*4 v = input[:, i, :, :].var() me.append(m) va.append(v) output2[:, i, :, :] = ((input[:, i, :, :] - m)/v.sqrt()) * weights[0][i].item() + weights[1][i].item() print(output2) #和output相差0.001左右 print(me) print(va)
2.3 BN的做用
(1)BN使得網絡中每層輸入數據的分佈相對穩定,加速模型學習速度
(2)BN使得模型對網絡中的參數不那麼敏感,簡化調參過程,使得網絡學習更加穩定
(3)BN容許網絡使用飽和性激活函數(例如sigmoid,tanh等),緩解梯度消失問題
(4)BN具備必定的正則化效果
在Batch Normalization中,因爲咱們使用mini-batch的均值與方差做爲對總體訓練樣本均值與方差的估計,儘管每個batch中的數據都是從整體樣本中抽樣獲得,但不一樣mini-batch的均值與方差會有所不一樣,這就爲網絡的學習過程當中增長了隨機噪音,與Dropout經過關閉神經元給網絡訓練帶來噪音相似,在必定程度上對模型起到了正則化的效果。另外,原做者經過也證實了網絡加入BN後,能夠丟棄Dropout,模型也一樣具備很好的泛化效果。
參考:https://zhuanlan.zhihu.com/p/34879333
https://zhuanlan.zhihu.com/p/24810318
3. Dropout
論文:Improving neural networks by preventing co-adaptation of feature detectors
3.1 背景
在進行神經網絡的訓練時,常常會出現過擬合的現象,特別是模型的參數太多,而訓練樣本又太少。過擬合現象表現爲:訓練集上損失函數較小,準確率高,測試集上損失函數大,準確率較低。而Dropout策略能在必定程度上緩解過擬合。
dropout策略:前向傳播的時候,讓神經元的激活值以必定的機率p中止工做,這樣部分特徵不會傳遞下去,可使模型泛化性更強,由於它不會太依賴某些局部的特徵。以下圖所示:
3.2 dropout算法實現
dropout算法的具體實現有兩種,目前多用第二種,且機率常設置爲0.5
(1)訓練階段以機率p捨棄神經元輸出值,測試階段神經元輸出值乘以機率1-p。numpy實現代碼以下:
#coding:utf-8 import numpy as np (1)訓練階段以機率p捨棄神經元輸出值,測試階段神經元輸出值乘以機率1-p #train def dropout_train_step(x, p): zeros = np.zeros_like(x) x = np.max((zeros, input),axis=3) #ReLU mask = np.random.rand(*(x.shape)) < p #randn產生0-1的隨機分佈,其中值小於機率值p的爲0 return x*mask #dropout,值小於機率值p的會被捨棄掉 #test def dropout_test_step(x, p): zeros = np.zeros_like(x) x = np.max((zeros, input),axis=3) #ReLU return x*(1-p) #直接乘以機率1-p, 由於每一個值保留的機率值爲1-p """ 因爲不肯定訓練階段捨棄的是那些神經元的值,測試階段採起求指望的方式,推理以下: 假設x=[x0, x1], p=0.3; 在訓練階段的mask會出現四種狀況:[0, 0], [0, 1], [1, 1], [1, 0], 每種狀況的輸出以下: mask=[0, 0]時, 機率爲p1 = p*p=0.09, 結果爲r1=[x0, x1]*[0, 0]=[0, 0] mask=[0, 1]時, 機率爲p2 = p*(1-p)=0.21, 結果爲r2=[x0, x1]*[0, 1]=[0, x1] mask=[1, 1]時, 機率爲p3 = (1-p)*(1-p)=0.49, 結果爲r3=[x0, x1]*[1, 1]=[x0, x1] mask=[1, 0]時, 機率爲p4 = p*(1-p)=0.21, 結果爲r4=[x0, x1]*[1, 0]=[x0, 0] 取平均值 r = (r1*p1 + r2*p2 +r3*p3 + r4*p4) = [0.7*x0, 0.7*x1] = x*(1-p) 所以在測試階段,能夠直接採用輸出值乘以機率 """
因爲不肯定訓練階段捨棄的是那些神經元的值,測試階段採起求指望的方式,推理以下:
假設x=[x0, x1], p=0.3; 在訓練階段的mask會出現四種狀況:[0, 0], [0, 1], [1, 1], [1, 0], 每種狀況的輸出以下:
mask=[0, 0]時, 機率爲p1 = p*p=0.09, 結果爲r1=[x0, x1]*[0, 0]=[0, 0]
mask=[0, 1]時, 機率爲p2 = p*(1-p)=0.21, 結果爲r2=[x0, x1]*[0, 1]=[0, x1]
mask=[1, 1]時, 機率爲p3 = (1-p)*(1-p)=0.49, 結果爲r3=[x0, x1]*[1, 1]=[x0, x1]
mask=[1, 0]時, 機率爲p4 = p*(1-p)=0.21, 結果爲r4=[x0, x1]*[1, 0]=[x0, 0]
取平均值 r = (r1*p1 + r2*p2 +r3*p3 + r4*p4) = [0.7*x0, 0.7*x1] = x*(1-p)
所以在測試階段,能夠直接採用輸出值乘以機率1-p
(2)訓練階段以機率p捨棄神經元輸出值,併除以機率值1-p,測試階段不處理。numpy實現代碼以下:
#(2)訓練階段以機率p捨棄神經元輸出值,併除以機率值1-p,測試階段不處理 #train def dropout_train_step(x, p): zeros = np.zeros_like(x) x = np.max((zeros, input),axis=3) #ReLU mask = np.random.rand(*(x.shape)) < p #randn產生0-1的隨機分佈,其中值小於機率值p的爲0 return x*mask/(1-p) #dropout,值小於機率值p的會被捨棄掉 #test def dropout_test_step(x, p): zeros = np.zeros_like(x) x = np.max((zeros, input),axis=3) #ReLU return x #訓練階段除以了機率1-p, 因此測試時不處理 if __name__=="__main__": input = np.random.randn(4, 3, 2, 2) print(dropout_train_step(input, 0.5))
由上面(1)可知,在測試階段須要乘以機率1-p,能夠改成在訓練階段除以機率1-p, 這樣測試階段能夠的不用處理
4.正則化和歸一化(Regularization and Normalization)
4.1 正則化(Regularization)
正則化(Regularization):在機器學習中,爲了遏制過擬合,常使用正則化的方法。即在loss函數中引入正則化項,其實質是削弱特徵值對loss的影響。
正則化形式:以下圖中紅色框中部分即引入的正則化項,依次爲線性迴歸,邏輯迴歸和神經網絡中的表示形式:
正則化原理: 下圖中,對比Linear regression的正則化先後表達式,能夠發現loss函數引入正則化項後,在進行梯度降低時,原參數θj 引入了一個權重(綠框部分),所以對應的輸入數據對結果的影響變小了,從而削弱了特徵值的影響。
正則化種類:上述式子中都採用的是L2 Regularization,還有L1 Regularization。以下圖所示:
4.2 歸一化(Normalization)
歸一化:一條數據中常有多個特徵,而每一個特徵維度上數據大尺度不一致,如房子有價格和房間數兩個特徵,價格都是過萬的數字,而房間數都是十之內,差距較大,爲了使其具備可比性,常在每一個特徵維度上進行歸一化,將數據歸一化到0-1範圍內。歸一化方法以下所示:
參考:https://www.zhihu.com/question/20924039/answer/131421690
https://www.cnblogs.com/maybe2030/p/9231231.html