Initialization(初始化)
本文作業是在jupyter notebook上一步一步做的,帶有一些過程中查找的資料等(出處已標明)並翻譯成了中文,如有錯誤,歡迎指正!
歡迎來到“改進深度神經網絡”的第一個作業。
訓練神經網絡需要指定權重的初始值。一個精心選擇的初始化方法將有助於學習。
如果您完成了這個專門化的前一門課程,那么您可能按照我們的說明進行了權重初始化,到目前為止,它已經完成了。但是如何選擇一個新的神經網絡的初始化呢?在這個筆記本中,您將看到不同的初始化如何導致不同的結果。
一個精心選擇的初始化可以:
•加速梯度下降的收斂
•增加梯度下降收斂為較低訓練(和泛化)誤差的幾率
首先,運行以下單元格以加載包和您將嘗試分類的平面數據集。
import numpy as np import matplotlib.pyplot as plt import sklearn import sklearn.datasets from init_utils import sigmoid, relu, compute_loss, forward_propagation, backward_propagation from init_utils import update_parameters, predict, load_dataset, plot_decision_boundary, predict_dec %matplotlib inline plt.rcParams['figure.figsize'] = (7.0, 4.0) # set default size of plots 設置圖形的默認大小 plt.rcParams['image.interpolation'] = 'nearest'#設置插值為最近的 plt.rcParams['image.cmap'] = 'gray' #設置顏色樣式 # load image dataset: blue/red dots in circles 加載圖像數據集:藍色/紅色圓點在圓圈 train_X, train_Y, test_X, test_Y = load_dataset()
您需要一個分類器來區分藍點和紅點。
Python之Sklearn使用教程,來自愛折騰的大懶豬,鏈接:https://www.jianshu.com/p/6ada34655862
1 - Neural Network model 神經網絡模型
您將使用一個3層神經網絡(已經為您實現了)。這里是你將試驗的初始化方法:
•zero初始化——設置初始化=“zero”在輸入參數中。
•隨機初始化——在輸入參數中設置初始化=“Random”。這會將權重初始化為較大的隨機值。
•He初始化——設置初始化=輸入參數中的“He”。這將根據He等人2015年的一篇論文將權重初始化為按比例縮放的隨機值。
說明:請快速閱讀下面的代碼,並運行它。在下一部分中,您將實現這個模型()調用的三個初始化方法。
1 def model(X, Y, learning_rate = 0.01, num_iterations = 15000, print_cost = True, initialization = "he"): 2 """ 3 Implements a three-layer neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SIGMOID. 4 5 Arguments: 6 X -- input data, of shape (2, number of examples) 輸入數據,形狀為(2, 樣本數) 7 Y -- true "label" vector (containing 0 for red dots; 1 for blue dots), of shape (1, number of examples) 真是標簽向量(0為紅點,1為藍點),形狀(1, y樣本數) 8 learning_rate -- learning rate for gradient descent 梯度下降的學習率 9 num_iterations -- number of iterations to run gradient descent 運行梯度下降的迭代次數 10 print_cost -- if True, print the cost every 1000 iterations如果為真,每1000次迭代打印成本 11 initialization -- flag to choose which initialization to use ("zeros","random" or "he") 12 13 Returns: 14 parameters -- parameters learnt by the model 模型學習的參數 15 """ 16 17 grads = {} 18 costs = [] # to keep track of the loss 記錄損失情況 19 m = X.shape[1] # number of examples 樣本數量 20 layers_dims = [X.shape[0], 10, 5, 1] #每層的神經單元數,分別是第0層,第一層 21 22 # Initialize parameters dictionary.初始化參數字典,如下:有三種方式 23 if initialization == "zeros": 24 parameters = initialize_parameters_zeros(layers_dims) 25 elif initialization == "random": 26 parameters = initialize_parameters_random(layers_dims) 27 elif initialization == "he": 28 parameters = initialize_parameters_he(layers_dims) 29 30 # Loop (gradient descent)循環,梯度下降 31 32 for i in range(0, num_iterations): 33 34 # Forward propagation: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID. 35 a3, cache = forward_propagation(X, parameters) 36 37 # Loss損失 38 cost = compute_loss(a3, Y) 39 40 # Backward propagation.反向傳播 41 grads = backward_propagation(X, Y, cache) 42 43 # Update parameters.更新參數 44 parameters = update_parameters(parameters, grads, learning_rate) 45 46 # Print the loss every 1000 iterations 47 if print_cost and i % 1000 == 0: 48 print("Cost after iteration {}: {}".format(i, cost)) 49 costs.append(cost) 50 51 # plot the loss 52 plt.plot(costs) 53 plt.ylabel('cost') 54 plt.xlabel('iterations (per hundreds)') 55 plt.title("Learning rate =" + str(learning_rate)) 56 plt.show() 57 58 return parameters
2 - Zero initialization 零初始化
在神經網絡中有兩種類型的參數需要初始化:
•權重矩陣(W [1],W [2],W[3],…),W [L−1],W [L])
•偏差向量(b [1],b [2],b[3],…),b [L−1],b [L])
練習:實現以下函數,將所有參數初始化為零。稍后您將看到,這並不能很好地工作,因為它不能“破壞對稱”,但讓我們無論如何嘗試一下,看看會發生什么。使用np. 0((..,..))和正確的形狀。

