Improving Deep Neural Networks[1]
對吳恩達老師的《優化深度神經網絡》課程作業知識進行總結。
文章目錄
參數初始化 Initialization
首先,明確參數初始化的目的:
- 好的初始化策略能加快梯度下降的收斂速度;
- 能降低梯度下降收斂過程中出錯的概率。
在本節,吳恩達主要介紹了三種初始化策略:
- 零初始化 Zeros initialization
- 隨機初始化 Random initialization
- He初始化 He initialization
在神經網絡中,需要初始化的參數有:
- 權重:
- 偏移量:
其中,每一個權重的維度都是[當前層的神經元數,前一層的神經元數],每一個偏移量都是標量。
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
在吳恩達老師的課程中,隨機初始化可以將參數初始化爲:
- 較大的參數
- 較小的參數
同時,提出了一個疑問:如果較大/較小的參數表現較好,那麼需要設置爲多大/小呢?
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
吳恩達老師在本節末提到:
- Different initializations lead to different results.
- Random initialization is used to break symmetry and make sure different hidden units can learn different things.
- Don’t initialize to values that are too large .
- He initialization works well for networks with ReLU activations.
下一篇:Improving Deep Neural Networks [2]
2019/10 Karl