cs231n-(5)神經網絡-2:設置數據和Loss

數據預處理

神經網絡輸入的數據往往要經過預處理。假設數據X大小爲[N x D],其中N表示元素個數,D表示維度。

減去均值

最長用的就是減去每個特徵的均值(均值常常有訓練集計算得到),減去均值的幾何意義是將數據中心大致移到零點。。使用python時,可以用X-=np.mean(X, axis = 0)算得均值。如果是圖像,常常減去RGB通道的均值。

正則化

正則化是指將數據各個維度歸一化,即變化範圍相同。一般有兩種方法:1、將數據均值設爲零(如減去均值),之後除以標準差:X /= np.std(X, axis=0)。2、不同維度的數據範圍相差很大,且重要性相同,將其最大值和最小值分別變換爲+1和-1。

下去就是原始數據,零中心化,正則化處理的效果。 
cs231n6_01.jpeg

PCA and Whitening

PCA是用來降維,假設已經完成了零中心化和歸一化,降維過程如下: 
先計算協方差矩陣

# Assume input data matrix X of size [N x D]
X -= np.mean(X, axis = 0) # zero-center the data (important)
cov = np.dot(X.T, X) / X.shape[0] # get the data covariance matrix

協方差矩陣中(i,j)位的數據表示i維度和j維度數據的協方差;對角線上數據表示某一維度的方差。協方差矩陣是對稱的半正定矩陣,對它進行SVD分解:

U,S,V = np.linalg.svd(cov)

得到U是特徵向量矩陣,它的每一列都是一個特徵向量,S是特徵值向量,因爲協方差矩陣是對稱的半正定矩陣,所以它等於特徵值平方。爲了去除相關性,將已經中心化的數據映射到特徵向量上

Xrot = np.dot(X, U) # decorrelate the data

其中U的每一列都是標準正交特徵向量,且已經按照特徵值由大到小排列(np.linalg.svg返回時已經排列)。與特徵向量相乘,相當於對X的數據做一個旋轉映射,映射到特徵向量對應的正交基上。可以只保留前面較大特徵值對應的特徵向量,丟棄較小值對應的特徵向量,以此來降維。這種方法叫做Principal component analysis

Xrot_reduced = np.dot(X, U[:,:100]) # Xrot_reduced becomes [N x 100]
  • 1

通過這個操作,保留了前100維度數據(以方差大小爲標準)。

經過PCA處理的數據,可以再經過白化Whitening處理。白化是指PCA處理後的數據,每個維度除以其特徵值。幾何解釋就是服從多維度高斯分佈的數據,經過白化處理後,服從均值爲零,協方差相等的分佈。

# whiten the data:
# divide by the eigenvalues (which are square roots of the singular values)
Xwhite = Xrot / np.sqrt(S + 1e-5)

上面處理爲白化操作,分母加上1e-5爲防止分母爲零。這樣的操作把所有維度數據拉伸到相同範圍,可能會放大噪聲,實際中可以通過增大分母(加上比1e-5更大的值)來平滑。 
cs231n6_02.jpeg

上圖左邊分佈爲原始數據。中間爲PAC處理後的數據,可以看出PCA處理後,將座標軸旋轉,可以看出橫軸信息量大,如果只保留一維數據,要丟棄縱軸數據。右邊爲白化處理後的數據,數據範圍相同了

使用CIFAR-10來展示PCA和白化 
cs231n6_03.jpeg
上圖中,最左邊爲原始數據,每張圖片可以看做是3072的列向量。第二張爲特徵向量中,前144個(按照特徵值排列)。第三張爲經過PAC降維處理後,只保留144維特徵的圖片;圖片變模糊了,說明只保留了低頻部分。最後一張爲白化後的圖片。

注意:CNN不需要進行PCA和白化操作,這裏提到只是講解數據處理的一般方法。 
數據預處理,只能在訓練集上應用。應該先將數據分爲訓練集、驗證集、測試集,之後在訓練集上應用數據預處理。

權重初始化

