Improving Deep Neural Networks [1]

Improving Deep Neural Networks[1]

對吳恩達老師的《優化深度神經網絡》課程作業知識進行總結。

參數初始化 Initialization

首先,明確參數初始化的目的:

  • 好的初始化策略能加快梯度下降的收斂速度;
  • 能降低梯度下降收斂過程中出錯的概率。

在本節,吳恩達主要介紹了三種初始化策略:

  • 零初始化 Zeros initialization
  • 隨機初始化 Random initialization
  • He初始化 He initialization

在神經網絡中,需要初始化的參數有:

  • 權重:(W[1],W[2],W[3],...,W[L1],W[L])(W^{[1]}, W^{[2]}, W^{[3]}, ..., W^{[L-1]}, W^{[L]})
  • 偏移量:(b[1],b[2],b[3],...,b[L1],b[L])(b^{[1]}, b^{[2]}, b^{[3]}, ..., b^{[L-1]}, b^{[L]})

其中,每一個權重的維度都是[當前層的神經元數,前一層的神經元數],每一個偏移量都是標量。


1 零初始化 Zeros initialization

def initialize_parameters_zeros(layers_dims):    
    parameters = {}
    L = len(layers_dims)            # number of layers in the network
    
    for l in range(1, L):
        parameters['W'+str(l)] = np.zeros((layers_dims[l], layers_dims[l-1]))
        parameters['b'+str(l)] = np.zeros((layers_dims[l], 1))
    return parameters

在例程中,使用 np.zeros((dim_x, dim_y)) 初始化了參數。


然而,實驗結果是出人意料的:
在這裏插入圖片描述
經過迭代沒有任何變化。

原因分析:

初始化所有的權重爲0,前向傳播,因此Z1, Z2, … Zn都爲0;

經過激活函數後值相同,A1 = A2 = … = An = g(Zi) = g(0).

反向傳播,參數的梯度改變是一樣的,所以新的參數相同。

因此,不管進行多少輪前向以及反向傳播,每倆層之間的參數都是一樣的。

沒有打破對稱性 Fail to break Symmetry

換句話說,本來我們希望不同的結點學習到不同的參數,但是由於參數相同以及輸出值都一樣,不同的結點根本無法學到不同的特徵!這樣就失去了網絡學習特徵的意義了。

隱藏層與其它層多個結點,其實僅僅相當於一個結點。

Ref: 爲什麼神經網絡參數不能全部初始化爲0?


2 隨機初始化 Random initialization

在吳恩達老師的課程中,隨機初始化可以將參數初始化爲:

  1. 較大的參數
  2. 較小的參數

同時,提出了一個疑問:如果較大/較小的參數表現較好,那麼需要設置爲多大/小呢?

def initialize_parameters_random(layers_dims):
    np.random.seed(3)
    parameters = {}
    L = len(layers_dims)

    for l in range(1, L):
        parameters['W'+str(l)] = 
        	np.random.randn(layers_dims[l], layers_dims[l-1]) * 10
        parameters['b'+str(l)] = 
        	np.zeros((layers_dims[l], 1))
    return parameters

在本例中,使用np.random.randn(layers_dims[l], layers_dims[l-1]) * 10將參數初始化爲一個比較大的值,來測試較大的參數表現如何。


結果如下:

在這裏插入圖片描述
代價從一個極高的值開始(實際上在本例是-inf),在迭代過程中容易出現梯度消失或梯度爆炸。

預測結果如下:

在這裏插入圖片描述

顯然,這不是一個好的預測模型。


筆者同時在上代碼段修改np.random.randn(layers_dims[l], layers_dims[l-1]) * 0.1將參數初始化爲一個很小的值,來測試較小的參數表現如何。

cost - iteration圖如下:

預測結果如下:

同樣,太小的參數也不是一個可取的結果。


在此基礎上,吳恩達老師繼續介紹了下一種可行的初始化方法。


3 He初始化 He initialization

He 初始化由He等人在2015年首次提出,與著名的Xavier initialization只有一點細微的差別。

Xavier: sqrt(1./layers_dims[l-1])

He: sqrt(2./layers_dims[l-1])

二者在對W進行標準化的時候採用了以上兩種不同的策略(儘管只有極其微小的差別)。


def initialize_parameters_he(layers_dims):
    np.random.seed(3)
    parameters = {}
    L = len(layers_dims)

    for l in range(1, L):
        parameters['W'+str(l)] = 
        	np.random.randn(layers_dims[l], layers_dims[l-1]) *
            np.sqrt(2./layers_dims[l-1])
        parameters['b'+str(l)] = 
        	np.zeros((layers_dims[l], 1))
    return parameters

cost - iteration圖如下:

在這裏插入圖片描述

預測結果如下:

在這裏插入圖片描述

顯然,預測結果是很不錯的。


關於He 與 Xavier兩個初始化方式,簡單總結如下:

  • He initialization works better for layers with ReLu activation.
  • Xavier initialization works better for layers with sigmoid activation.

He 初始化在使用ReLu激活函數時表現很好;Xavier 初始化在使用sigmoid激活函數時表現很好。

二者的基本思想都是:防止方差因爲較大或較小的初始值而變化,進而導致梯度在傳播過程中(前向、反向)消失等意外的發生。

Ref: Difference between “he and xavier initialization”


4 總結 Conclusion

吳恩達老師在本節末提到:

  1. Different initializations lead to different results.
  2. Random initialization is used to break symmetry and make sure different hidden units can learn different things.
  3. Don’t initialize to values that are too large .
  4. He initialization works well for networks with ReLU activations.


下一篇:Improving Deep Neural Networks [2]

2019/10 Karl

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