• L1W4作业1 逐步构建你的深度神经网络


    逐步构建你的深度神经网络

    欢迎来到第4周作业的第1部分!在此之前你已经训练了一个2层的神经网络(只有一个隐藏层)。本周,你将学会构建一个任意层数的深度神经网络!

    • 在此作业中,你将实现构建深度神经网络所需的所有函数。
    • 在下一个作业中,你将使用这些函数来构建一个用于图像分类的深度神经网络。

    完成此任务后,你将能够:

    • 使用ReLU等非线性单位来改善模型
    • 建立更深的神经网络(具有1个以上的隐藏层)
    • 实现一个易于使用的神经网络类

    符号说明

    • 上标 [ l ] [l] [l]表示与 l t h l^{th} lth层相关的数量。
      - 示例: a [ L ] a^{[L]} a[L]是$L^{th} $层的激活。 $W^{[L]} 和 和 b{[L]}$是$L{th}$层参数。
    • 上标$(i) KaTeX parse error: Undefined control sequence: \- at position 21: …{th}示例相关的数量。 \̲-̲ 示例:x(i ) 是第 )是第 )是第i^{th}$ 的训练数据。
    • 下标 i i i 表示 i t h i^{th} ith的向量。
      - 示例: a i [ l ] a^{[l]}_i ai[l] 表示 l t h l^{th} lth 层激活的 i t h i^{th} ith 输入。

    让我们开始吧!

    1 安装包

    让我们首先导入作业过程中需要的所有包。

    • numpy是Python科学计算的基本包。
    • matplotlib是在Python中常用的绘制图形的库。
    • dnn_utils为此笔记本提供了一些必要的函数。
    • testCases提供了一些测试用例来评估函数的正确性
    • np.random.seed(1)使所有随机函数调用保持一致。 这将有助于我们评估你的作业,请不要改变seed。

    In [1]:

    cd ../input/deeplearning46278
    /home/kesci/input/deeplearning46278
    
    • 1
    • 2

    In [2]:

    import numpy as np
    import h5py
    import matplotlib.pyplot as plt
    from testCases_v2 import *
    from dnn_utils_v2 import sigmoid, sigmoid_backward, relu, relu_backward
    
    %matplotlib inline
    plt.rcParams['figure.figsize'] = (5.0, 4.0) # set default size of plots
    plt.rcParams['image.interpolation'] = 'nearest'
    plt.rcParams['image.cmap'] = 'gray'
    
    %load_ext autoreload
    %autoreload 2
    
    np.random.seed(1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2 作业大纲

    为了构建你的神经网络,你将实现几个“辅助函数”。这些辅助函数将在下一个作业中使用,用来构建一个两层神经网络和一个L层的神经网络。你将实现的每个函数都有详细的说明,这些说明将指导你完成必要的步骤。此作业的大纲如下:

    • 初始化两层的网络和L层的神经网络的参数。
    • 实现正向传播模块(在下图中以紫色显示)。
      - 完成模型正向传播步骤的LINEAR部分( Z [ l ] Z^{[l]} Z[l])。
      - 提供使用的ACTIVATION函数(relu / Sigmoid)。
      - 将前两个步骤合并为新的[LINEAR-> ACTIVATION]前向函数。
      - 堆叠[LINEAR-> RELU]正向函数L-1次(第1到L-1层),并在末尾添加[LINEAR-> SIGMOID](最后的L层)。这合成了一个新的L_model_forward函数。
    • 计算损失。
    • 实现反向传播模块(在下图中以红色表示)。
      - 完成模型反向传播步骤的LINEAR部分。
      - 提供的ACTIVATE函数的梯度(relu_backward / sigmoid_backward)
      - 将前两个步骤组合成新的[LINEAR-> ACTIVATION]反向函数。
      - 将[LINEAR-> RELU]向后堆叠L-1次,并在新的L_model_backward函数中后向添加[LINEAR-> SIGMOID]
    • 最后更新参数。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Py4aQ89D-1662895428829)(L1W4%E4%BD%9C%E4%B8%9A1%20%E9%80%90%E6%AD%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C.assets/960.png)]

    图1

    注意:对于每个正向函数,都有一个对应的反向函数。 这也是为什么在正向传播模块的每一步都将一些值存储在缓存中的原因。缓存的值可用于计算梯度。 然后,在反向传导模块中,你将使用缓存的值来计算梯度。 此作业将指导说明如何执行这些步骤。

    3 初始化

    首先编写两个辅助函数用来初始化模型的参数。 第一个函数将用于初始化两层模型的参数。 第二个将把初始化过程推广到L层模型上。

    3.1 2层神经网络

    练习:创建并初始化2层神经网络的参数。

    说明

    • 模型的结构为:LINEAR -> RELU -> LINEAR -> SIGMOID
    • 随机初始化权重矩阵。 确保准确的维度,使用np.random.randn(shape)* 0.01
    • 将偏差初始化为0。 使用np.zeros(shape)

    In [3]:

    # GRADED FUNCTION: initialize_parameters
    
    def initialize_parameters(n_x, n_h, n_y):
        """
        Argument:
        n_x -- size of the input layer
        n_h -- size of the hidden layer
        n_y -- size of the output layer
        
        Returns:
        parameters -- python dictionary containing your parameters:
                        W1 -- weight matrix of shape (n_h, n_x)
                        b1 -- bias vector of shape (n_h, 1)
                        W2 -- weight matrix of shape (n_y, n_h)
                        b2 -- bias vector of shape (n_y, 1)
        """
        
        np.random.seed(1)
        
    ### START CODE HERE ### (≈ 4 lines of code)
        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))
        ### END CODE HERE ###
        
        
        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    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    In [4]:

    parameters = initialize_parameters(2,2,1)
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))
    W1 = [[ 0.01624345 -0.00611756]
     [-0.00528172 -0.01072969]]
    b1 = [[0.]
     [0.]]
    W2 = [[ 0.00865408 -0.02301539]]
    b2 = [[0.]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    预期输出:
    W1 = [[ 0.01624345 -0.00611756]
    [-0.00528172 -0.01072969]]
    b1 = [[0.]
    [0.]]
    W2 = [[ 0.00865408 -0.02301539]]
    b2 = [[0.]]

    3.2 L层神经网络

    更深的L层神经网络的初始化更加复杂,因为存在更多的权重矩阵和偏差向量。 完成 initialize_parameters_deep后,应确保各层之间的维度匹配。 回想一下, n [ l ] n^{[l]} n[l]是l层中的神经元数量。 因此,如果我们输入的 X 的大小为(12288,209)(以m=209为例),则:

    Shape of WShape of bActivationShape of Activation
    Layer 1 ( n [ 1 ] , 12288 ) (n^{[1]},12288) (n[1],12288) ( n [ 1 ] , 1 ) (n^{[1]},1) (n[1],1) Z [ 1 ] = W [ 1 ] X + b [ 1 ] Z^{[1]} = W^{[1]} X + b^{[1]} Z[1]=W[1]X+b[1] ( n [ 1 ] , 209 ) (n^{[1]},209) (n[1],209)
    Layer 2 ( n [ 2 ] , n [ 1 ] ) (n^{[2]}, n^{[1]}) (n[2],n[1]) ( n [ 2 ] , 1 ) (n^{[2]},1) (n[2],1) Z [ 2 ] = W [ 2 ] A [ 1 ] + b [ 2 ] Z^{[2]} = W^{[2]} A^{[1]} + b^{[2]} Z[2]=W[2]A[1]+b[2] ( n [ 2 ] , 209 ) (n^{[2]}, 209) (n[2],209)
    Layer L-1 ( n [ L − 1 ] , n [ L − 2 ] ) (n^{[L-1]}, n^{[L-2]}) (n[L1],n[L2]) ( n [ L − 1 ] , 1 ) (n^{[L-1]}, 1) (n[L1],1) Z [ L − 1 ] = W [ L − 1 ] A [ L − 2 ] + b [ L − 1 ] Z^{[L-1]} = W^{[L-1]} A^{[L-2]} + b^{[L-1]} Z[L1]=W[L1]A[L2]+b[L1] ( n [ L − 1 ] , 209 ) (n^{[L-1]}, 209) (n[L1],209)
    Layer L ( n [ L ] , n [ L − 1 ] ) (n^{[L]}, n^{[L-1]}) (n[L],n[L1]) ( n [ L ] , 1 ) (n^{[L]}, 1) (n[L],1) Z [ L ] = W [ L ] A [ L − 1 ] + b [ L ] Z^{[L]} = W^{[L]} A^{[L-1]} + b^{[L]} Z[L]=W[L]A[L1]+b[L] ( n [ L ] , 209 ) (n^{[L]}, 209) (n[L],209)

    当我们在python中计算 W X + b W X + b WX+b时,使用广播,比如:

    W = [ j k l m n o p q r ]        X = [ a b c d e f g h i ]        b = [ s t u ] (2) W = [jklmnopqr]\;\;\; X = [abcdefghi] \;\;\; b =[stu]\tag{2} W= jmpknqlor X= adgbehcfi b= stu (2)

    Then W X + b WX+b WX+b will be:

    W X + b = [ ( j a + k d + l g ) + s ( j b + k e + l h ) + s ( j c + k f + l i ) + s ( m a + n d + o g ) + t ( m b + n e + o h ) + t ( m c + n f + o i ) + t ( p a + q d + r g ) + u ( p b + q e + r h ) + u ( p c + q f + r i ) + u ] (3) WX + b = [(ja+kd+lg)+s(jb+ke+lh)+s(jc+kf+li)+s(ma+nd+og)+t(mb+ne+oh)+t(mc+nf+oi)+t(pa+qd+rg)+u(pb+qe+rh)+u(pc+qf+ri)+u]\tag{3} WX+b= (ja+kd+lg)+s(ma+nd+og)+t(pa+qd+rg)+u(jb+ke+lh)+s(mb+ne+oh)+t(pb+qe+rh)+u(jc+kf+li)+s(mc+nf+oi)+t(pc+qf+ri)+u (3)

    练习:实现L层神经网络的初始化。

    说明

    • 模型的结构为 [LINEAR -> RELU] × (L-1) -> LINEAR -> SIGMOID。也就是说,L−1层使用ReLU作为激活函数,最后一层采用sigmoid激活函数输出。

    • 随机初始化权重矩阵。使用np.random.rand(shape)* 0.01

    • 零初始化偏差。使用np.zeros(shape)

    • 我们将在不同的layer_dims变量中存储 n [ l ] n^{[l]} n[l],即不同层中的神经元数。例如,上周“二维数据分类模型”的layer_dims为[2,4,1]:即有两个输入,一个隐藏层包含4个隐藏单元,一个输出层包含1个输出单元。因此,W1的维度为(4,2),b1的维度为(4,1),W2的维度为(1,4),而b2的维度为(1,1)。现在你将把它应用到L层!

    • 这是L=1(一层神经网络)的实现。以启发你如何实现通用的神经网络(L层神经网络)。

      if L == 1:  
            parameters["W" + str(L)] = np.random.randn(layer_dims[1], layer_dims[0]) * 0.01  
            parameters["b" + str(L)] = np.zeros((layer_dims[1], 1))
      
      • 1
      • 2
      • 3

    In [5]:

    # GRADED FUNCTION: initialize_parameters_deep
    
    def initialize_parameters_deep(layer_dims):
        """
        Arguments:
        layer_dims -- python array (list) containing the dimensions of each layer in our network
        
        Returns:
        parameters -- python dictionary containing your parameters "W1", "b1", ..., "WL", "bL":
                        Wl -- weight matrix of shape (layer_dims[l], layer_dims[l-1])
                        bl -- bias vector of shape (layer_dims[l], 1)
        """
        
        np.random.seed(3)
        parameters = {}
        L = len(layer_dims)            # number of layers in the network
    
        for l in range(1, L):
            ### START CODE HERE ### (≈ 2 lines of code)
            parameters['W' + str(l)] = np.random.randn(layer_dims[l],layer_dims[l-1])*0.01
            parameters['b' + str(l)] = np.zeros((layer_dims[l],1))
            ### END CODE HERE ###
            
            assert(parameters['W' + str(l)].shape == (layer_dims[l], layer_dims[l-1]))
            assert(parameters['b' + str(l)].shape == (layer_dims[l], 1))
    
            
        return parameters
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    In [6]:

    parameters = initialize_parameters_deep([5,4,3])
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))
    W1 = [[ 0.01788628  0.0043651   0.00096497 -0.01863493 -0.00277388]
     [-0.00354759 -0.00082741 -0.00627001 -0.00043818 -0.00477218]
     [-0.01313865  0.00884622  0.00881318  0.01709573  0.00050034]
     [-0.00404677 -0.0054536  -0.01546477  0.00982367 -0.01101068]]
    b1 = [[0.]
     [0.]
     [0.]
     [0.]]
    W2 = [[-0.01185047 -0.0020565   0.01486148  0.00236716]
     [-0.01023785 -0.00712993  0.00625245 -0.00160513]
     [-0.00768836 -0.00230031  0.00745056  0.01976111]]
    b2 = [[0.]
     [0.]
     [0.]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    预期输出:
    W1 = [[ 0.01788628 0.0043651 0.00096497 -0.01863493 -0.00277388]
    [-0.00354759 -0.00082741 -0.00627001 -0.00043818 -0.00477218]
    [-0.01313865 0.00884622 0.00881318 0.01709573 0.00050034]
    [-0.00404677 -0.0054536 -0.01546477 0.00982367 -0.01101068]]
    b1 = [[0.]
    [0.]
    [0.]
    [0.]]
    W2 = [[-0.01185047 -0.0020565 0.01486148 0.00236716]
    [-0.01023785 -0.00712993 0.00625245 -0.00160513]
    [-0.00768836 -0.00230031 0.00745056 0.01976111]]
    b2 = [[0.]
    [0.]
    [0.]]

    4 正向传播模块

    4.1 线性正向

    现在,你已经初始化了参数,接下来将执行正向传播模块。 首先实现一些基本函数,用于稍后的模型实现。按以下顺序完成三个函数:

    • LINEAR
    • LINEAR -> ACTIVATION,其中激活函数采用ReLU或Sigmoid。
    • [LINEAR -> RELU] × (L-1) -> LINEAR -> SIGMOID(整个模型)

    线性正向模块(在所有数据中均进行向量化)的计算按照以下公式:

    Z [ l ] = W [ l ] A [ l − 1 ] + b [ l ] (4) Z^{[l]} = W^{[l]}A^{[l-1]} +b^{[l]}\tag{4} Z[l]=W[l]A[l1]+b[l](4)

    其中 A [ 0 ] = X A^{[0]} = X A[0]=X

    练习:建立正向传播的线性部分。

    提醒
    该单元的数学表示为 Z [ l ] = W [ l ] A [ l − 1 ] + b [ l ] Z^{[l]} = W^{[l]}A^{[l-1]} +b^{[l]} Z[l]=W[l]A[l1]+b[l],你可能会发现np.dot()有用。 如果维度不匹配,则可以printW.shape查看修改。

    In [7]:

    # GRADED FUNCTION: linear_forward
    
    def linear_forward(A, W, b):
        """
        Implement the linear part of a layer's forward propagation.
    
        Arguments:
        A -- activations from previous layer (or input data): (size of previous layer, number of examples)
        W -- weights matrix: numpy array of shape (size of current layer, size of previous layer)
        b -- bias vector, numpy array of shape (size of the current layer, 1)
    
        Returns: 
        Z -- the input of the activation function, also called pre-activation parameter 
        cache -- a python dictionary containing "A", "W" and "b" ; stored for computing the backward pass efficiently
        """
        
        ### START CODE HERE ### (≈ 1 line of code)
        Z = np.dot(W,A) + b
        ### END CODE HERE ###
        
        assert(Z.shape == (W.shape[0], A.shape[1]))
        cache = (A, W, b)
        
        return Z, cache
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    In [8]:

    A, W, b = linear_forward_test_case()
    
    Z, linear_cache = linear_forward(A, W, b)
    print("Z = " + str(Z))
    Z = [[ 3.26295337 -1.23429987]]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    预期输出:
    Z = [[ 3.26295337 -1.23429987]]

    4.2 正向线性激活

    在此笔记本中,你将使用两个激活函数:

    • Sigmoid σ ( Z ) = σ ( W A + b ) = 1 1 + e − ( W A + b ) \sigma(Z) = \sigma(W A + b) = \frac{1}{ 1 + e^{-(W A + b)}} σ(Z)=σ(WA+b)=1+e(WA+b)1。 我们为你提供了“ Sigmoid”函数。 该函数返回两项值:激活值"a"和包含"Z"的"cache"(这是我们将馈入到相应的反向函数的内容)。 你可以按下述方式得到两项值:

      A, activation_cache = sigmoid(Z)
      
      • 1
    • ReLU:ReLu的数学公式为 A = R E L U ( Z ) = m a x ( 0 , Z ) A = RELU(Z) = max(0, Z) A=RELU(Z)=max(0,Z)。我们为你提供了relu函数。 该函数返回两项值:激活值“A”和包含“Z”的“cache”(这是我们将馈入到相应的反向函数的内容)。 你可以按下述方式得到两项值:

      A, activation_cache = relu(Z)
      
      • 1

    为了更加方便,我们把两个函数(线性和激活)组合为一个函数(LINEAR-> ACTIVATION)。 因此,我们将实现一个函数用以执行LINEAR正向步骤和ACTIVATION正向步骤。

    练习:实现 LINEAR->ACTIVATION 层的正向传播。 数学表达式为: A [ l ] = g ( Z [ l ] ) = g ( W [ l ] A [ l − 1 ] + b [ l ] ) A^{[l]} = g(Z^{[l]}) = g(W^{[l]}A^{[l-1]} +b^{[l]}) A[l]=g(Z[l])=g(W[l]A[l1]+b[l]),其中激活"g" 可以是sigmoid()或relu()。 使用linear_forward()和正确的激活函数。

    In [9]:

    # GRADED FUNCTION: linear_activation_forward
    
    def linear_activation_forward(A_prev, W, b, activation):
        """
        Implement the forward propagation for the LINEAR->ACTIVATION layer
    
        Arguments:
        A_prev -- activations from previous layer (or input data): (size of previous layer, number of examples)
        W -- weights matrix: numpy array of shape (size of current layer, size of previous layer)
        b -- bias vector, numpy array of shape (size of the current layer, 1)
        activation -- the activation to be used in this layer, stored as a text string: "sigmoid" or "relu"
    
        Returns:
        A -- the output of the activation function, also called the post-activation value 
        cache -- a python dictionary containing "linear_cache" and "activation_cache";
                 stored for computing the backward pass efficiently
        """
        
        if activation == "sigmoid":
            # Inputs: "A_prev, W, b". Outputs: "A, activation_cache".
            ### START CODE HERE ### (≈ 2 lines of code)
            Z, linear_cache = linear_forward(A_prev,W,b)
            A, activation_cache = sigmoid(Z)
            ### END CODE HERE ###
        
        elif activation == "relu":
            # Inputs: "A_prev, W, b". Outputs: "A, activation_cache".
            ### START CODE HERE ### (≈ 2 lines of code)
            Z, linear_cache = linear_forward(A_prev,W,b)
            A, activation_cache = relu(Z)
            ### END CODE HERE ###
        
        assert (A.shape == (W.shape[0], A_prev.shape[1]))
        cache = (linear_cache, activation_cache)
    
        return A, cache
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    In [10]:

    A_prev, W, b = linear_activation_forward_test_case()
    
    A, linear_activation_cache = linear_activation_forward(A_prev, W, b, activation = "sigmoid")
    print("With sigmoid: A = " + str(A))
    
    A, linear_activation_cache = linear_activation_forward(A_prev, W, b, activation = "relu")
    print("With ReLU: A = " + str(A))
    With sigmoid: A = [[0.96890023 0.11013289]]
    With ReLU: A = [[3.43896131 0.        ]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    预期输出:
    With sigmoid: A = [[0.96890023 0.11013289]]
    With ReLU: A = [[3.43896131 0. ]]

    注意:在深度学习中,"[LINEAR->ACTIVATION]"计算被视为神经网络中的单个层,而不是两个层。

    4.3 L层模型

    为了方便实现L层神经网络,你将需要一个函数来复制前一个函数(使用RELU的linear_activation_forward)L−1次,以及复制带有SIGMOID的linear_activation_forward

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWKSYeNY-1662895428831)(L1W4%E4%BD%9C%E4%B8%9A1%20%E9%80%90%E6%AD%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C.assets/960-1662529885234-1.png)]

    图2 : [LINEAR -> RELU] × (L-1) -> LINEAR -> SIGMOID 模型

    练习:实现上述模型的正向传播。

    说明:在下面的代码中,变量AL表示 A [ L ] = σ ( Z [ L ] ) = σ ( W [ L ] A [ L − 1 ] + b [ L ] ) A^{[L]} = \sigma(Z^{[L]}) = \sigma(W^{[L]} A^{[L-1]} + b^{[L]}) A[L]=σ(Z[L])=σ(W[L]A[L1]+b[L])(有时也称为Yhat,即 Y ^ \hat{Y} Y^。)

    提示

    • 使用你先前编写的函数
    • 使用for循环复制[LINEAR-> RELU](L-1)次
    • 不要忘记在“cache”列表中更新缓存。 要将新值 c添加到list中,可以使用list.append(c)

    In [11]:

    # GRADED FUNCTION: L_model_forward
    
    def L_model_forward(X, parameters):
        """
        Implement forward propagation for the [LINEAR->RELU]*(L-1)->LINEAR->SIGMOID computation
        
        Arguments:
        X -- data, numpy array of shape (input size, number of examples)
        parameters -- output of initialize_parameters_deep()
        
        Returns:
        AL -- last post-activation value
        caches -- list of caches containing:
                    every cache of linear_relu_forward() (there are L-1 of them, indexed from 0 to L-2)
                    the cache of linear_sigmoid_forward() (there is one, indexed L-1)
        """
    
        caches = []
        A = X
        L = len(parameters) // 2                  # number of layers in the neural network
        
        # Implement [LINEAR -> RELU]*(L-1). Add "cache" to the "caches" list.
        for l in range(1, L):
            A_prev = A 
             ### START CODE HERE ### (≈ 2 lines of code)
            A, cache = linear_activation_forward(A_prev,parameters['W' + str(l)],parameters['b' + str(l)],activation = "relu")
            caches.append(cache)
            ### END CODE HERE ###
        
        # Implement LINEAR -> SIGMOID. Add "cache" to the "caches" list.
        ### START CODE HERE ### (≈ 2 lines of code)
        AL, cache = linear_activation_forward(A,parameters['W' + str(L)],parameters['b' + str(L)],activation = "sigmoid")
        caches.append(cache)
        ### END CODE HERE ###
        
        assert(AL.shape == (1,X.shape[1]))
                
        return AL, caches
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    In [12]:

    X, parameters = L_model_forward_test_case()
    AL, caches = L_model_forward(X, parameters)
    print("AL = " + str(AL))
    print("Length of caches list = " + str(len(caches)))
    AL = [[0.17007265 0.2524272 ]]
    Length of caches list = 2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    预期输出:
    AL = [[0.17007265 0.2524272 ]]
    Length of caches list = 2

    现在,你有了一个完整的正向传播模块,它接受输入X并输出包含预测的行向量 A [ L ] A^{[L]} A[L]。 它还将所有中间值记录在"caches"中以计算预测的损失值。

    5 损失函数

    现在,你将实现模型的正向和反向传播。 你需要计算损失,以检查模型是否在学习。

    练习:使用以下公式计算交叉熵损失J:
    − 1 m ∑ i = 1 m ( y ( i ) log ⁡ ( a [ L ] ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − a [ L ] ( i ) ) ) (7) -\frac{1}{m} \sum\limits_{i = 1}^{m} (y^{(i)}\log\left(a^{[L] (i)}\right) + (1-y^{(i)})\log\left(1- a^{[L](i)}\right)) \tag{7} m1i=1m(y(i)log(a[L](i))+(1y(i))log(1a[L](i)))(7)

    In [13]:

    # GRADED FUNCTION: compute_cost
    
    def compute_cost(AL, Y):
        """
        Implement the cost function defined by equation (7).
    
        Arguments:
        AL -- probability vector corresponding to your label predictions, shape (1, number of examples)
        Y -- true "label" vector (for example: containing 0 if non-cat, 1 if cat), shape (1, number of examples)
    
        Returns:
        cost -- cross-entropy cost
        """
        
        m = Y.shape[1]
    
        # Compute loss from aL and y.
        ### START CODE HERE ### (≈ 1 lines of code)
        cost = -1 / m * np.sum(Y * np.log(AL) + (1-Y) * np.log(1-AL),axis=1,keepdims=True)
        ### END CODE HERE ###
        
        cost = np.squeeze(cost)      # To make sure your cost's shape is what we expect (e.g. this turns [[17]] into 17).
        assert(cost.shape == ())
        
        return cost
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    In [14]:

    Y, AL = compute_cost_test_case()
    
    print("cost = " + str(compute_cost(AL, Y)))
    cost = 0.41493159961539694
    
    • 1
    • 2
    • 3
    • 4

    预期输出:
    cost = 0.41493159961539694

    6 反向传播模块

    就像正向传播一样,你将实现辅助函数以进行反向传播。 请记住,反向传播用于计算损失函数相对于参数的梯度。

    提醒

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zbNE7TBV-1662895428833)(L1W4%E4%BD%9C%E4%B8%9A1%20%E9%80%90%E6%AD%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C.assets/960-1662529885235-2.png)]

    图3
    LINEAR->RELU->LINEAR->SIGMOID 的正向和反向传播,紫色块代表正向传播,红色块代表反向传播。

    对于那些精通微积分的人(不必进行此作业),可以使用微积分的链式规则来得出2层网络中的损失 L \mathcal{L} L相对于 z [ 1 ] z^{[1]} z[1]的导数,如下所示:

    d L ( a [ 2 ] , y ) d z [ 1 ] = d L ( a [ 2 ] , y ) d a [ 2 ] d a [ 2 ] d z [ 2 ] d z [ 2 ] d a [ 1 ] d a [ 1 ] d z [ 1 ] (8) \frac{d \mathcal{L}(a^{[2]},y)}{{dz^{[1]}}} = \frac{d\mathcal{L}(a^{[2]},y)}{{da^{[2]}}}\frac{{da^{[2]}}}{{dz^{[2]}}}\frac{{dz^{[2]}}}{{da^{[1]}}}\frac{{da^{[1]}}}{{dz^{[1]}}} \tag{8} dz[1]dL(a[2],y)=da[2]dL(a[2],y)dz[2]da[2]da[1]dz[2]dz[1]da[1](8)

    为了计算梯度 d W [ 1 ] = ∂ L ∂ W [ 1 ] dW^{[1]} = \frac{\partial L}{\partial W^{[1]}} dW[1]=W[1]L,请使用上一个链规则,然后执行 d W [ 1 ] = d z [ 1 ] × ∂ z [ 1 ] ∂ W [ 1 ] dW^{[1]} = dz^{[1]} \times \frac{\partial z^{[1]} }{\partial W^{[1]}} dW[1]=dz[1]×W[1]z[1]。 在反向传播的每个步骤中,你都将当前梯度乘以对应层的梯度,以获得所需的梯度。

    同样地,为了计算梯度 d b [ 1 ] = ∂ L ∂ b [ 1 ] db^{[1]} = \frac{\partial L}{\partial b^{[1]}} db[1]=b[1]L,你使用前一个链规则,然后执行 d b [ 1 ] = d z [ 1 ] × ∂ z [ 1 ] ∂ b [ 1 ] db^{[1]} = dz^{[1]} \times \frac{\partial z^{[1]} }{\partial b^{[1]}} db[1]=dz[1]×b[1]z[1]

    这也是为什么我们称之为反向传播

    现在,类似于正向传播,你将分三个步骤构建反向传播:

    • LINEAR backward
    • LINEAR -> ACTIVATION backward,其中激活函数使用ReLUsigmoid 的导数计算
    • [LINEAR -> RELU] × (L-1) -> LINEAR -> SIGMOID backward(整个模型)

    6.1 线性反向

    对于层 l l l,线性部分为: Z [ l ] = W [ l ] A [ l − 1 ] + b [ l ] Z^{[l]} = W^{[l]} A^{[l-1]} + b^{[l]} Z[l]=W[l]A[l1]+b[l](之后是激活)。

    假设你已经计算出导数 d Z [ l ] = ∂ L ∂ Z [ l ] dZ^{[l]} = \frac{\partial \mathcal{L} }{\partial Z^{[l]}} dZ[l]=Z[l]L。 你想获得 ( d W [ l ] , d b [ l ] d A [ l − 1 ] ) (dW^{[l]}, db^{[l]} dA^{[l-1]}) (dW[l],db[l]dA[l1])

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKWyKw63-1662895428834)(L1W4%E4%BD%9C%E4%B8%9A1%20%E9%80%90%E6%AD%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C.assets/960-1662529885235-3.png)]

    图4

    使用输入 d Z [ l ] dZ^{[l]} dZ[l]计算三个输出 ( d W [ l ] , d b [ l ] , d A [ l ] ) (dW^{[l]}, db^{[l]}, dA^{[l]}) (dW[l],db[l],dA[l])。以下是所需的公式:

    d W [ l ] = ∂ L ∂ W [ l ] = 1 m d Z [ l ] A [ l − 1 ] T (8) dW^{[l]} = \frac{\partial \mathcal{L} }{\partial W^{[l]}} = \frac{1}{m} dZ^{[l]} A^{[l-1] T} \tag{8} dW[l]=W[l]L=m1dZ[l]A[l1]T(8)

    d b [ l ] = ∂ L ∂ b [ l ] = 1 m ∑ i = 1 m d Z [ l ] ( i ) (9) db^{[l]} = \frac{\partial \mathcal{L} }{\partial b^{[l]}} = \frac{1}{m} \sum_{i = 1}^{m} dZ^{[l](i)}\tag{9} db[l]=b[l]L=m1i=1mdZ[l](i)(9)

    d A [ l − 1 ] = ∂ L ∂ A [ l − 1 ] = W [ l ] T d Z [ l ] (10) dA^{[l-1]} = \frac{\partial \mathcal{L} }{\partial A^{[l-1]}} = W^{[l] T} dZ^{[l]} \tag{10} dA[l1]=A[l1]L=W[l]TdZ[l](10)

    练习:使用上面的3个公式实现linear_backward()。

    In [15]:

    # GRADED FUNCTION: linear_backward
    
    def linear_backward(dZ, cache):
        """
        Implement the linear portion of backward propagation for a single layer (layer l)
     
        Arguments:
        dZ -- Gradient of the cost with respect to the linear output (of current layer l)
        cache -- tuple of values (A_prev, W, b) coming from the forward propagation in the current layer
    
        Returns:
        dA_prev -- Gradient of the cost with respect to the activation (of the previous layer l-1), same shape as A_prev
        dW -- Gradient of the cost with respect to W (current layer l), same shape as W
        db -- Gradient of the cost with respect to b (current layer l), same shape as b
        """
        A_prev, W, b = cache
        m = A_prev.shape[1]
       ### START CODE HERE ### (≈ 3 lines of code)
        dW = 1 / m * np.dot(dZ ,A_prev.T)
        db = 1 / m * np.sum(dZ,axis = 1 ,keepdims=True)
        dA_prev = np.dot(W.T,dZ) 
        ### END CODE HERE ###
        
        assert (dA_prev.shape == A_prev.shape)
        assert (dW.shape == W.shape)
        assert (db.shape == b.shape)
        
        return dA_prev, dW, db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    In [16]:

    # Set up some test inputs
    dZ, linear_cache = linear_backward_test_case()
    
    dA_prev, dW, db = linear_backward(dZ, linear_cache)
    print ("dA_prev = "+ str(dA_prev))
    print ("dW = " + str(dW))
    print ("db = " + str(db))
    dA_prev = [[ 0.51822968 -0.19517421]
     [-0.40506361  0.15255393]
     [ 2.37496825 -0.89445391]]
    dW = [[-0.10076895  1.40685096  1.64992505]]
    db = [[0.50629448]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    预期输出:
    dA_prev = [[ 0.51822968 -0.19517421]
    [-0.40506361 0.15255393]
    [ 2.37496825 -0.89445391]]
    dW = [[-0.10076895 1.40685096 1.64992505]]
    db = [[0.50629448]]

    6.2 反向线性激活

    接下来,创建一个合并两个辅助函数的函数:linear_backward 和反向步骤的激活 linear_activation_backward

    为了帮助你实现linear_activation_backward,我们提供了两个反向函数:

    • sigmoid_backward:实现SIGMOID单元的反向传播。 你可以这样使用:
    dZ = sigmoid_backward(dA, activation_cache)
    
    • 1
    • relu_backward:实现RELU单元的反向传播。 你可以这样使用:
    dZ = relu_backward(dA, activation_cache)
    
    • 1

    如果 g ( . ) g(.) g(.)是激活函数,
    sigmoid_backwardrelu_backward计算
    d Z [ l ] = d A [ l ] ∗ g ′ ( Z [ l ] ) (11) dZ^{[l]} = dA^{[l]} * g'(Z^{[l]}) \tag{11} dZ[l]=dA[l]g(Z[l])(11)

    练习:实现LINEAR->ACTIVATION 层的反向传播。

    In [17]:

    # GRADED FUNCTION: linear_activation_backward
    
    def linear_activation_backward(dA, cache, activation):
        """
        Implement the backward propagation for the LINEAR->ACTIVATION layer.
        
        Arguments:
        dA -- post-activation gradient for current layer l 
        cache -- tuple of values (linear_cache, activation_cache) we store for computing backward propagation efficiently
        activation -- the activation to be used in this layer, stored as a text string: "sigmoid" or "relu"
        
        Returns:
        dA_prev -- Gradient of the cost with respect to the activation (of the previous layer l-1), same shape as A_prev
        dW -- Gradient of the cost with respect to W (current layer l), same shape as W
        db -- Gradient of the cost with respect to b (current layer l), same shape as b
        """
        linear_cache, activation_cache = cache
        
        if activation == "relu":
            ### START CODE HERE ### (≈ 2 lines of code)
            dZ = relu_backward(dA, activation_cache)
            dA_prev, dW, db = linear_backward(dZ, linear_cache)
            ### END CODE HERE ###
            
        elif activation == "sigmoid":
            ### START CODE HERE ### (≈ 2 lines of code)
            dZ = sigmoid_backward(dA, activation_cache)
            dA_prev, dW, db = linear_backward(dZ, linear_cache)
            ### END CODE HERE ###
        
        return dA_prev, dW, db
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    In [18]:

    AL, linear_activation_cache = linear_activation_backward_test_case()
    
    dA_prev, dW, db = linear_activation_backward(AL, linear_activation_cache, activation = "sigmoid")
    print ("sigmoid:")
    print ("dA_prev = "+ str(dA_prev))
    print ("dW = " + str(dW))
    print ("db = " + str(db) + "\n")
    
    dA_prev, dW, db = linear_activation_backward(AL, linear_activation_cache, activation = "relu")
    print ("relu:")
    print ("dA_prev = "+ str(dA_prev))
    print ("dW = " + str(dW))
    print ("db = " + str(db))
    sigmoid:
    dA_prev = [[ 0.11017994  0.01105339]
     [ 0.09466817  0.00949723]
     [-0.05743092 -0.00576154]]
    dW = [[ 0.10266786  0.09778551 -0.01968084]]
    db = [[-0.05729622]]
    
    relu:
    dA_prev = [[ 0.44090989  0.        ]
     [ 0.37883606  0.        ]
     [-0.2298228   0.        ]]
    dW = [[ 0.44513824  0.37371418 -0.10478989]]
    db = [[-0.20837892]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    sigmoid 输出:
    dA_prev = [[ 0.11017994 0.01105339]
    [ 0.09466817 0.00949723]
    [-0.05743092 -0.00576154]]
    dW = [[ 0.10266786 0.09778551 -0.01968084]]
    db = [[-0.05729622]]

    relu 输出:
    dA_prev = [[ 0.44090989 0. ]
    [ 0.37883606 0. ]
    [-0.2298228 0. ]]
    dW = [[ 0.44513824 0.37371418 -0.10478989]]
    db = [[-0.20837892]]

    6.3 反向L层模型

    现在,你将为整个网络实现反向传播函数。 回想一下,当你实现L_model_forward函数时,在每次迭代中,你都存储了一个包含(X,W,b和z)的缓存。 在反向传播模块中,你将使用这些变量来计算梯度。 因此,在L_model_backward函数中,你将从L层开始向后遍历所有隐藏层。在每个步骤中,你都将使用 l l l层的缓存值反向传播到层 l l l。 图5展示了反向传播过程。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mUEV3xUW-1662895428835)(L1W4%E4%BD%9C%E4%B8%9A1%20%E9%80%90%E6%AD%A5%E6%9E%84%E5%BB%BA%E4%BD%A0%E7%9A%84%E6%B7%B1%E5%BA%A6%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C.assets/960-1662529885235-4.png)]

    图5:反向流程

    初始化反向传播
    为了使网络反向传播,我们知道输出是
    A [ L ] = σ ( Z [ L ] ) A^{[L]} = \sigma(Z^{[L]}) A[L]=σ(Z[L])。因此,你的代码需要计算dAL = ∂ L ∂ A [ L ] = \frac{\partial \mathcal{L}}{\partial A^{[L]}} =A[L]L
    为此,请使用以下公式(不需要深入的微积分知识):

    dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL)) # derivative of cost with respect to AL
    
    • 1

    然后,你可以使用此激活后的梯度dAL继续反向传播。如图5所示,你现在可以将dAL输入到你实现的LINEAR-> SIGMOID反向函数中(它将使用L_model_forward函数存储的缓存值)。之后,你得通过for循环,使用LINEAR-> RELU反向函数迭代所有其他层。同时将每个dAdWdb存储在grads词典中。为此,请使用以下公式:

    g r a d s [ " d W " + s t r ( l ) ] = d W [ l ] (15) grads["dW" + str(l)] = dW^{[l]}\tag{15} grads["dW"+str(l)]=dW[l](15)

    例如,当 l = 3 l=3 l=3时,它将在grads["dW3"]中存储 d W [ l ] dW^{[l]} dW[l]

    练习:实现 [LINEAR->RELU] × (L-1) -> LINEAR -> SIGMOID 模型的反向传播。

    In [19]:

    # GRADED FUNCTION: L_model_backward
    
    def L_model_backward(AL, Y, caches):
        """
        Implement the backward propagation for the [LINEAR->RELU] * (L-1) -> LINEAR -> SIGMOID group
        
        Arguments:
        AL -- probability vector, output of the forward propagation (L_model_forward())
        Y -- true "label" vector (containing 0 if non-cat, 1 if cat)
        caches -- list of caches containing:
                    every cache of linear_activation_forward() with "relu" (it's caches[l], for l in range(L-1) i.e l = 0...L-2)
                    the cache of linear_activation_forward() with "sigmoid" (it's caches[L-1])
        
        Returns:
        grads -- A dictionary with the gradients
                 grads["dA" + str(l)] = ...
                 grads["dW" + str(l)] = ...
                 grads["db" + str(l)] = ...
        """
        grads = {}
        L = len(caches) # the number of layers
        m = AL.shape[1]
        Y = Y.reshape(AL.shape) # after this line, Y is the same shape as AL
    
        # Initializing the backpropagation
        ### START CODE HERE ### (1 line of code)
        dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))
        ### END CODE HERE ###
        
        # Lth layer (SIGMOID -> LINEAR) gradients. Inputs: "AL, Y, caches". Outputs: "grads["dAL"], grads["dWL"], grads["dbL"]
        ### START CODE HERE ### (approx. 2 lines)
        current_cache = caches[L - 1]
        dA_prev_temp, dW_temp, db_temp = linear_activation_backward(dAL, current_cache, "sigmoid")
        grads["dA" + str(L-1)] = dA_prev_temp
        grads["dW" + str(L)] = dW_temp
        grads["db" + str(L)] = db_temp 
        ### END CODE HERE ###
          
        for l in reversed(range(L - 1)):
            # lth layer: (RELU -> LINEAR) gradients.
            # Inputs: "grads["dA" + str(l + 2)], caches". Outputs: "grads["dA" + str(l + 1)] , grads["dW" + str(l + 1)] , grads["db" + str(l + 1)] 
            ### START CODE HERE ### (approx. 5 lines)
            
            current_cache = caches[l]
            dA_prev_temp, dW_temp, db_temp = linear_activation_backward(grads["dA" + str(l+1)], current_cache, activation = "relu")
            grads["dA" + str(l)] = dA_prev_temp
            grads["dW" + str(l+1)] = dW_temp
            grads["db" + str(l+1)] = db_temp
            ### END CODE HERE ###
    
    
        return grads
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    In [20]:

    AL, Y_assess, caches = L_model_backward_test_case()
    grads = L_model_backward(AL, Y_assess, caches)
    print ("dW1 = "+ str(grads["dW1"]))
    print ("db1 = "+ str(grads["db1"]))
    print ("dA1 = "+ str(grads["dA1"]))
    dW1 = [[0.41010002 0.07807203 0.13798444 0.10502167]
     [0.         0.         0.         0.        ]
     [0.05283652 0.01005865 0.01777766 0.0135308 ]]
    db1 = [[-0.22007063]
     [ 0.        ]
     [-0.02835349]]
    dA1 = [[ 0.          0.52257901]
     [ 0.         -0.3269206 ]
     [ 0.         -0.32070404]
     [ 0.         -0.74079187]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    预期输出
    dW1 = [[0.41010002 0.07807203 0.13798444 0.10502167]
    [0. 0. 0. 0. ]
    [0.05283652 0.01005865 0.01777766 0.0135308 ]]
    db1 = [[-0.22007063]
    [ 0. ]
    [-0.02835349]]
    dA1 = [[ 0. 0.52257901]
    [ 0. -0.3269206 ]
    [ 0. -0.32070404]
    [ 0. -0.74079187]]

    6.4 更新参数

    在本节中,你将使用梯度下降来更新模型的参数:

    W [ l ] = W [ l ] − α   d W [ l ] (16) W^{[l]} = W^{[l]} - \alpha \text{ } dW^{[l]} \tag{16} W[l]=W[l]α dW[l](16)

    b [ l ] = b [ l ] − α   d b [ l ] (17) b^{[l]} = b^{[l]} - \alpha \text{ } db^{[l]} \tag{17} b[l]=b[l]α db[l](17)

    其中 α 是学习率。 在计算更新的参数后,将它们存储在参数字典中。

    练习:实现update_parameters()以使用梯度下降来更新模型参数。

    说明
    对于 l = 1 , 2 , . . . , L l = 1, 2, ..., L l=1,2,...,L,使用梯度下降更新每个 W [ l ] W^{[l]} W[l] b [ l ] b^{[l]} b[l]的参数。

    In [21]:

    # GRADED FUNCTION: update_parameters
    
    def update_parameters(parameters, grads, learning_rate):
        """
        Update parameters using gradient descent
        
        Arguments:
        parameters -- python dictionary containing your parameters 
        grads -- python dictionary containing your gradients, output of L_model_backward
        
        Returns:
        parameters -- python dictionary containing your updated parameters 
                      parameters["W" + str(l)] = ... 
                      parameters["b" + str(l)] = ...
        """
        
        L = len(parameters) // 2 # number of layers in the neural network
    
        # Update rule for each parameter. Use a for loop.
        ### START CODE HERE ### (≈ 3 lines of code)
        for l in range(L):
            parameters["W" + str(l+1)] =  parameters["W" + str(l+1)] - learning_rate * grads["dW" + str(l + 1)]
            parameters["b" + str(l+1)] = parameters["b" + str(l+1)] - learning_rate * grads["db" + str(l + 1)]
        ### END CODE HERE ###
            
        return parameters
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    In [22]:

    parameters, grads = update_parameters_test_case()
    parameters = update_parameters(parameters, grads, 0.1)
    
    print ("W1 = "+ str(parameters["W1"]))
    print ("b1 = "+ str(parameters["b1"]))
    print ("W2 = "+ str(parameters["W2"]))
    print ("b2 = "+ str(parameters["b2"]))
    W1 = [[-0.59562069 -0.09991781 -2.14584584  1.82662008]
     [-1.76569676 -0.80627147  0.51115557 -1.18258802]
     [-1.0535704  -0.86128581  0.68284052  2.20374577]]
    b1 = [[-0.04659241]
     [-1.28888275]
     [ 0.53405496]]
    W2 = [[-0.55569196  0.0354055   1.32964895]]
    b2 = [[-0.84610769]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    预期输出:
    W1 = [[-0.59562069 -0.09991781 -2.14584584 1.82662008]
    [-1.76569676 -0.80627147 0.51115557 -1.18258802]
    [-1.0535704 -0.86128581 0.68284052 2.20374577]]
    b1 = [[-0.04659241]
    [-1.28888275]
    [ 0.53405496]]
    W2 = [[-0.55569196 0.0354055 1.32964895]]
    b2 = [[-0.84610769]]

    7 结论

    恭喜你实现了构建深度神经网络所需的所有函数!

    我们知道这是一项艰巨的任务,但是继续前进将变得更好。 下一部分的作业相对容易。

    在下一个作业中,你将使用这些函数构建两个模型用于分类猫图像和非猫图像:

    • 两层神经网络
    • L层神经网络
  • 相关阅读:
    【python】遇上COS美图怎么办?当然是大胆冲呀~
    在uniapp中开发年份弹出选择组件
    kubernetes从1.23.8升级到1.24.6
    unity局部坐标和世界坐标角度介绍
    品牌化战略:跨境电商市场突破的关键
    svn的常规使用
    前端进击笔记第十七节 提升开发效率:数据抽象与配置化
    大数据flink篇之二-基础实例wordcount
    Polygon zkEVM Memory状态机
    DevOps篇:Jenkins Pipeline流水线语法基础与进阶
  • 原文地址:https://blog.csdn.net/segegse/article/details/126808279