訓練神經網絡前,要先初始化權重。

全部初始化爲零

權重最終的值我們不知道,但是根據前面數據預處理過程,大概可以猜到,權重最終應該是一般爲正,一般爲負。但是權重不能全部初始化爲零。如果全部初始化爲零,那麼所有神經元輸出將相同,計算得到所有梯度都相同,權重更新相同,最終得到的權重也相同。

小的隨機數

因爲正則化,權重要比較小,但是又不能對稱;那麼可以用小的隨機數來初始化。這樣計算得到不同梯度,迭代更新權重會趨向不同。例如這樣初始化。W = 0.01 * np.random.randn(D, H)randn是生成零均值單位方差的高斯分佈。這樣初始化,每個神經權重向量是從高維高斯分佈隨機採樣而來;也可是使用隨機生成的隨機數。但是在實際中,這樣初始化效果不好。

小的權重並不一定會得到好的效果。神經網絡中,如果權重比較小,那麼反向傳播時,梯度就比較小。這樣會減小梯度傳播的信號,在深度神經網絡中也是個問題。

校準方差

如果神經元輸出有着相似的分佈,那麼收斂速度回加快。前面提到的權重初始化方法,隨着輸入增大,輸出的方差會增大。通過除以sqrt(n),其中n是輸入個數,可以將輸出方差歸一化到1;例如這樣初始化w = np.random.randn(n) / sqrt(n)

不考慮非線性激活函數,假設輸出s=niwixis=∑inwixi,那麼計算輸出方差和輸入關係如下:

Var(s)=Var(inwixi)=inVar(wixi)=in[E(wi)]2Var(xi)+E[(xi)]2Var(wi)+Var(xi)Var(wi)=inVar(xi)Var(wi)=(nVar(w))Var(x)Var(s)=Var(∑inwixi)=∑inVar(wixi)=∑in[E(wi)]2Var(xi)+E[(xi)]2Var(wi)+Var(xi)Var(wi)=∑inVar(xi)Var(wi)=(nVar(w))Var(x)

上面第三步中,用到了假設E[xi]=E[wi]=0E[xi]=E[wi]=0(注意,有些並不等於零,例如ReLU),最後一步假設了x,wx,w服從相同分佈。如果想要輸出和xx有相同的方差,那麼nVar(w)nVar(w)必須爲1,所以得到上面初始化方式w = np.random.randn(n) / sqrt(n)

論文Understanding the difficulty of training deep feedforward neural networks推薦初始化方式爲Var(w)=2/(nin+nout)Var(w)=2/(nin+nout),其中nin,noutnin,nout分佈表示前一層和後一層網絡中單元個數。論文 Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification 提出,針對ReLU初始化,網絡中神經元方差爲2.0/n2.0/n,這樣初始化變爲w = np.random.randn(n) * sqrt(2.0/n);在實踐中使用ReLU時,推薦這樣初始化。。

稀疏初始化

首先將所有權重初始化爲零,但是爲了避免對稱,隨機在層之間連接個別神經全,權重初始化可以使用小的高斯分佈,連接個數常常設置爲10.

實際應用

目錄,使用ReLU激活函數的,建議初始化爲w = np.random.randn(n) * sqrt(2.0/n),參考He et al

批歸一化 Batch Normalization

這是個最近出現的技術,參考論文。它在一定程度上減輕瞭如何初始化網絡權重的問題。具體做法爲讓數據在輸入激活函數前先通過一個網絡,通過這個網絡之後,輸出數據(即輸入激活函數的數據)服從標準高斯分佈。因爲歸一化是一個可以簡單的求導操作,因此方案可行。實際應用中,常常在全連接層(卷積層)和激活函數(非線性操作)之間插入一個BatchNormalization層。批歸一化可以理解爲在網絡每一層之前都做了預處理。

正則化

正則化用來阻止網絡過擬合,有以下幾種方法:

L2 regularization

