注意np.zeros(shape)中的shape是有括号的形式。
1 | W1 = np.random.randn(n_h,n_x)*0.01 |
python中,//为整除符号,取整数部分。
1 | >>> 1/2 |
算法步骤
- 初始化参数
我们使用layer_dims来存储每一层单元的数量。 如layer_dims = [2,4,1] : 第一个是输入层有两个单元,第二个是隐藏层有4个单元,第三个是输出层有1个单元,因此W1大小为 (4,2), b1 为 (4,1),W2 为 (1,4) , b2 为 (1,1)。
1 |
|
- 前向传播模块
首先实现线性前向传播
1 | def linear_forward(A, W, b): |
加上激活函数
1 | def linear_activation_forward(A_prev, W, b, activation): |
实现 L 层神经网络,堆叠使用 RELU 的 linear_activation_forward 函数 L−1 次, 最后堆叠一个使用 SIGMOID 的 linear_activation_forward 函数。
1 |
|
- 计算损失函数
1 | def compute_cost(AL, Y): |
- 反向传播模块
对于层$l$的线性部分 $Z^{[l]} = W^{[l]} A^{[l-1]} + b^{[l]}$。
假设已经知道 $dZ^{[l]} = \frac{\partial \mathcal{L} }{\partial Z^{[l]}}$,计算:
$$ dW^{[l]} = \frac{\partial \mathcal{L} }{\partial W^{[l]}} = \frac{1}{m} dZ^{[l]} A^{[l-1] T} $$
$$ db^{[l]} = \frac{\partial \mathcal{L} }{\partial b^{[l]}} = \frac{1}{m} \sum_{i = 1}^{m} dZ^{[l][i]}$$
$$ dA^{[l-1]} = \frac{\partial \mathcal{L} }{\partial A^{[l-1]}} = W^{[l] T} dZ^{[l]} $$
其中,$dZ^{[l]}: (n^{[l]},m)$、$A^{[l-1]}: (n^{[l-1]},m)$、$W^{[l]}: (n^{[l]},n^{[l-1]})$。
1 |
|
下面求$dZ^{[l]}$,对于激活函数部分
$$dZ^{[l]} = dA^{[l]} * g’(Z^{[l]})$$
1 |
|
堆叠L层反向传播。首先初始化反向传播,我们知道在第 L 层,$A^{[L]} = \sigma(Z^{[L]})$,要计算$Z^{[L]}$关于激活函数的导数,首先要计算出$A^{[l]}$关于损失函数的导数$ dA^{[L]} = \frac{\partial \mathcal{L}}{\partial A^{[L]}}$ ,以作为def linear_activation_backward(dA, cache, activation)的初值,之后的$ dA^{[L-1]} \dots dA^{[1]}$均可由此函数递推出来。
$ dA^{[L]} $计算方法如下:dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))
1 |
|
- 更新参数
1 |
|
- 预测函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def predict(X, y, parameters):
m = X.shape[1]
n = len(parameters) // 2 # number of layers in the neural network
p = np.zeros((1,m))
# Forward propagation
probas, caches = L_model_forward(X, parameters)
# convert probas to 0/1 predictions
for i in range(0, probas.shape[1]):
if probas[0,i] > 0.5:
p[0,i] = 1
else:
p[0,i] = 0
print("Accuracy: " + str(np.sum((p == y)/m)))
return p
附录1:SIGMOID和RELU函数实现
1 | def sigmoid(Z): |
附录2:SIGMOID和RELU反向传播函数实现
relu_backward中dZ[Z <= 0] = 0这一步不是很懂,不应该是大于等于0时导数为1吗?
1 | def relu_backward(dA, cache): |