目录
整理所涉及的维度
注:输入样本X.shape=(12288,209)
第1隐藏层的节点数:n¹;第2隐藏层的节点数:n²;...
W | b | Z | shape of Z | |
第1层 | (n¹ ,12288) | (n¹ ,1) | Z¹ = W¹X + b¹ | (n¹ ,209) |
第2层 | (n² ,12288) | (n² ,1) | Z² = W²A¹ + b² | (n² ,209) |
第3层 | (n³ ,12288) | (n³ ,1) | Z³ = W³A² + b³ | (n³ ,209) |
... | ... | ... | ... | ... |
开始构建多层网络
接下来的多隐藏层神经网络是什么结构?
- L层神经网络(L是指不包含输入层的个数。换句话说L层神经网络实际上有L+1层)
- 第0层为输入层。第1~L层需要利用激活函数计算得出。其中第2-(L-1)层激活函数使用的是relu;第L层激活函数使用的是sigmoid。
初始化网络的节点
initialize_parameters_deep(layers_dims): """ 初始化每层的参数矩阵。利用循环(for i in len(layers_dims))对参数进行创建,并初始化。其中偏向量b初始化为0。 eg:=》layers_dims={2,3,6}。 意:输出层的节点个数为2,隐藏层节点个数为3,输出层节点个数为6""" 参数: layers_dims。里面包含每层的节点个数。 可利用该list参数得到神经网络层数L=len(layers_dims)-1。 返回: parameter。已初始化的参数。共有(len(layers_dims)-1)*2个。
前向传播
前向传播分为两部分:线性部分(linear_forward)、激活部分(activation_forward)。
1次线性部分计算 + 1次激活部分计算 = 1层的前向传播。因此,一次前向传播,有L次1层的前向传播。
该多隐藏层神经网络在内层使用relu激活函数,在输出层使用sigmoid激活函数。因此,实现多隐藏层的前向传播需要单独构建算法:利用循环实现L-1次 relu激活,最后实现1次sigmoid激活函数。
linear_forward(A_prev, W, b): """ 前向传播的线性部分。直接利用公式计算Z值(亦称预激活参数)。 参数: A_prev -- 本层前向传播的输入(输入层值X or前一层前向传播的输出值A_prev)。 W -- 前一层到本层的权重矩阵。计算Z值所需。 b -- 本层的偏向量。 返回: Z -- 待激活的参数。亦称预激活参数。 linear_cache -- list类型。(A_prev、W、b)。保存本层前向传播线性传播部分计算Z所使用的所有矩阵。 """
linear_activation_forward(A_prev, W, b, activation): """ 前向传播的激活部分。 首先利用参数activation得到本层使用的激活函数,接着调用【linear_forward()】函数得到Z(待激活参数),然后调用对应的激活函数得到本层的激活值。 参数: A_prev -- 本层前向传播的输入。 W -- 前一层到本层的权重矩阵。 b -- 本层的偏向量。 activation -- 本层所使用的激活函数名,字符串类型。【"sigmoid" | "relu"】 返回: A -- 本层激活函数的输出,也称为激活后的值。 cache -- list类型。(linear_cache,activation_cache)= ((A_pre、W、b),Z) """
解释说明:激活函数sigmoid()、relu()的解释
sigmoid() - 利用公式计算得到激活后的值A=1/(1+np.exp(-Z))。参数:Z。返回:A,Z
relu() - 利用公式计算得到激活后的值A=np.maximum(0,Z)。参数:Z。返回:A,Z
L_model_forward(X, parameters):
"""
构建适用于多隐藏层神经网络的前向传播算法。
一共L层。计算L-1层【LINEAR->RELU】前向传播;再计算1层【LINEAR->SIGMOID】前向传播。
算法:直接循环调用L-1次【linear_activation_forward()】,输入参数为relu激活函数。再单独调一次【linear_activation_forward()】,输入参数为sigmoid激活函数。
记录【linear_activation_forward()】方法返回的返回值——L个cache。
参数:
X -- 输入层的数据集。X.shape (输入层的节点数量, 样本数)。
parameters -- 多层神经网络模型的参数。【initialize_parameters_deep()】算法的输出。
利用parameters得到神经网络模型的层数L = len(parameters)//2。
利用parameters得到神经网络模型使用的权值矩阵W和偏向量b。
返回:
AL -- 输出层的值。亦称预测值。
caches -- list类型。保存每次调用【linear_activation_forward()】返回的cache值。
(((A_pre、W、b),Z),((A_pre、W、b),Z),...) # 仅仅示例结构。
"""
计算误差
compute_cost(AL, Y):
"""
计算预测值与实际值之间的损失。
参数:
AL -- 通过模型计算的标签(预测值)。【L_model_forward()】的输出。
Y -- 实际样本集的样本标签。
返回:
cost -- 损失熵。利用公式得出。 !!!实现数学公式时注意括号!!!
"""
后向传播
(有不懂的计算过程多看看西瓜书,多动笔推导。包括一些公式推导。知道来源有助于理解)
后向传播同样也分为两部分:线性部分(linear_backward),激活部分(linear_activation_backward)。
前两部分算法是搭建多隐藏层神经网络后向传播的基础。
linear_backward(dZ, linear_cache): """ 线性部分。在方法中可以计算出dW、db、dA_prev。 利用数学推导(详细见西瓜书P101+吴恩达深度学习课程1 4.2小节视频)得到三个参数偏导具体的计算公式。 参数: dZ -- 本层Z的梯度。 linear_cache -- 本层前向传播时的相关矩阵。【linear_forward()】方法的输出(A_prev,W,b). 返回: dA_prev -- 前一层激活值A_pre的梯度。 dW -- 本层权值的梯度。 db -- 本层偏向量的梯度。 """
linear_activation_backward(dA, cache, activation): """ 激活部分。利用参数activation得到本层利用的激活函数。再调用对应的激活函数的梯度计算函数【relu_backward() |sigmoid_backward()】计算Z的梯度dZ。得到本层的dZ后,接着调用【linear_backward()】得到本层的参数梯度dW、db,以及前一层的激活值梯度dA_pre。再将本方法计算所有梯度(dA_prev,dW,db)进行返回。 参数: dA -- 本层激活值的梯度。 cache -- list类型。本层前向传播时【linear_activation_forward】的返回值。 activation -- 本层的激活函数。string: "sigmoid" or "relu"。 返回: dA_prev - 前一层的激活值的梯度。 dW - 本层权值的梯度。 db - 本层偏向量的梯度。 """
解释说明:激活函数的求偏导函数sigmoid_backward()、relu_backward()的解释
sigmoid_backward() - 利用公式计算偏导dZ=dA * g(z) * (1-g(z))。参数:dA, activation_cache(实际是Z)。返回:dZ。
relu_backward() - 利用公式计算偏导dZ=0|1。参数:dA, activation_cache(实际是Z)。返回:dZ。
L_model_backward(AL, Y, caches): """ 搭建多隐藏层神经网络的后向传播。 算法:与前向传播相似。共L层后向传播,其中L-1层【LINEAR->RELU】,1层【LINEAR->SIGMOID】,但计算顺序相反。先【LINEAR->SIGMOID】,再【LINEAR->RELU】。 ★由于输出层的特殊性————没有后向传播激活部分【linear_activation_backward()】需要的传入参数dA。之所以在激活部分如此设计,普遍性————每层都有dA。因此,需要单独计算一次输出层的激活值的梯度,但用符号dAL表示。dAL由对损失函数L(AL,Y)求导计算得到。 算法:得到dAL后,取出【L_model_forward()】输出的caches(注:索引为0~(L-1))。遍历得到每一个cache,再作为参数传入【linear_activation_backward()】进行计算每层的梯度。 ★依旧是由于输出层的特殊性——激活函数使用sigmoid。单独计算一次第L层(输出层)的梯度。 算法:得到输出层的梯度后,存入grads字典。再由于剩余隐藏层的普适性。利用循环,计算1~(L-1)层的梯度。得到梯度存入grads字典。 参数: AL -- 模型输出值(预测值)。 Y -- 样本真实的标签向量 (0|1)。 caches -- 多层神经网络前向传播后【L_model_forward()】的返回值caches。 利用caches可以得到模型的层数L = len(caches)。 利用caches可以得到模型的权值W、偏向量b、激活值、预激活值。 返回: grads -- 存储梯度的字典 grads["dA" + str(l)] = ... grads["dW" + str(l)] = ... grads["db" + str(l)] = ... """
更新参数
update_parameters(parameters, grads, learning_rate): """ 使用梯度下降法优化的参数。 参数: parameters -- 包含本次训练的运行的参数字典。 grads -- 包含本次训练后,所计算的梯度,【L_model_backward】的输出。 learning_rate -- 学习率。 返回: parameters -- 返回优化后的参数字典 parameters["W" + str(l)] = ... parameters["b" + str(l)] = ... """
整合多层网络训练模型
L_layer_model(X,Y,layers_dims,learning_rate=0.0075,num_iterations=3000,print_cost=False,isPlot=True): """ 实现L层神经网络模型。将前面步骤结合到一起。 参数: X - 输入的数据,维度为(n_x,例子数)。 Y - 标签,向量,【0|1】,维度为(1,数量)。 layers_dims - 每层的节点数,维度为(1,L+1)。 learning_rate - 学习率。 num_iterations - 迭代的次数。 print_cost - 是否打印成本值。 isPlot - 是否绘制出学习曲线。 返回: parameters - 模型训练好的参数。 """