1 # GRADED FUNCTION: initialize_parameters_zeros 2 3 def initialize_parameters_zeros(layers_dims): 4 """ 5 Arguments: 6 layer_dims -- python array (list) containing the size of each layer. python數組(列表),包含每一層的大小。 7 8 Returns: 9 parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL": 10 W1 -- weight matrix of shape (layers_dims[1], layers_dims[0]) 11 b1 -- bias vector of shape (layers_dims[1], 1) 12 ... 13 WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1]) 14 bL -- bias vector of shape (layers_dims[L], 1) 15 """ 16 17 parameters = {} 18 L = len(layers_dims) # number of layers in the network 網絡的層數 19 20 for l in range(1, L): 21 ### START CODE HERE ### (≈ 2 lines of code) 22 parameters['W' + str(l)] = np.zeros((layers_dims[l], layers_dims[l - 1])) 23 parameters['b' + str(l)] = np.zeros((layers_dims[l], 1)) 24 ### END CODE HERE ### 25 return parameters
parameters = initialize_parameters_zeros([3,2,1]) print("W1 = " + str(parameters["W1"])) print("b1 = " + str(parameters["b1"])) print("W2 = " + str(parameters["W2"])) print("b2 = " + str(parameters["b2"]))
結果:
運行以下代碼,使用零初始化對模型進行15,000次迭代。
parameters = model(train_X, train_Y, initialization = "zeros") print ("On the train set:") predictions_train = predict(train_X, train_Y, parameters) print ("On the test set:") predictions_test = predict(test_X, test_Y, parameters)
結果:
性能是非常糟糕的,並不真正降低成本,算法的表現沒有比隨機猜測更好。為什么?讓我們看看預測和決策邊界的細節:
print ("predictions_train = " + str(predictions_train)) print ("predictions_test = " + str(predictions_test))
plt.title("Model with Zeros initialization") axes = plt.gca() axes.set_xlim([-1.5,1.5]) axes.set_ylim([-1.5,1.5]) plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
這兒會出現錯誤,還是由於數組維度的問題:

