Course 1 - 神经网络和深度学习 - 第四周作业
1、本周重点难点
- 重点:在本次教程中,我们要构建两个神经网络,一个是构建两层的神经网络,一个是构建多层的神经网络,多层神经网络的层数可以自己定义。
- 难点:[LINEAR-> ACTIVATION]转发函数
比如我有一个多层的神经网络
1、结构是输入层->隐藏层->隐藏层->···->隐藏层->输出层;
2、在每一层中,我会首先计算Z = np.dot(W,A) + b,这叫做【linear_forward】;
3、然后再计算A = relu(Z) 或者 A = sigmoid(Z),这叫做【linear_activation_forward】
4、合并起来就是这一层的计算方法
所以每一层的计算都有两个步骤,先是计算Z,再计算A,你也可以参照下图:
2、步骤
1.初始化网络参数
2.前向传播
2.1 计算一层的中线性求和的部分
2.2 计算激活函数的部分(ReLU使用L-1次,Sigmod使用1次)
2.3 结合线性求和与激活函数
3.计算误差
4.反向传播
4.1 线性部分的反向传播公式
4.2 激活函数部分的反向传播公式
4.3 结合线性部分与激活函数的反向传播公式
5.更新参数
注意:对于每个前向函数,都有一个相应的后向函数。 这就是为什么在我们的转发模块的每一步都会在cache中存储一些值,cache的值对计算梯度很有用, 在反向传播模块中,我们将使用cache来计算梯度。
看看上面的图,z[1]…z[n]就是存在cache的值,因为要通过z[l]才能计算dw[l],db[l]。
3、开始
3.0下载,准备软件包
下载资料,提取码:xx1w
import numpy as np
import h5py
import matplotlib.pyplot as plt
import testCases #参见资料包,或者在文章底部copy
from dnn_utils import sigmoid, sigmoid_backward, relu, relu_backward #参见资料包
import lr_utils #参见资料包,或者在文章底部copy
为了和我的数据匹配,你需要指定随机种子
np.random.seed(1)
3.2 初始化网络参数
下面是一个两层的神经网络结构,跟第三周的作业一样,结构都是:线性->ReLU函数->线性->sigmod函数
def initialize_parameters(n_x,n_h,n_y):
"""
此函数是为了初始化两层网络参数而使用的函数。
参数:
n_x - 输入层节点数量
n_h - 隐藏层节点数量
n_y - 输出层节点数量
返回:
parameters - 包含你的参数的python字典:
W1 - 权重矩阵,维度为(n_h,n_x)
b1 - 偏向量,维度为(n_h,1)
W2 - 权重矩阵,维度为(n_y,n_h)
b2 - 偏向量,维度为(n_y,1)
"""
W1 = np.random.randn(n_h, n_x) * 0.01
b1 = np.zeros((n_h, 1))
W2 = np.random.randn(n_y, n_h) * 0.01
b2 = np.zeros((n_y, 1))
#使用断言确保我的数据格式是正确的
assert(W1.shape == (n_h, n_x))
assert(b1.shape == (n_h, 1))
assert(W2.shape == (n_y, n_h))
assert(b2.shape == (n_y, 1))
parameters = {
"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2}
return parameters
测试:
print("==============测试initialize_parameters==============")
parameters = initialize_parameters(3,2,1)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
结果:
测试完就能注释掉了,测试只是为了保证不出错
通过视频可知:
w[l]的维度是(n[l],n[l-1]), b[l]的维度是(n[l-1],1) , z[ l ] (n[l],1)
上面两层的神经网络结构,一层是隐藏层,一层是输出层
基本就是这样:
矩阵计算方法:
多层的神经网络初始化
# 初始化多层网络参数而使用的函数
def initialize_parameters_deep(layers_dims):
# 参数:layers_dims-包含我们网络中每个图层的节点数量的列表
np.random.seed(3)
parameters = {
}
L = len(layers_dims)
# 还记得吴老师说,每一层遍历是需要用for的
for l in range(1,L):
parameters["w"+str(l)] = np.random.randn(layers_dims[l],layers_dims[l-1])/np.sqrt(layers_dims[l-1])
parameters["b"+str(l)] = np.zeros((layers_dims[l],1))
# 没有弄懂为什么wl那个要除np.sqrt(layers_dims[l-1])
assert (parameters["w"+str(l)].shape == (layers_dims[l],layers_dims[l-1]))
assert (parameters["b"+str(l)].shape == (layers_dims[l],1))
return parameters
测试
#测试initialize_parameters_deep
print("==============测试initialize_parameters_deep==============")
layers_dims = [5,4,3]
parameters = initialize_parameters_deep(layers_dims)
print("W1 = " + str(parameters["w1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + st