吴恩达深度学习第⼆课第⼀周编程作业_regularization(正则化)
Regularization 正则化
声明
本⽂作业是在jupyter notebook上⼀步⼀步做的,带有⼀些过程中查的资料等(出处已标明)并翻译成了中⽂,如有错误,欢迎指正!
lambda编程参考Kulbear 的和和,以及的,以及,
欢迎来到本周的第⼆次作业。深度学习模型有很⼤的灵活性和容量,如果训练数据集不够⼤,过拟合可能会成为⼀个严重的问题。当然,它在训练集上做得很好,但学习过的⽹络不能推⼴到它从未见过的新例⼦!(也就是训练可以,⼀到实战测试就拉胯。)
第⼆个作业的⽬的:
2. 正则化模型:
2.1:使⽤⼆范数对⼆分类模型正则化,尝试避免过拟合。
2.2:使⽤随机删除节点的⽅法精简模型,同样是为了尝试避免过拟合。
您将学习:在您的深度学习模型中使⽤正则化。
让我们⾸先导⼊将要使⽤的包。
# import packages
import numpy as np
import matplotlib.pyplot as plt
from reg_utils import sigmoid, relu, plot_decision_boundary, initialize_parameters, load_2D_dataset, predict_dec
from reg_utils import compute_cost, predict, forward_propagation, backward_propagation, update_parameters
import sklearn
import sklearn.datasets
import scipy.io #scipy是构建在numpy的基础之上的,它提供了许多的操作numpy的数组的函数。scipy.io包提供了多种功能来解决不同格式的⽂件的输⼊和输出。
from testCases import * #from XXX import*是把XXX下的所有名字引⼊当前名称空间。
%matplotlib inline
C:\Users\1\Downloads\代码作业\第⼆课第⼀周编程作业\assignment1\reg_utils.py:85: SyntaxWarning: assertion is always true, perhaps remove parentheses?
assert(parameters['W' + str(l)].shape == layer_dims[l], layer_dims[l-1])
C:\Users\1\Downloads\代码作业\第⼆课第⼀周编程作业\assignment1\reg_utils.py:86: SyntaxWarning: assertion is always true, perhaps remove parentheses?
assert(parameters['W' + str(l)].shape == layer_dims[l], 1)
问题陈述:你刚刚被法国⾜球公司聘为AI专家。他们希望你能推荐法国队守门员应该在什么位置踢球,这样法国队的球员就可以⽤头去碰球了。
**Figure 1** : **Football field** 图⼀⾜球场
守门员把球踢向空中,每个队的队员都在拼命地⽤头击球
他们提供了以下来⾃法国过去10场⽐赛的2D数据集。
train_X, train_Y, test_X, test_Y = load_2D_dataset()
每个点对应⾜球场上法国守门员从球场左侧射门后,⾜球运动员⽤头击球的位置。
•如果圆点是蓝⾊的,表⽰法国球员⽤头击中了球
•如果圆点是红⾊的,表⽰对⽅队员⽤头击球
你的⽬标:使⽤深度学习模型来到守门员应该在场上踢球的位置。
数据集的分析:这个数据集有点嘈杂,但是它看起来像⼀条对⾓线,将左上⾓(蓝⾊)和右下⾓(红⾊)分开,这样会很好。
您将⾸先尝试⼀个⾮正则化的模型。然后,您将学习如何将其规范化,并决定选择哪种模型来解决法国⾜球公司的问题。
1 - Non-regularized model ⽆正则化的模型
您将使⽤以下神经⽹络(下⾯已经为您实现)。该模型可以使⽤:
•正则化模式——通过设置lambd输⼊为⼀个⾮零值。我们使⽤“lambd”⽽不是“lambda”,因为“lambda”在Python中是⼀个保留关键字。
•dropout模式(随机删除节点)——通过设置keep_prob的值⼩于1
您将⾸先尝试不进⾏任何正则化的模型。然后,你将实现:
•L2正则化——函数:“compute_cost_with_regularization()”和“backward_propagation_with_regularization()”
•Dropout——函数:“forward_propagation_with_dropout()”和“backward_propagation_with_dropout()”
在每个部分中,您将使⽤正确的输⼊运⾏此模型,以便它调⽤已实现的函数。请查看下⾯的代码以熟悉模型。
1 def model(X, Y, learning_rate = 0.3, num_iterations = 30000, print_cost = True, lambd = 0, keep_prob = 1):
2 """
3 Implements a three-layer neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SIGMOID.
4
5 Arguments:
6 X -- input data, of shape (input size, number of examples)输⼊的数据,维度为(2, 要训练/测试的数量)
7 Y -- true "label" vector (1 for blue dot / 0 for red dot), of shape (output size, number of examples)
8 learning_rate -- learning rate of the optimization
9 num_iterations -- number of iterations of the optimization loop
10 print_cost -- If True, print the cost every 10000 iterations
11 lambd -- regularization hyperparameter, scalar 正则化超参数,标量
12 keep_prob - probability of keeping a neuron active during drop-out, scalar.在dropout过程中保持神经元活跃的概率,标量
13
14 Returns:
15 parameters -- parameters learned by the model. They can then be used to predict.
16 """
17
18 grads = {}
19 costs = [] # to keep track of the cost
20 m = X.shape[1] # number of examples
21 layers_dims = [X.shape[0], 20, 3, 1]
22
23 # Initialize parameters dictionary.
24 parameters = initialize_parameters(layers_dims)
25
26 # Loop (gradient descent)
27
28 for i in range(0, num_iterations):
29
30 # Forward propagation: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID.
31 if keep_prob == 1:
32 a3, cache = forward_propagation(X, parameters)
33 elif keep_prob < 1: #使⽤上了dropout
34 a3, cache = forward_propagation_with_dropout(X, parameters, keep_prob)
35
36 # Cost function 计算成本
37 if lambd == 0:
38 cost = compute_cost(a3, Y)
39 else:#使⽤上了L2正则化
40 cost = compute_cost_with_regularization(a3, Y, parameters, lambd)
41
42 # Backward propagation.
43 assert(lambd==0 or keep_prob==1) # it is possible to use both L2 regularization and dropout, 可以同时使⽤L2正则化和dropout,
44 # but this assignment will only explore one at a time 这次作业⼀次只探讨⼀个问题
45 if lambd == 0 and keep_prob == 1: #不使⽤L2正则化,也没使⽤dropout,就正常的反向传播
46 grads = backward_propagation(X, Y, cache)
47 elif lambd != 0: #只使⽤了L2正则化
48 grads = backward_propagation_with_regularization(X, Y, cache, lambd)
49 elif keep_prob < 1:#只使⽤了dropout
50 grads = backward_propagation_with_dropout(X, Y, cache, keep_prob)
51
52 # Update parameters.参数更新
53 parameters = update_parameters(parameters, grads, learning_rate)
54
55 # Print the loss every 10000 iterations
56 if print_cost and i % 10000 == 0:
57 print("Cost after iteration {}: {}".format(i, cost))
58 if print_cost and i % 1000 == 0:
59 costs.append(cost)
60
61 # plot the cost
62 plt.plot(costs)
63 plt.ylabel('cost')
64 plt.xlabel('iterations (x1,000)')
65 plt.title("Learning rate =" + str(learning_rate))
66 plt.show()
67
68 return parameters
让我们在不进⾏任何正则化的情况下训练模型,并观察在训练/测试集上的准确性。
parameters = model(train_X, train_Y)
print ("On the training set:")
predictions_train = predict(train_X, train_Y, parameters)
print ("On the test set:")
predictions_test = predict(test_X, test_Y, parameters)
训练精度为94.8%,试验精度为91.5%。这是基线模型(您将观察正则化对该模型的影响)。运⾏以下代码以绘制模型的决策边界。
plt.title("Model without regularization")
axes = a()
axes.set_xlim([-0.75,0.40])
axes.set_ylim([-0.75,0.65])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
注意这⾥会报错:
TypeError Traceback (most recent call last)
D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba(c, alpha)
165 try:
--> 166 rgba = _colors_full_map.cache[c, alpha]
167 except (KeyError, TypeError): # Not in cache, or unhashable.
TypeError: unhashable type: 'numpy.ndarray'
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
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) 4287 # must be acceptable as PathCollection facecolors
-> 4288 colors = _rgba_array(c)
4289 except ValueError:
D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba_array(c, alpha)
266 for i, cc in enumerate(c):
--> 267 result[i] = to_rgba(cc, alpha)
268 return result
D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in to_rgba(c, alpha)
167 except (KeyError, TypeError): # Not in cache, or unhashable.
--> 168 rgba = _to_rgba_no_colorcycle(c, alpha)
169 try:
D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\colors.py in _to_rgba_no_colorcycle(c, alpha)
222 if len(c) not in [3, 4]:
--> 223 raise ValueError("RGBA sequence should have length 3 or 4")
224 if len(c) == 3 and alpha is None:
ValueError: RGBA sequence should have length 3 or 4
During handling of the above exception, another exception occurred:
ValueError Traceback (most recent call last)
<ipython-input-8-1c83d5b7143d> in <module>()
3 axes.set_xlim([-0.75,0.40])
4 axes.set_ylim([-0.75,0.65])
----> 5 plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
~\Downloads\代码作业\第⼆课第⼀周编程作业\assignment1\reg_utils.py in plot_decision_boundary(model, X, y)
322 plt.ylabel('x2')
323 plt.xlabel('x1')
--> 324 plt.scatter(X[0, :], X[1, :], c=y, Spectral)
325 plt.show()
326
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) 3473 vmin=vmin, vmax=vmax, alpha=alpha,
3474 linewidths=linewidths, verts=verts,
-> 3475 edgecolors=edgecolors, data=data, **kwargs)
3476 finally:
3477 ax._hold = washold
D:\ProgramData\Anaconda3\lib\site-packages\matplotlib\__init__.py in inner(ax, *args, **kwargs)
1865 "the Matplotlib list!)" % (label_namer, func.__name__),
1866 RuntimeWarning, stacklevel=2)
-> 1867 return func(ax, *args, **kwargs)
1868
1869 inner.__doc__ = _add_data_doc(inner.__doc__,
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) 4291 raise ValueError("c of shape {} not acceptable as a color "
4292 "sequence for x with size {}, y with size {}"
-> 4293 .format(c.shape, x.size, y.size))
4294 else:
4295 colors = None # use cmap, norm after collection is created
ValueError: c of shape (1, 211) not acceptable as a color sequence for x with size 211, y with size 211
报错
解决为修改函数⾥C的维度。参考本周第⼀个作业。
重新执⾏结果:
⾮正则化模型明显是对训练集过拟合,它是对有噪点的拟合!现在让我们看看减少过拟合的两种技术。
2 - L2 Regularization L2正则化
避免过拟合的标准⽅法称为L2正则化。它包括适当修改你的成本函数,从原来的成本函数(1)到现在的函数(2):
让我们修改你的成本并观察其结果。
练习:使⽤正则化()来执⾏compute_cost_with_regularization(),计算公式(2)所给出的成本。
注意,你必须对w[1], w[2]和w[3]这样做,然后把这三项加起来,再乘以
1 # GRADED FUNCTION: compute_cost_with_regularization
2
3 def compute_cost_with_regularization(A3, Y, parameters, lambd):
4 """
5 Implement the cost function with L2 regularization. 实现公式2的L2正则化计算成本 See formula (2) above.见上式(2)
6
7 Arguments 参数:
8 A3 -- post-activation, output of forward propagation, of shape (output size, number of examples)激活后,正向传播的输出结果,维度为(输出节点数量,训练/测试的数量)
9 Y -- "true" labels vector, of shape (output size, number of examples) 标签向量,与数据⼀⼀对应,维度为(输出节点数量,训练/测试的数量)
10 parameters -- python dictionary containing parameters of the model 包含模型学习后的参数的字典
11
12 Returns:
13 cost - value of the regularized loss function (formula (2))使⽤公式2计算出来的正则化损失的值
14 """
15 m = Y.shape[1]
16 W1 = parameters["W1"]
17 W2 = parameters["W2"]
18 W3 = parameters["W3"]
19
20 cross_entropy_cost = compute_cost(A3, Y) # This gives you the cross-entropy part of the cost 这就给出了代价的交叉熵部分
21
22 ### START CODE HERE ### (approx. 1 line)
23 L2_regularization_cost = (1 / m * lambd / 2 )* (np.sum(np.square(W1)) + np.sum(np.square(W2)) + np.sum(np.square(W3)))
24 ### END CODER HERE ###
25
26 cost = cross_entropy_cost + L2_regularization_cost
27
28 return cost
# GRADED FUNCTION: compute_cost_with_regularization
A3, Y_assess, parameters = compute_cost_with_regularization_test_case()
print("cost = " + str(compute_cost_with_regularization(A3, Y_assess, parameters, lambd = 0.1)))
结果:
当然,因为更改了成本,所以也必须更改反向传播!所有的梯度都要根据这个新成本计算。
练习:实现向后传播所需的更改,以考虑正则化。这些更改只涉及dW1、dW2和dW3。对于每⼀个,你必须加上正则项的梯度
1 # GRADED FUNCTION: backward_propagation_with_regularization
2
3 def backward_propagation_with_regularization(X, Y, cache, lambd):
4 """
5 Implements the backward propagation of our baseline model to which we added an L2 regularization.
6
7 Arguments:
8 X -- input dataset, of shape (input size, number of examples)输⼊数据集,维度为(输⼊节点数量,数据集⾥⾯的数量)
9 Y -- "true" labels vector, of shape (output size, number of examples)标签,维度为(输出节点数量,数据集⾥⾯的数量)
10 cache -- cache output from forward_propagation()来⾃forward_propagation()的cache输出
11 lambd -- regularization hyperparameter, scalarregularization超参数,实数
12
13 Returns:
14 gradients -- A dictionary with the gradients with respect to each parameter, activation and pre-activation variables ⼀个包含了每个参数、激活值和预激活值变量的梯度的字典
15 """
16
17 m = X.shape[1]
18 (Z1, A1, W1, b1, Z2, A2, W2, b2, Z3, A3, W3, b3) = cache
19
20 dZ3 = A3 - Y
21
22 ### START CODE HERE ### (approx. 1 line)
23 dW3 = 1./m * np.dot(dZ3, A2.T) + ((lambd * W3) / m)
24 ### END CODE HERE ###
25 db3 = 1./m * np.sum(dZ3, axis=1, keepdims = True)
26
27 dA2 = np.dot(W3.T, dZ3)
28 dZ2 = np.multiply(dA2, np.int64(A2 > 0))
29 ### START CODE HERE ### (approx. 1 line)
30 dW2 = 1./m * np.dot(dZ2, A1.T) + ((lambd * W2) / m)
31 ### END CODE HERE ###
32 db2 = 1./m * np.sum(dZ2, axis=1, keepdims = True)
33
34 dA1 = np.dot(W2.T, dZ2)
35 dZ1 = np.multiply(dA1, np.int64(A1 > 0))
36 ### START CODE HERE ### (approx. 1 line)
37 dW1 = 1./m * np.dot(dZ1, X.T) + ((lambd * W1) / m)
38 ### END CODE HERE ###
39 db1 = 1./m * np.sum(dZ1, axis=1, keepdims = True)
40
41 gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3,"dA2": dA2,
42 "dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,
43 "dZ1": dZ1, "dW1": dW1, "db1": db1}
44
45 return gradients
# GRADED FUNCTION: backward_propagation_with_regularization
X_assess, Y_assess, cache = backward_propagation_with_regularization_test_case()
grads = backward_propagation_with_regularization(X_assess, Y_assess, cache, lambd = 0.7)
print ("dW1 = "+ str(grads["dW1"]))
print ("dW2 = "+ str(grads["dW2"]))
print ("dW3 = "+ str(grads["dW3"]))
结果:
现在让我们运⾏L2正则化的模型。model()函数将调⽤:
•compute_cost_with_regularization⽽不是compute_cost
•backward_propagation_with_regularization⽽不是backward_propagation
parameters = model(train_X, train_Y, lambd = 0.7)
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)
On the train set:
Accuracy: 0.9383886255924171
On the test set:
Accuracy: 0.93
恭喜,测试集的准确率提⾼到了93%。你救了法国⾜球队!
你不再过度拟合训练数据了。让我们画出决策边界。
plt.title("Model with L2-regularization")
axes = a() #Get Current Axes
axes.set_xlim([-0.75,0.40])
axes.set_ylim([-0.75,0.65])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
结果:
观察:
•您可以使⽤开发集对其进⾏优化,其中的值是⼀个超参数。
•L2正则化使您的决策边界更加平滑。如果拟合太⼤,也可能会“过度平滑”,导致模型具有⾼偏差。
l2正规化的实际作⽤是什么?
l2正则化的前提是,权值较⼩的模型⽐权值较⼤的模型更简单。因此,通过惩罚成本函数中权重的平⽅值,可以将所有权重都变成更⼩的值。它变得太昂贵的成本有⼤的重量!这将产⽣⼀个更平滑的模型,在这个模型中,输出随着输⼊的变化⽽变化得更慢。
(L2正则化依赖于较⼩权重的模型⽐具有较⼤权重的模型更简单这样的假设,因此,通过削减成本函数中权重的平⽅值,可以将所有权重值逐渐改变到到较⼩的值。权值数值⾼的话会有更平滑的模型,其中输⼊变化时输出变化更慢,但是你需要花费更多的时间。)
* *你应该记得* *
——L2-regularization的含义:
成本计算:——正则化的计算项需要添加到成本函数中
反向传播功能:——有额外的术语在梯度对权重矩阵,(在权重矩阵⽅⾯,梯度计算时也要依据正则化来做出相应的计算)
最终权重变⼩(“重量衰减”):——重量推到更⼩的值。(权重被逐渐改变到较⼩的值。)
3 - Dropout 随机删除节点
最后,dropout是⼀种⼴泛使⽤的正则化技术,专门⽤于深度学习。它在每次迭代中随机关闭⼀些神经元。看看这两个视频,看看这意味着什么!
Figure 2 : Drop-out on the second hidden layer. 图2 第⼆层启⽤随机节点删除。
在每次迭代,你关闭(设置为零)⼀层的每个神经元,概率为1 - keep_prob,我们在这保持它的概率为keep_prob(这⾥是50%)。在迭代的前向和后向传播中,缺失的神经元对训练都没有贡献。
Figure 3 : Drop-out on the first and third hidden layers. 图3 在第⼀层和第三层启⽤随机删除.
第⼀层:我们平均关闭40%的神经元。第三层:我们平均关闭20%的神经元。
当你关闭⼀些神经元时,你实际上修改了你的模型。drop-out背后的想法是,在每次迭代中,你训练
⼀个不同的模型,它只使⽤你神经元的⼀个⼦集。有了dropout,你的神经元因此变得对另⼀个特定神经元的激活不那么敏感,因为另⼀个神经元可能在任何时候关闭。
3.1 - Forward propagation with dropout 带有dropout的正向传播
练习:使⽤dropout实现转发。您使⽤了⼀个3层的神经⽹络,并将dropout添加到第⼀层和第⼆层隐藏层。我们不会将dropout应⽤到输⼊层或输出层。
说明:你想关闭第⼀层和第⼆层的⼀些神经元。要做到这⼀点,你需要执⾏4个步骤:
1.在讲座中,我们讨论了使⽤np.random.rand()创建⼀个与a[1]具有相同形状的变量d[1],以随机获取0到1之间的数字。这⾥,您将使⽤向量化实现,因此创建⼀个随机矩阵D [1] =[D [1](1) D[1](2)…与A[1]维数相同的。
2.通过适当地对D[1]中的值进⾏阈值设定,将D[1]的每个条⽬的概率设为0 (1-keep_prob)或概率设为1 (keep_prob)。提⽰:要将矩阵X的所有项设为0(如果项⼩于0.5)或1(如果项⼤于0.5),您可以这样做:X = (X < 0.5)。注意,0和1分别等同于False和True。
3.将A[1]设置为A[1]∗D[1]。(你正在关闭⼀些神经元)。你可以把d[1]看作⼀个掩码,当它与另⼀个矩阵相乘时,它会关闭⼀些值。
4.A[1]除以keep_prob。通过这样做,您可以确保成本的结果仍然具有与没有dropout相同的期望值。(这种技术也被称为反向dropout。)
1 # GRADED FUNCTION: forward_propagation_with_dropout
2
3 def forward_propagation_with_dropout(X, parameters, keep_prob = 0.5):
4 """
5 Implements the forward propagation: LINEAR -> RELU + DROPOUT -> LINEAR -> RELU + DROPOUT -> LINEAR -> SIGMOID.
6 实现具有随机舍弃节点的前向传播。
7 Arguments:
8 X -- input dataset, of shape (2, number of examples)
9 parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3":
10 W1 -- weight matrix of shape (20, 2)
11 b1 -- bias vector of shape (20, 1) 偏向量
12 W2 -- weight matrix of shape (3, 20)
13 b2 -- bias vector of shape (3, 1)
14 W3 -- weight matrix of shape (1, 3)
15 b3 -- bias vector of shape (1, 1)
16 keep_prob - probability of keeping a neuron active during drop-out, scalar 随机删除的概率,实数
17
18 Returns:
19 A3 -- last activation value, output of the forward propagation, of shape (1,1) 最后的激活值,维度为(1,1),正向传播的输出
20 cache -- tuple, information stored for computing the backward propagation 存储了⼀些⽤于计算反向传播的数值的元组
21 """
22
23 np.random.seed(1)
24
25 # retrieve parameters
26 W1 = parameters["W1"]
27 b1 = parameters["b1"]
28 W2 = parameters["W2"]
29 b2 = parameters["b2"]
30 W3 = parameters["W3"]
31 b3 = parameters["b3"]
32
33 # LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOID
34 Z1 = np.dot(W1, X) + b1
35 A1 = relu(Z1)
36 ### START CODE HERE ### (approx. 4 lines) # Steps 1-4 below correspond to the Steps 1-4 described above. 下⾯的步骤1-4对应于上述的步骤1-4。
37 D1 = np.random.rand(A1.shape[0], A1.shape[1]) # Step 1: initialize matrix D1 = np.random.rand(..., ...) 初始化矩阵D1 = np.random.rand(..., ...)
38 D1 = D1<keep_prob # Step 2: convert entries of D1 to 0 or 1 (using keep_prob as the threshold)将D1的值转换为0或1(使⽤keep_prob作为阈值)
39 A1 = A1 * D1 # Step 3: shut down some neurons of A1 的⼀些节点(将它的值变为0或False)
40 A1 = A1 / keep_prob # Step 4: scale the value of neurons that haven't been shut down 缩放未舍弃的节点(不为0)的值
41 ### END CODE HERE ###
42 Z2 = np.dot(W2, A1) + b2
43 A2 = relu(Z2)
44 ### START CODE HERE ### (approx. 4 lines)
45 D2 = np.random.rand(A2.shape[0], A2.shape[1]) # Step 1: initialize matrix D2 = np.random.rand(..., ...) 初始化矩阵D2 = np.random.rand(..., ...)
46 D2 = D2 < keep_prob # Step 2: convert entries of D2 to 0 or 1 (using keep_prob as the threshold) 将D2的值转换为0或1(使⽤keep_prob作为阈值)
47 A2 = A2 * D2 # Step 3: shut down some neurons of A2 舍弃A1的⼀些节点(将它的值变为0或False)舍弃A1的⼀些节点(将它的值变为0或False)
48 A2 = A2 / keep_prob # Step 4: scale the value of neurons that haven't been shut down 缩放未舍弃的节点(不为0)的值
49 ### END CODE HERE ###
50 Z3 = np.dot(W3, A2) + b3
51 A3 = sigmoid(Z3)
52
53 cache = (Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3)
54
55 return A3, cache
# GRADED FUNCTION: forward_propagation_with_dropout
X_assess, parameters = forward_propagation_with_dropout_test_case()
A3, cache = forward_propagation_with_dropout(X_assess, parameters, keep_prob = 0.7)
print ("A3 = " + str(A3))
3.2 - Backward propagation with dropout 使⽤dropout的反向传播
练习:使⽤dropout实现向后传播。与前⾯⼀样,您正在训练⼀个3层⽹络。使⽤存储在缓存中的掩码D[1]和D[2],在第⼀和第⼆隐藏层添加dropout。
说明:带dropout的反向传播实际上很容易。您将必须执⾏两个步骤:
1.在前向传播的过程中,通过对A1施加⼀个掩码D[1],你已经关闭了⼀些神经元。在反向传播中,你必须通过对dA1重新应⽤相同的掩码D[1]来关闭相同的神经元。
2.在前向传播期间,您将A1除以keep_prob。在反向传播中,您将不得不再次将dA1除以keep_prob(微积分解释是,如果⼀个A[1]被keep_prob缩放,那么它的导数dA[1]也被相同的keep_prob缩放)。
# GRADED FUNCTION: backward_propagation_with_dropout
def backward_propagation_with_dropout(X, Y, cache, keep_prob):
"""
Implements the backward propagation of our baseline model to which we added dropout.
Arguments:
X -- input dataset, of shape (2, number of examples)
Y -- "true" labels vector, of shape (output size, number of examples)
cache -- cache output from forward_propagation_with_dropout() 来⾃forward_propagation_with_dropout()的cache输出
keep_prob - probability of keeping a neuron active during drop-out, scalar 随机删除的概率,实数
Returns:
gradients -- A dictionary with the gradients with respect to each parameter, activation and pre-activation variables ⼀个关于每个参数、激活值和预激活变量的梯度值的字典
"""
m = X.shape[1]
(Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3) = cache
dZ3 = A3 - Y
dW3 = 1./m * np.dot(dZ3, A2.T)
db3 = 1./m * np.sum(dZ3, axis=1, keepdims = True)
dA2 = np.dot(W3.T, dZ3)
### START CODE HERE ### (≈ 2 lines of code)
dA2 = dA2 * D2 # Step 1: Apply mask D2 to shut down the same neurons as during the forward propagation使⽤正向传播期间相同的节点,舍弃那些关闭的节点(因为任何数乘以0或者False都为0或者False) dA2 = dA2 / keep_prob # Step 2: Scale the value of neurons that haven't been shut down 缩放未舍弃的节点(不为0)的值
### END CODE HERE ###
dZ2 = np.multiply(dA2, np.int64(A2 > 0))
dW2 = 1./m * np.dot(dZ2, A1.T)
db2 = 1./m * np.sum(dZ2, axis=1, keepdims = True)
dA1 = np.dot(W2.T, dZ2)
### START CODE HERE ### (≈ 2 lines of code)
dA1 = dA1 * D1 # Step 1: Apply mask D1 to shut down the same neurons as during the forward propagation 使⽤正向传播期间相同的节点,舍弃那些关闭的节点(因为任何数乘以0或者False都为0或者False) dA1 = dA1 / keep_prob # Step 2: Scale the value of neurons that haven't been shut down 缩放未舍弃的节点(不为0)的值
### END CODE HERE ###
dZ1 = np.multiply(dA1, np.int64(A1 > 0))
dW1 = 1./m * np.dot(dZ1, X.T)
db1 = 1./m * np.sum(dZ1, axis=1, keepdims = True)
gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3,"dA2": dA2,
"dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,
"dZ1": dZ1, "dW1": dW1, "db1": db1}
return gradients
X_assess, Y_assess, cache = backward_propagation_with_dropout_test_case()
gradients = backward_propagation_with_dropout(X_assess, Y_assess, cache, keep_prob = 0.8)
print ("dA1 = " + str(gradients["dA1"]))
print ("dA2 = " + str(gradients["dA2"]))
结果:
现在让我们运⾏带有dropout (keep_prob = 0.86)的模型。这意味着在每次迭代中,以24%的概率关闭第1层和第2层的每个神经元。函数model()现在将调⽤:
•forward_propagation_with_dropout⽽不是forward_propagation。
•backward_propagation_with_dropout⽽不是backward_propagation。
parameters = model(train_X, train_Y, keep_prob = 0.86, learning_rate = 0.3)
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)
结果:
dropout⼲的很好!测试准确度再次提⾼(到95%)!你的模型没有过度拟合训练集,⽽且在测试集上做得很好。法国⾜球队将永远感谢你!
运⾏下⾯的代码来绘制决策边界。
plt.title("Model with dropout")
axes = a()
axes.set_xlim([-0.75,0.40])
axes.set_ylim([-0.75,0.65])
plot_decision_boundary(lambda x: predict_dec(parameters, x.T), train_X, train_Y)
注意:
•在使⽤dropout时,⼀个常见的错误是在训练和测试中都使⽤它。您应该只在训练中使⽤dropout(随机删除节点)。
•深度学习框架,如tensorflow, PaddlePaddle, keras或caffe都带有dropout层实现。不要紧张——你很快就会学到其中⼀些框架。
关于dropout你应该记住的是:**
- dropout是⼀种正则化技术。
-你只在训练期间使⽤dropout。在测试期间不要使⽤dropout(随机删除节点)。
-在正向传播和反向传播期间应⽤dropout。
-在训练期间,⽤keep_prob对每个dropout层进⾏划分,以保持激活的期望值相同。例如,如果keep_prob是0.5,那么我们将平均关闭⼀半节点,因此输出将按0.5进⾏缩放,因为只有剩下的⼀半对解决
⽅案有贡献。除以0.5等于乘以2。因此,输出现在具有相同的期望值。您可以检查,即使在keep_prob的值不是0.5时,这个⽅法也可以⼯作。
4 - Conclusions 结论
以下是我们三个模型的结果:
注意,正则化会影响训练集的性能!这是因为它限制了⽹络过度适应训练集的能⼒。但由于它最终提供了更好的测试准确性,它有助于您的系统。
恭喜你完成了这项任务!以及法国⾜球的⾰命。:-)
**我们希望你从这个笔记本中记住的东西**:
-正则化将帮助你减少过拟合。
-正规化将使你的权重值降低。
- L2正则化和Dropout正则化是两种⾮常有效的正则化技术。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论