L2正則化是最常用的方法;它可以直接懲罰目標函數中任何一個權重平方的幅度。具體實現時對於每一個權重ww在目標函數都加上一項12λw212λw2,其中λλ常常等於1212,這樣方便求導運算。L2正則化可以直觀理解爲,它限制單個較大的權重,在權重和不變時,它把權重大概均勻分不到每個權重上。使用L2正則化後,在反向傳播梯度更新時,權重會以W+=-lambda * W速度向0靠近。

L1 regularization

L1正則化也是常用的一種方法,在目標函數中,它給每個權重加上一項λ|w|λ|w|。可以把L1和L2正則化結合起來λ1|w|+λ2w2λ1|w|+λ2w2(叫做Elastic net regularization)。L1正則化會使權重矩陣變得稀疏(非常接近0);經過L1正則化後,使用時,用的就是輸入的子集了(某些權重係數接近0,對應輸入會變爲0)。而L2正則化後,權重會變爲大小分佈均勻且都接近0的數。使用中,如果沒有顯示去選擇特徵,那麼L2正則化效果一般優於L1正則化。

Max norm constraints

Max norm正則化限制梯度幅度最大值,並使用投影梯度來確保限制。使用中,參數更新方式不變,只需要檢查更新後滿足||w||2<c||w→||2<c,不滿足則消減梯度。cc常常設置爲3或4。使用這個約束後,網絡就不會“爆炸”,因爲它限制了權重大小。

Dropout

Drop是非常簡單高效的正則化方法,在論文Dropout: A Simple Way to Prevent Neural Networks from Overfitting 中介紹,可以作爲上面正則化方法的補充。它的思想爲在訓練時,讓神經元以概率pp激活(或者設置爲零,不激活)。

cs231n6_04.jpeg 
例如上面圖片中,左邊是沒有使用Dropout的網絡,右邊是使用了Dropout的網絡。需要注意,Dropout只是在訓練的時候使用,在測試時,不使用。

3層網絡Dropout代碼

""" Vanilla Dropout: Not recommended implementation (see notes below) """

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  """ X contains the data """

  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = np.random.rand(*H1.shape) < p # first dropout mask
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = np.random.rand(*H2.shape) < p # second dropout mask
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)

def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) * p # NOTE: scale the activations
  H2 = np.maximum(0, np.dot(W2, H1) + b2) * p # NOTE: scale the activations
  out = np.dot(W3, H2) + b3

在訓練時使用了Dropout,在預測沒有使用Dropout。在使用DropOut時,以概率pp來激活神經元,那麼一層網絡的輸出會變爲原來的pp倍;在預測是不使用DropOut,爲了使得每一層輸出值和訓練時一致,在每一層計算後也要乘以概率pp

因爲我們更加關心測試時的性能,在預測時增加計算會減低生產環境性能;一個解決的方法爲在訓練時,把使用DropOut的層除以概率pp,這個方法叫做Inverted dropout。


""" 
Inverted Dropout: Recommended implementation example.
We drop and scale at train time and don't do anything at test time.
"""

p = 0.5 # probability of keeping a unit active. higher = less dropout

def train_step(X):
  # forward pass for example 3-layer neural network
  H1 = np.maximum(0, np.dot(W1, X) + b1)
  U1 = (np.random.rand(*H1.shape) < p) / p # first dropout mask. Notice /p!
  H1 *= U1 # drop!
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  U2 = (np.random.rand(*H2.shape) < p) / p # second dropout mask. Notice /p!
  H2 *= U2 # drop!
  out = np.dot(W3, H2) + b3

  # backward pass: compute gradients... (not shown)
  # perform parameter update... (not shown)

def predict(X):
  # ensembled forward pass
  H1 = np.maximum(0, np.dot(W1, X) + b1) # no scaling necessary
  H2 = np.maximum(0, np.dot(W2, H1) + b2)
  out = np.dot(W3, H2) + b3

更多內容可以參考 
Dropout paper by Srivastava et al. 2014. 
Dropout Training as Adaptive Regularization: “we show that the dropout regularizer is first-order equivalent to an L2 regularizer applied after scaling the features by an estimate of the inverse diagonal Fisher information matrix”