1 TypeError Traceback (most recent call last) 2 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba(c, alpha) 3 165 try: 4 --> 166 rgba = _colors_full_map.cache[c, alpha] 5 167 except (KeyError, TypeError): # Not in cache, or unhashable. 6 7 TypeError: unhashable type: 'numpy.ndarray' 8 9 During handling of the above exception, another exception occurred: 10 11 ValueError Traceback (most recent call last) 12 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, **kwargs) 13 4287 # must be acceptable as PathCollection facecolors 14 -> 4288 colors = mcolors.to_rgba_array(c) 15 4289 except ValueError: 16 17 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba_array(c, alpha) 18 266 for i, cc in enumerate(c): 19 --> 267 result[i] = to_rgba(cc, alpha) 20 268 return result 21 22 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba(c, alpha) 23 167 except (KeyError, TypeError): # Not in cache, or unhashable. 24 --> 168 rgba = _to_rgba_no_colorcycle(c, alpha) 25 169 try: 26 27 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in _to_rgba_no_colorcycle(c, alpha) 28 222 if len(c) not in [3, 4]: 29 --> 223 raise ValueError("RGBA sequence should have length 3 or 4") 30 224 if len(c) == 3 and alpha is None: 31 32 ValueError: RGBA sequence should have length 3 or 4 33 34 During handling of the above exception, another exception occurred: 35 36 ValueError Traceback (most recent call last) 37 <ipython-input-12-0ec6f7c907fb> in <module>() 38 3 axes.set_xlim([-1.5,1.5]) 39 4 axes.set_ylim([-1.5,1.5]) 40 ----> 5 plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y) 41 42 ~\Downloads\代碼作業\第二課第一周編程作業\assignment1\init_utils.py in plot_decision_boundary(model, X, y) 43 215 plt.ylabel('x2') 44 216 plt.xlabel('x1') 45 --> 217 plt.scatter(X[0, :], X[1, :], c=y, cmap=plt.cm.Spectral) 46 218 plt.show() 47 219 48 49 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\pyplot.py in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, hold, data, **kwargs) 50 3473 vmin=vmin, vmax=vmax, alpha=alpha, 51 3474 linewidths=linewidths, verts=verts, 52 -> 3475 edgecolors=edgecolors, data=data, **kwargs) 53 3476 finally: 54 3477 ax._hold = washold 55 56 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\__init__.py in inner(ax, *args, **kwargs) 57 1865 "the Matplotlib list!)" % (label_namer, func.__name__), 58 1866 RuntimeWarning, stacklevel=2) 59 -> 1867 return func(ax, *args, **kwargs) 60 1868 61 1869 inner.__doc__ = _add_data_doc(inner.__doc__, 62 63 D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\axes\_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, **kwargs) 64 4291 raise ValueError("c of shape {} not acceptable as a color " 65 4292 "sequence for x with size {}, y with size {}" 66 -> 4293 .format(c.shape, x.size, y.size)) 67 4294 else: 68 4295 colors = None # use cmap, norm after collection is created 69 70 ValueError: c of shape (1, 300) not acceptable as a color sequence for x with size 300, y with size 300
解決辦法:參考自:十一點三十六,鏈接:https://blog.csdn.net/qq_33782064/article/details/80259141
結果:
模型對每個例子的預測都是0。
一般來說,將所有權值初始化為零會導致網絡無法破壞對稱性。這意味着每一層中的每一個神經元都將學習相同的東西,你也可以用n [l] =1來訓練一個神經網絡,而這個網絡並不比線性分類器(比如logistic回歸)更強大。
**你應該記住的**:-權重W [l]應該被隨機初始化以打破對稱性。-然而,將偏差b [l]初始化為零是可以的。隨機初始化W [l]仍然破壞了對稱性。
3 - Random initialization 隨機初始化
為了打破對稱性,讓權重隨機化。在隨機初始化之后,每個神經元可以繼續學習其輸入的不同函數。在這個練習中,您將看到如果權重被隨機地初始化,但是權重是非常大的值會發生什么。
練習:執行以下函數,將權重初始化為大的隨機值(按*10的比例縮放),並將偏差初始化為零。為了偏見,使用np.random.randn(..,..) * 10來表示權重和np. 0 (..)。我們使用固定的np.random.seed(..)來確保您的“隨機”權重與我們的匹配,所以如果運行幾次您的代碼總是給您相同的參數初始值,也不用擔心。

