- 不要抄作业!
- 我只是把思路整理了,供个人学习。
- 不要抄作业!
本周的作业分了3部分:
- 初始化参数
- 正则化(L2、dropout)
- 梯度检验
part1:Initialization
主要说明的不同的初始化对迭代的影响。
首先,模型函数是这样的:
1 | def model(X, Y, learning_rate = 0.01, num_iterations = 15000, print_cost = True, initialization = "he"): |
1. Zero Initialization
把参数全都置位0,结果是显而易见的,就是没有任何变化。
2. Random initialization
把W参数随机化了,但是乘以10倍系数,所以导致初始化的参数太大,收敛速度很慢
1 | def initialize_parameters_random(layers_dims): |
结果一般般
3. He initialization
把W参数随机化,但是乘上系数 sqrt(2./layers_dims[l-1])
1 | def initialize_parameters_he(layers_dims): |
结果非常理想。
Part 2:Regularization
数据集:
模型函数:
1 | def model(X, Y, learning_rate = 0.3, num_iterations = 30000, print_cost = True, lambd = 0, keep_prob = 1): |
没有使用正则化时,效果:
L2 正则
计算代价函数
$$J_{regularized} = \small \underbrace{-\frac{1}{m} \sum\limits_{i = 1}^{m} \large{(}\small y^{(i)}\log\left(a^{[L] (i)}\right) + (1-y^{(i)})\log\left(1- a^{[L] (i)}\right) \large{)} }_\text{cross-entropy cost} + \underbrace{\frac{1}{m} \frac{\lambda}{2} \sum\limits_l\sum\limits_k\sum\limits_j W_{k,j}^{[l]2} }_\text{L2 regularization cost} $$
公式已经给了,只要加上后面那一项就可以了
使用np.sum(np.square(Wl))
来计算$\sum\limits_k\sum\limits_j W_{k,j}^{[l]2}$
1 | # GRADED FUNCTION: compute_cost_with_regularization |
计算反向传播函数
在$dW$上加上了正则项$\frac{\lambda}{m} W$
1 | # GRADED FUNCTION: backward_propagation_with_regularization |
加上L2正则项后,效果很明显:
dropout
在每一次迭代中,都随机删除一定概率的neurons。
1. Forward propagation with dropout
分4步:
- 每一层的$d^{[l]}$对应每一层的$a^{[l]}$,因为有m个样本,所以就有$D^{[1]} = [d^{1} d^{1} … d^{1}] $of the same dimension as $A^{[1]}$.使用np.random.rand(n,m)
- 将$D^{[l]}$布尔化, $ < keepprob$ 分为 1和0
- Set $A^{[1]}$ to $A^{[1]} * D^{[1]}$.
- Divide $A^{[1]}$ by
keep_prob
.
记得用cache把每一层的D都记录下来
1 | # GRADED FUNCTION: forward_propagation_with_dropout |
2. Backward propagation with dropout
- reapplying the same mask $D^{[1]}$ to
dA1
. - divide
dA1
bykeep_prob
反向传播的时候,让之前的删除的neurons依旧归0,然后也要除以keepprob,因为dA = np.dot(W.T, dZ)
,并没有重复除以过系数。
1 | # GRADED FUNCTION: backward_propagation_with_dropout |
最终结果,也还不错:
注意:
- dropout也是正则化的一种
- 训练的时候用,测试的时候不要用
- 在正向传播和反向传播中都要用
Part3:Gradient Checking
首先写了一维的checking
1 | # GRADED FUNCTION: forward_propagation |
1 | # GRADED FUNCTION: backward_propagation |
根据公式:
$$ difference = \frac {\mid\mid grad - gradapprox \mid\mid_2}{\mid\mid grad \mid\mid_2 + \mid\mid gradapprox \mid\mid_2} $$
步骤是:
- $\theta^{+} = \theta + \varepsilon$
- $\theta^{-} = \theta - \varepsilon$
- $J^{+} = J(\theta^{+})$
- $J^{-} = J(\theta^{-})$
- $gradapprox = \frac{J^{+} - J^{-}}{2 \varepsilon}$
1 | def gradient_check(x, theta, epsilon = 1e-7): |
在N维的空间中,
1 | def forward_propagation_n(X, Y, parameters): |
1 | def backward_propagation_n(X, Y, cache): |
这个时候,给了两个函数,可以在字典和向量结构相互转换,也就是要计算$\theta^{+}$时,把字典转为向量会比较好计算。
1 | dictionary_to_vector() |
J_plus[i]就是向量中的每一个元素,也就是W,b展开之后的每一项元素
- To compute
J_plus[i]
:- Set $\theta^{+}$ to
np.copy(parameters_values)
- Set $\theta^{+}_i$ to $\theta^{+}_i + \varepsilon$
- Calculate $J^{+}_i$ using to
forward_propagation_n(x, y, vector_to_dictionary(
$\theta^{+}$))
.
- Set $\theta^{+}$ to
- To compute
J_minus[i]
: do the same thing with $\theta^{-}$ - Compute $gradapprox[i] = \frac{J^{+}_i - J^{-}_i}{2 \varepsilon}$
代码如下,记住 thetaplus是一个(n,1)的向量,循环计算每一个参数的gradapprox,再和原本的grad比较:
1 | # GRADED FUNCTION: gradient_check_n |
注意:
梯度检验太慢,不要在训练的时候运行,你运行只是为了保证你的算法是正确的。