Bootstrap

【DeepLearning.ai实验笔记】课程1-week4:多隐藏层神经网络搭建

目录

整理所涉及的维度

开始构建多层网络

初始化网络的节点

前向传播

计算误差

后向传播

        更新参数

整合多层网络训练模型


整理所涉及的维度

注:输入样本X.shape=(12288,209)

       第1隐藏层的节点数:n¹;第2隐藏层的节点数:n²;...

WbZshape 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 - 模型训练好的参数。
        """
;