1 # GRADED FUNCTION: initialize_parameters_random 2 3 def initialize_parameters_random(layers_dims): 4 """ 5 Arguments: 6 layer_dims -- python array (list) containing the size of each layer. 7 8 Returns: 9 parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL": 10 W1 -- weight matrix of shape (layers_dims[1], layers_dims[0]) 11 b1 -- bias vector of shape (layers_dims[1], 1) 12 ... 13 WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1]) 14 bL -- bias vector of shape (layers_dims[L], 1) 15 """ 16 17 np.random.seed(3) # This seed makes sure your "random" numbers will be the as ours 18 parameters = {} 19 L = len(layers_dims) # integer representing the number of layers 20 21 for l in range(1, L): 22 ### START CODE HERE ### (≈ 2 lines of code) 23 parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) * 10 24 parameters['b' + str(l)] = np.zeros((layers_dims[l], 1)) 25 ### END CODE HERE ### 26 27 return parameters
parameters = initialize_parameters_random([3, 2, 1]) print("W1 = " + str(parameters["W1"])) print("b1 = " + str(parameters["b1"])) print("W2 = " + str(parameters["W2"])) print("b2 = " + str(parameters["b2"]))
結果:
運行以下代碼,使用隨機初始化對模型進行15,000次迭代訓練。
parameters = model(train_X, train_Y, initialization = "random") print ("On the train set:") predictions_train = predict(train_X, train_Y, parameters) print ("On the test set:") predictions_test = predict(test_X, test_Y, parameters)
結果:
神經網絡中的RuntimeWarning: divide by zero encountered in log問題,參考:BUB1997
如果你看到“inf”是迭代0之后的代價,這是因為數值舍入;一個更復雜的數字實現可以解決這個問題。但就我們的目的而言,這並不值得擔心。
不管怎么說,看起來你破壞了對稱性,這就得到了更好的結果。比以前。模型不再輸出所有0。
print (predictions_train) print (predictions_test)
plt.title("Model with large random initialization") axes = plt.gca() axes.set_xlim([-1.5,1.5]) axes.set_ylim([-1.5,1.5]) plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
觀察:
•成本一開始就很高。這是因為對於大型隨機值權重,最后一個激活(sigmoid)在某些示例中輸出的結果非常接近於0或1,而當它錯誤地執行該示例時,會對該示例造成非常大的損失。確實,當log(a [3])=log(0)時,損失趨於無窮。
•糟糕的初始化會導致梯度消失/爆炸,這也會減慢優化算法。
•如果你訓練這個網絡的時間更長,你會看到更好的結果,但初始化過大的隨機數會降低優化速度。
-將權重初始化為非常大的隨機值並不能很好地工作。希望用小的隨機值初始化效果更好。重要的問題是:這些隨機值應該有多小?讓我們在下一部分中揭曉答案!
4 - He initialization He初始化
最后,嘗試“He初始化”;以He et al., 2015的第一作者命名。(如果您聽說過“Xavier初始化”,這與此類似,除了Xavier初始化為sqrt(1./layers_dims[l-1])的權重W [l]使用一個比例因子,其中初始化將使用sqrt(2./layers_dims[l-1])。)
練習:實現以下函數來初始化參數。
提示:這個函數類似於前面的initialize_parameters_random(…)。唯一的區別是,不是將np.random.randn(..,..)乘以10,而是將其乘以
,這是他對ReLU激活的層的初始化建議。

1 # GRADED FUNCTION: initialize_parameters_he 2 3 def initialize_parameters_he(layers_dims): 4 """ 5 Arguments: 6 layer_dims -- python array (list) containing the size of each layer. 7 8 Returns: 9 parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL": 10 W1 -- weight matrix of shape (layers_dims[1], layers_dims[0]) 11 b1 -- bias vector of shape (layers_dims[1], 1) 12 ... 13 WL -- weight matrix of shape (layers_dims[L], layers_dims[L-1]) 14 bL -- bias vector of shape (layers_dims[L], 1) 15 """ 16 17 np.random.seed(3) 18 parameters = {} 19 L = len(layers_dims) - 1 # integer representing the number of layers 20 21 for l in range(1, L + 1): 22 ### START CODE HERE ### (≈ 2 lines of code) 23 parameters['W' + str(l)] = np.random.randn(layers_dims[l], layers_dims[l-1]) * np.sqrt(2. / layers_dims[l-1]) 24 parameters['b' + str(l)] = np.zeros((layers_dims[l], 1)) 25 ### END CODE HERE ### 26 27 return parameters
parameters = initialize_parameters_he([2, 4, 1]) print("W1 = " + str(parameters["W1"])) print("b1 = " + str(parameters["b1"])) print("W2 = " + str(parameters["W2"])) print("b2 = " + str(parameters["b2"]))
結果:
運行以下代碼,使用He初始化對模型進行15,000次迭代訓練。
parameters = model(train_X, train_Y, initialization = "he") print ("On the train set:") predictions_train = predict(train_X, train_Y, parameters) print ("On the test set:") predictions_test = predict(test_X, test_Y, parameters)
plt.title("Model with He initialization") axes = plt.gca() axes.set_xlim([-1.5,1.5]) axes.set_ylim([-1.5,1.5]) plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
觀察:
•具有He初始化的模型在少量的迭代中很好地分離了藍色和紅色的點。
5 - Conclusions 結論
</tr> <td> 3-layer NN with zeros initialization </td> <td> 50% </td> <td> fails to break symmetry </td> <tr> <td> 3-layer NN with large random initialization </td> <td> 83% </td> <td> too large weights </td> </tr> <tr> <td> 3-layer NN with He initialization </td> <td> 99% </td> <td> recommended method </td> </tr>
這里單元格內是上面這串代碼,但是運行了無法顯示為表格,還未找到解決辦法。
* *你應該從這個筆記本記得* *:
——不同的初始化導致不同的結果
——隨機初始化用於打破對稱,確保不同的隱藏單元可以學到不同的東西
——不要intialize值太大——他用ReLU激活初始化適用於網絡。