Theme of noise in forward pass

DropOut是在前向傳播時引入一些隨機行爲,在預測時通過數值方法補償這個隨機行爲。這樣類似的方法還有DropConnect

Bias regularization

偏置不直接和輸入數據相乘,它並不直接影響某一維度的數據,因此常常不用對偏置正則化。實際應用中,數據合理預處理後,對偏置正則化也很少導致算法性能變差;可能是因爲權重係數遠遠多於偏置。

Per-layer regularization.

不同的層使用不同的正則化方法。很少見。

實踐

1、全局使用L2正則化,λλ大小通過交叉驗證獲得。 
2、使用L2正則化後,常常再結合Dropout,一般可以設置p=0.5p=0.5,也可以通過交叉驗證獲得。

損失函數

這裏來討論損失函數中的數據損失部分,在監督學習中常常用到,用來衡量預測值和真實值的差異程度。損失函數是輸入數據的平均L=1NiLiL=∑1NiLi,其中NN是訓練集大小。實際常常常常遇到以下幾類問題

分類問題

這裏假設每個樣本都只有一個標籤,最常用的兩個損失函數爲:

Li=jyimax(0,fjfyi+1)Li=∑j≠yimax(0,fj−fyi+1)
Li=log(efyijefj)Li=−log⁡(efyi∑jefj)

第一個是SVM分類中用到的,第二個時Softmax分類器用到的交叉熵loss。

Problem: Large number of classes.

當標籤集合特別大時(例如單詞字典等),要使用Hierarchical Softmax。其思想爲,把標籤構建爲一棵樹,每個標籤爲樹的一條路徑,在樹的每個結點訓練Softmax分類器。樹的結構要依具體問題而定。

Attribute classification

如果一個樣本的標籤不止一個時,例如標籤yiyi是一個二值向量,可能包含標籤集合中的某幾個標籤,且標籤不互斥。這時可以爲每個標籤建立一個二值分類器:

Li=jmax(0,1yijfj)Li=∑jmax(0,1−yijfj)

jj表示lable數量,yijyij表示第ii個樣本是否包含第jj個標籤,如果包含yijyij爲+1,否則爲-1;fifi表示預測值,正確預測時其值爲正,否則爲負。可以計算,當正確預測且分值小於1,或錯誤預測分值大於-1時,loss就會大於零。

還有一個方法,就是對每個標籤訓練一個分類器,那麼loss函數爲

Li=jyijlog(σ(fj))+(1yij)log(1σ(fj))Li=∑jyijlog⁡(σ(fj))+(1−yij)log⁡(1−σ(fj))

這裏yijyij是1(表示包含標籤j)或0(不包含標籤j)。

迴歸

對於預測連續值,迴歸問題的loss函數有L2正則化和L1正則化形式,分別爲

Li=fyi22Li=‖f−yi‖22
Li=fyi1=jfj(yi)jLi=‖f−yi‖1=∑j∣fj−(yi)j∣

注意

1、與更加穩定的loss(例如Softmax),L2 loss更加難以優化。L2 loss要求每個輸入都要輸出正確值;而Softmax的評分並不重要,只有當評分在適當量級時纔有意義。 
2、L2 Norm的魯棒性並不好,異常值可能引起很大的梯度。 
3、面對迴歸問題時,優先想想能不能轉換爲分類問題。 
4、如果使用迴歸,L2是一個不錯的選擇。但是在dorpout網絡結構中,不宜再用L2。

Structured prediction

結構化預測是指標籤是任意的形狀(樹,圖等),通常假設結構空間非常大且難以遍歷。其思想和結構化SVM類似,在正確分類和分值最高的錯誤分類間建立一個分類面。

總結

1、數據預處理:零中心化,正則化把特徵範圍縮放爲[-1,1]。 
2、初始化權重方法,通過使用高斯分佈,標準差爲2/n2/n。 
3、正則化L2,L1,Dropout。 
4、BachNorm。 
5、Loss函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章