• 吴恩达深度学习 第一课第三周课后编程作业


     

    一个隐含层的平面数据分类

    2020-07-21

    欢迎来到第三周的编程作业。现在是构建第一个神经网络的时候了,它有一个隐藏层。您将看到此模型与使用逻辑回归实现的模型之间的巨大差异

    您将学习如何:

    •实现一个只有一个隐藏层的2分类神经网络
    •使用具有非线性激活函数的单元,如tanh
    •计算交叉熵损失
    •实现向前和向后传播

    本文作业是在jupyter notebook上一步一步做的,带有一些过程中查找的资料等(出处已标明)并翻译成了中文,如有错误,欢迎指正!


    1 - Packages(包)

    让我们首先导入在此任务中需要的所有包。

    numpy是使用Python进行科学计算的基本包。
    •sklearn为数据挖掘数据分析提供了简单而高效的工具。
    matplotlib是Python中用于绘制图形的库
    testcase提供了一些测试示例来评估函数的正确性
    planar_utils提供了在这个赋值中使用的各种有用的函数

    # Package imports
    import numpy as np
    import matplotlib.pyplot as plt
    from testCases import *
    import sklearn
    import sklearn.datasets
    import sklearn.linear_model
    from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset, load_extra_datasets
    
    %matplotlib inline #这行代码是由于在jupyter上运行才要的
    #可以将matplotlib的图表直接嵌入到Notebook之中,或者使用指定的界面库显示图表,它有一个参数指定matplotlib图表的显示方式。inline表示将图表嵌入到Notebook中
    #有了%matplotlib inline 就可以省掉plt.show()了
    
    
    np.random.seed(1) # set a seed so that the results are consistent

    python中我们常会用到numpy.random.seed()函数。
    其基本用法或作用网上很多人都写过:

    seed( ) 用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed( )值,则每次生成的随即数都相同

    关于numpy.random.seed()的参数说明 


     

    2 - Dataset(数据集)

    First, let's get the dataset you will work on. The following code will load a "flower" 2-class dataset into variables X and Y.

    首先,让我们获得要处理的数据集。下面的代码将把一个“flower”2分类 数据集加载到变量X和Y中。

    X, Y = load_planar_dataset()

     可以看到向量X是2X400就是2行400列,而Y是1X400就是1行400列

    使用matplotlib可视化数据集。数据看起来像一朵“花”,有一些红色(标签y=0)和一些蓝色(y=1)点。您的目标是构建一个模型匹配这些数据

    # Visualize the data:
    plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral);

    (由于使用Jupyter Notebook在这周作业出现问题,运行不通过)问题如下:

     

     

    参考了来自Miss思的吴恩达深度学习——第一课第三周课后编程作业Debug经历,链接:https://blog.csdn.net/weixin_43978140/article/details/85012675

    以下转自:https://blog.csdn.net/weixin_43978140/article/details/85012675

    1、数据可视化

    #plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral)
    plt.scatter(X[0,:],X[1,:],c=np.squeeze(Y),*s=40,cmap=plt.cm.Spectral)

    这里进行数据可视化的时候,纯用c=Y会出错,出错原因及解决方法如下:

    在机器学习和深度学习中,通常算法的结果是可以表示向量的数组(即包含两对或以上的方括号形式[[]]),如果直接利用这个数组进行画图可能显示界面为空(见后面的示例)。
    我们可以利用squeeze()函数将表示向量的数组转换为秩为1的数组,这样利用matplotlib库函数画图时,就可以正常的显示结果了。

    2、关于plot_decision_boundar函数
    这里主要也是要注意里面的参数,Y的部分要变成np.squeeze(Y)

    更改代码后:

    # Visualize the data:
    plt.scatter(X[0, :], X[1, :], c= np.squeeze(Y), s=40, cmap=plt.cm.Spectral);

    (plt.scatter( ) 函数的使用方法), 来自:

    matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, *, data=None, **kwargs)
    plt.scatter()
    参数的解释:
    
    x,y:表示的是大小为(n,)的数组,也就是我们即将绘制散点图的数据点
    
    s:是一个实数或者是一个数组大小为(n,),这个是一个可选的参数。
    
    c:表示的是颜色,也是一个可选项。默认是蓝色'b',表示的是标记的颜色,或者可以是一个表示颜色的字符,或者是一个长度为n的表示颜色的序列等等,感觉还没用到过现在不解释了。但是c不可以是一个单独的RGB数字,也不可以是一个RGBA的序列。可以是他们的2维数组(只有一行)。
    
    marker:表示的是标记的样式,默认的是'o'。
    
    cmap:Colormap实体或者是一个colormap的名字,cmap仅仅当c是一个浮点数数组的时候才使用。如果没有申明就是image.cmap
    
    norm:Normalize实体来将数据亮度转化到0-1之间,也是只有c是一个浮点数的数组的时候才使用。如果没有申明,就是默认为colors.Normalize。
    
    vmin,vmax:实数,当norm存在的时候忽略。用来进行亮度数据的归一化。
    
    alpha:实数,0-1之间。
    
    linewidths:也就是标记点的长度。
    plt.scatter参数说明

    python中 x[:,0]和x[:,1] 理解和实例解析,来自

    这里X[0, :]为第一行的所有数,X[1, :]为第二行的所有数

     你有:
    一个包含你的特征(x1, x2)的数字数组(矩阵)X
    一个包含标签(红色:0,蓝色:1)的数字数组(向量)Y。


    首先让我们更好地了解我们的数据是什么样的。
    练习:你有多少训练例子?另外,变量X和Y的形状是什么?
    提示:如何得到一个numpy数组的形状?(帮助)

    ### START CODE HERE ### (≈ 3 lines of code)
    shape_X = X.shape
    shape_Y = Y.shape
    m = shape_X[1]  # training set size
    ### END CODE HERE ###
    
    print ('The shape of X is: ' + str(shape_X))
    print ('The shape of Y is: ' + str(shape_Y))
    print ('I have m = %d training examples!' % (m))

     这里m = shape_X[1] # training set size,1是代表横轴的方向,所以有400个训练样本


    3 - Simple Logistic Regression(简单逻辑回归)

    在建立一个完整的神经网络之前,让我们先看看逻辑回归在这个问题上的表现。您可以使用sklearn的内置函数来实现这一点。运行下面的代码来训练数据集上的逻辑回归分类器

    # Train the logistic regression classifier
    clf = sklearn.linear_model.LogisticRegressionCV();
    clf.fit(X.T, Y.T);

    注意上面的代码的Y也是需要转换为秩为1的数字:

    # Train the logistic regression classifier
    clf = sklearn.linear_model.LogisticRegressionCV();
    clf.fit(X.T, np.squeeze(Y).T);

    看到还有一种:

    # Train the logistic regression classifier
    clf = sklearn.linear_model.LogisticRegressionCV();
    clf.fit(X.T, Y.T.ravel());#将多维数组降位一维

      numpy中的ravel()、flatten()、squeeze()的用法与区别 - 草稿,来自:爱学习的大丁

      fit()训练。调用fit(x,y)的方法来训练模型,其中x为数据的属性,y为所属类型。来自:静悟生慧LogisticRegression回归算法 Sklearn 参数详解

      sklearn逻辑回归(Logistic Regression,LR)类库使用小结,来自 :原文出处:http://www.cnblogs.com/pinard/p/6035872.html,在原文的基础上做了一些修订

      clf.fit需要转置,clf.fit填入数据进行训练

    现在可以绘制这些模型的决策边界。运行下面的代码。

    # Plot the decision boundary for logistic regression 绘制逻辑回归的决策边界
    plot_decision_boundary(lambda x: clf.predict(x), X, Y)
    plt.title("Logistic Regression")
    
    # Print accuracy 打印精度
    LR_predictions = clf.predict(X.T) #得到预测值Y_hat,标签
    print ('Accuracy of logistic regression: %d ' % float((np.dot(Y,LR_predictions) + np.dot(1-Y,1-LR_predictions))/float(Y.size)*100) +
           '% ' + "(percentage of correctly labelled datapoints)")

     

     绘制逻辑回归的决策边界是不是就是红蓝的分解线呢?

    float((np.dot(Y,LR_predictions) + np.dot(1-Y,1-LR_predictions))/float(Y.size)*100)

    到这里代码有些看不懂,plot_decision_boundary,这是一个函数吗?从最上面导入的情况来看是从属于planar_utils这个文件的,这个文件写了4个函数,如下

     1 import matplotlib.pyplot as plt
     2 import numpy as np
     3 import sklearn
     4 import sklearn.datasets
     5 import sklearn.linear_model
     6 
     7 def plot_decision_boundary(model, X, y):
     8     # Set min and max values and give it some padding
     9     x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1
    10     y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
    11     h = 0.01
    12     # Generate a grid of points with distance h between them
    13     xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    14     # Predict the function value for the whole grid
    15     Z = model(np.c_[xx.ravel(), yy.ravel()])
    16     Z = Z.reshape(xx.shape)
    17     # Plot the contour and training examples
    18     plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    19     plt.ylabel('x2')
    20     plt.xlabel('x1')
    21     plt.scatter(X[0, :], X[1, :], c=np.squeeze(y), cmap=plt.cm.Spectral)
    22     
    23 
    24 def sigmoid(x):
    25     """
    26     Compute the sigmoid of x
    27 
    28     Arguments:
    29     x -- A scalar or numpy array of any size.
    30 
    31     Return:
    32     s -- sigmoid(x)
    33     """
    34     s = 1/(1+np.exp(-x))
    35     return s
    36 
    37 def load_planar_dataset():
    38     np.random.seed(1)
    39     m = 400 # number of examples
    40     N = int(m/2) # number of points per class
    41     D = 2 # dimensionality
    42     X = np.zeros((m,D)) # data matrix where each row is a single example
    43     Y = np.zeros((m,1), dtype='uint8') # labels vector (0 for red, 1 for blue)
    44     a = 4 # maximum ray of the flower
    45 
    46     for j in range(2):
    47         ix = range(N*j,N*(j+1))
    48         t = np.linspace(j*3.12,(j+1)*3.12,N) + np.random.randn(N)*0.2 # theta
    49         r = a*np.sin(4*t) + np.random.randn(N)*0.2 # radius
    50         X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
    51         Y[ix] = j
    52         
    53     X = X.T
    54     Y = Y.T
    55 
    56     return X, Y
    57 
    58 def load_extra_datasets():  
    59     N = 200
    60     noisy_circles = sklearn.datasets.make_circles(n_samples=N, factor=.5, noise=.3)
    61     noisy_moons = sklearn.datasets.make_moons(n_samples=N, noise=.2)
    62     blobs = sklearn.datasets.make_blobs(n_samples=N, random_state=5, n_features=2, centers=6)
    63     gaussian_quantiles = sklearn.datasets.make_gaussian_quantiles(mean=None, cov=0.5, n_samples=N, n_features=2, n_classes=2, shuffle=True, random_state=None)
    64     no_structure = np.random.rand(N, 2), np.random.rand(N, 2)
    65     
    66     return noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure
    planar_utils

    解释:首先Y.size是400,因为Y是1X400的一个行向量,

    可以看到逻辑回归分类准确率很低,无法正确分类。

    解释:数据集不是线性可分的,所以logistic回归的效果不是很好。希望神经网络能做得更好。我们现在就来试试!


    4 - Neural Network model

    逻辑回归在“花数据集”上效果不佳。你要训练一个只有一个隐含层的神经网络

    Here is our model:

    数学上的:

    对于一个样本的xi

     根据对所有例子的预测,您还可以计算代价J如下:

     提醒:构建神经网络的一般方法是:

    1. 定义神经网络结构(输入单元,隐藏单元,等等)。
    2. 初始化模型的参数
    3.循环:
      实现正向传播
      计算损失
      实现反向传播,以获得梯度
      更新参数(梯度下降)

    您经常构建辅助函数来计算步骤1-3,然后将它们合并到一个称为nn_model()的函数中。一旦构建了nn_model()并学习了正确的参数,就可以对新数据进行预测

     


     

    4.1 -定义神经网络结构

    练习:定义三个变量:

    - n_x:输入层的大小
    - n_h:隐藏层的大小(设置为4)
    - n_y:输出层的大小

    提示:使用X和Y的形状来查找n_x和n_y。同时,将隐藏层的大小硬编码为4。

    # GRADED FUNCTION: layer_sizes
    
    def layer_sizes(X, Y):
        """
        Arguments:
        X -- input dataset of shape (input size, number of examples)
        Y -- labels of shape (output size, number of examples)
        
        Returns:
        n_x -- the size of the input layer
        n_h -- the size of the hidden layer
        n_y -- the size of the output layer
        """
        ### START CODE HERE ### (≈ 3 lines of code)
        n_x = X.shape[0] # size of input layer X是2X400,2是不是就是2个特征,红和蓝其中为1
        n_h = 4
        n_y = Y.shape[0] # size of output layer Y是1X400
        ### END CODE HERE ###
        return (n_x, n_h, n_y)
    X_assess, Y_assess = layer_sizes_test_case()
    (n_x, n_h, n_y) = layer_sizes(X_assess, Y_assess)
    print("The size of the input layer is: n_x = " + str(n_x))
    print("The size of the hidden layer is: n_h = " + str(n_h))
    print("The size of the output layer is: n_y = " + str(n_y))

    结果:

    The size of the input layer is: n_x = 5
    The size of the hidden layer is: n_h = 4
    The size of the output layer is: n_y = 2

    预期输出(这不是您将用于网络的大小,它们只是用于评估您刚刚编写的函数)。


    4.2 - Initialize the model's parameters(初始化模型的参数)

    练习:实现函数initialize_parameters()。

    说明:

    •确保参数大小正确。如有需要,请参考上面的神经网络图
    •您将用随机值初始化权重矩阵

      ◾使用:np.random.randn (a, b) * 0.01随机初始化一个矩阵的形状(a, b)。

    •将偏差向量初始化为零。

      ◾使用:np.zeros ((a, b))来初始化一个矩阵的形状与0 (a, b)。

    # 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:
        params -- 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(2) # we set up a seed so that your output matches ours although the initialization is random.
        
        ### 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
    n_x, n_h, n_y = initialize_parameters_test_case()
    
    parameters = initialize_parameters(n_x, n_h, n_y)
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))


    4.3 - The Loop(循环)

    Question: Implement forward_propagation().(问题:实现forward_propagation ()。)

    说明:

    •看看上面的分类器的数学表示。
    •可以使用函数sigmoid()。它是内置(导入)在笔记本电脑。
    •可以使用函数np.tanh()。它是numpy库的一部分。
    •你必须执行的步骤是:

    1、通过使用parameters[".."],从字典"parameters" (是initialize_parameters()的输出)中检索每个参数。
    2、实现向前传播。计算(你对训练集中所有例子的所有预测的向量)。


    •反向传播所需的值存储在“缓存”中。缓存将作为反向传播函数的输入

     向前传播:

    # GRADED FUNCTION: forward_propagation 先前传播
    
    def forward_propagation(X, parameters):
        """
        Argument:
        X -- input data of size (n_x, m)
        parameters -- python dictionary containing your parameters (output of initialization function)
        #parameters——包含参数的python字典(初始化函数的输出)
        
        Returns:
        A2 -- The sigmoid output of the second activation
        cache -- a dictionary containing "Z1", "A1", "Z2" and "A2"
        """
        # Retrieve each parameter from the dictionary "parameters" Retrieve恢复、检索、重新得到
        ### START CODE HERE ### (≈ 4 lines of code)
        W1 = parameters["W1"]
        b1 = parameters["b1"]
        W2 = parameters["W2"]
        b2 = parameters["b2"]
        ### END CODE HERE ###
        
        # Implement Forward Propagation to calculate A2 (probabilities)
        ### START CODE HERE ### (≈ 4 lines of code)
        Z1 = np.dot(W1, X) + b1
        A1 = np.tanh(Z1)
        Z2 = np.dot(W2, A1) + b2
        A2 = sigmoid(Z2)
        ### END CODE HERE ###
        
        assert(A2.shape == (1, X.shape[1]))
        
        cache = {"Z1": Z1,
                 "A1": A1,
                 "Z2": Z2,
                 "A2": A2}
        
        return A2, cache
    X_assess, parameters = forward_propagation_test_case()
    
    A2, cache = forward_propagation(X_assess, parameters)
    
    # Note: we use the mean here just to make sure that your output matches ours. 注意:我们在这里使用平均值只是为了确保您的输出与我们的匹配。
    print(np.mean(cache['Z1']) ,np.mean(cache['A1']),np.mean(cache['Z2']),np.mean(cache['A2']))

    现在你已经算出了A【2】(在Python中是变量“A2”),其中对于每个样本都包含了一个a【2】(i),你可以计算成本函数如下:

    练习:实现compute_cost()来计算代价J的值

    说明:•有很多方法可以实现交叉熵损失。为了帮助你,我们告诉你我们将如何实施:

    logprobs = np.multiply(np.log(A2),Y)

    cost = - np.sum(logprobs)              # no need to use a for loop!

    (you can use either np.multiply() and then np.sum() or directly np.dot()).

    # GRADED FUNCTION: compute_cost
    
    def compute_cost(A2, Y, parameters):
        """
        Computes the cross-entropy cost given in equation (13)
        
        Arguments:
        A2 -- The sigmoid output of the second activation, of shape (1, number of examples)
        Y -- "true" labels vector of shape (1, number of examples)
        parameters -- python dictionary containing your parameters W1, b1, W2 and b2
        
        Returns:
        cost -- cross-entropy cost given equation (13)
        """
        
        m = Y.shape[1] # number of example
    
        # Compute the cross-entropy cost
        ### START CODE HERE ### (≈ 2 lines of code)
        logprobs = np.multiply(np.log(A2), Y)
        cost = - np.sum(logprobs  + (1-Y) * np.log(1 - A2)) / m
        ### END CODE HERE ###
        
        cost = np.squeeze(cost)     # makes sure cost is the dimension we expect. 
                                    # E.g., turns [[17]] into 17 
        assert(isinstance(cost, float))
        
        return cost
    A2, Y_assess, parameters = compute_cost_test_case()
    
    print("cost = " + str(compute_cost(A2, Y_assess, parameters)))

    使用前向传播期间计算的缓存,现在可以实现后向传播。

    问题:实现函数backward_propagation()。

    说明:反向传播通常是深度学习中最难的部分。为了帮助你们,这里有一张关于反向传播的幻灯片。您需要使用这张幻灯片右边的六个方程,因为您正在构建一个向量化的实现

    提示:

    # GRADED FUNCTION: backward_propagation
    
    def backward_propagation(parameters, cache, X, Y):
        """
        Implement the backward propagation using the instructions above.
        
        Arguments:
        parameters -- python dictionary containing our parameters 
        cache -- a dictionary containing "Z1", "A1", "Z2" and "A2".
        X -- input data of shape (2, number of examples)
        Y -- "true" labels vector of shape (1, number of examples)
        
        Returns:
        grads -- python dictionary containing your gradients with respect to different parameters
        """
        m = X.shape[1]
        
        # First, retrieve W1 and W2 from the dictionary "parameters".
        ### START CODE HERE ### (≈ 2 lines of code)
        W1 = parameters["W1"]
        W2 = parameters["W2"]
        ### END CODE HERE ###
            
        # Retrieve also A1 and A2 from dictionary "cache".
        ### START CODE HERE ### (≈ 2 lines of code)
        A1 = cache["A1"]
        A2 = cache["A2"]
        ### END CODE HERE ###
        
        # Backward propagation: calculate dW1, db1, dW2, db2. 
        ### START CODE HERE ### (≈ 6 lines of code, corresponding to 6 equations on slide above)
        dZ2 = A2 - Y
        dW2 = np.dot(dZ2, A1.T) / m
        db2 = np.sum(dZ2, axis = 1, keepdims = True) / m
        dZ1 = np.multiply(W2.T * dZ2, (1 - np.power(A1, 2)))
        dW1 = np.dot(dZ1, X.T) / m
        db1 = np.sum(dZ1, axis = 1, keepdims = True) / m
        ### END CODE HERE ###
        
        grads = {"dW1": dW1,
                 "db1": db1,
                 "dW2": dW2,
                 "db2": db2}
        
        return grads
    parameters, cache, X_assess, Y_assess = backward_propagation_test_case()
    
    grads = backward_propagation(parameters, cache, X_assess, Y_assess)
    print ("dW1 = "+ str(grads["dW1"]))
    print ("db1 = "+ str(grads["db1"]))
    print ("dW2 = "+ str(grads["dW2"]))
    print ("db2 = "+ str(grads["db2"]))

    问题:实现更新规则。用梯度下降法。为了更新(W1、b1、W2、b2),必须使用(dW1、db1、dW2、db2)。

    一般梯度下降规则:式中,α为学习率,θ代表参数。

    说明:学习率好的梯度下降算法(收敛)和坏的学习率(发散)。图片由亚当·哈雷提供。

    # GRADED FUNCTION: update_parameters
    
    def update_parameters(parameters, grads, learning_rate = 1.2):
        """
        Updates parameters using the gradient descent update rule given above
        
        Arguments:
        parameters -- python dictionary containing your parameters 
        grads -- python dictionary containing your gradients 
        
        Returns:
        parameters -- python dictionary containing your updated parameters 
        """
        # Retrieve each parameter from the dictionary "parameters"
        ### START CODE HERE ### (≈ 4 lines of code)
        W1 = parameters["W1"]
        b1 = parameters["b1"]
        W2 = parameters["W2"]
        b2 = parameters["b2"]
        ### END CODE HERE ###
        
        # Retrieve each gradient from the dictionary "grads"
        ### START CODE HERE ### (≈ 4 lines of code)
        dW1 = grads["dW1"]
        db1 = grads["db1"]
        dW2 = grads["dW2"]
        db2 = grads["db2"]
        ## END CODE HERE ###
        
        # Update rule for each parameter
        ### START CODE HERE ### (≈ 4 lines of code)
        W1 -= learning_rate * dW1
        b1 -= learning_rate * db1
        W2 -= learning_rate * dW2
        b2 -= learning_rate * db2
        ### END CODE HERE ###
        
        parameters = {"W1": W1,
                      "b1": b1,
                      "W2": W2,
                      "b2": b2}
        
        return parameters
    parameters, grads = update_parameters_test_case()
    parameters = update_parameters(parameters, grads)
    
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))

    结果:


    4.4 - Integrate parts 4.1, 4.2 and 4.3 in nn_model() (4.4 -整合nn_model()中的4.1、4.2、4.3部分)

    问题:在nn_model()构建你的神经网络模型。

    说明:神经网络模型必须按照正确的顺序使用前面的函数。

     1 # GRADED FUNCTION: nn_model
     2 
     3 def nn_model(X, Y, n_h, num_iterations = 10000, print_cost=False):
     4     """
     5     Arguments:
     6     X -- dataset of shape (2, number of examples)
     7     Y -- labels of shape (1, number of examples)
     8     n_h -- size of the hidden layer
     9     num_iterations -- Number of iterations in gradient descent loop
    10     print_cost -- if True, print the cost every 1000 iterations
    11     
    12     Returns:
    13     parameters -- parameters learnt by the model. They can then be used to predict.
    14     """
    15     
    16     np.random.seed(3)
    17     n_x = layer_sizes(X, Y)[0]
    18     n_y = layer_sizes(X, Y)[2]
    19     
    20     # Initialize parameters, then retrieve W1, b1, W2, b2. Inputs: "n_x, n_h, n_y". Outputs = "W1, b1, W2, b2, parameters".
    21     ### START CODE HERE ### (≈ 5 lines of code)
    22     parameters = initialize_parameters(n_x, n_h, n_y)
    23     W1 = parameters["W1"]
    24     b1 = parameters["b1"]
    25     W2 = parameters["W2"]
    26     b2 = parameters["b2"]
    27     ### END CODE HERE ###
    28     
    29     # Loop (gradient descent)
    30 
    31     for i in range(0, num_iterations):
    32          
    33         ### START CODE HERE ### (≈ 4 lines of code)
    34         # Forward propagation. Inputs: "X, parameters". Outputs: "A2, cache".
    35         A2, cache = forward_propagation(X, parameters)
    36         
    37         # Cost function. Inputs: "A2, Y, parameters". Outputs: "cost".
    38         cost = compute_cost(A2, Y, parameters)
    39  
    40         # Backpropagation. Inputs: "parameters, cache, X, Y". Outputs: "grads".
    41         grads = backward_propagation(parameters, cache, X, Y)
    42  
    43         # Gradient descent parameter update. Inputs: "parameters, grads". Outputs: "parameters".
    44         parameters = update_parameters(parameters, grads)
    45         
    46         ### END CODE HERE ###
    47         
    48         # Print the cost every 1000 iterations
    49         if print_cost and i % 1000 == 0:
    50             print ("Cost after iteration %i: %f" %(i, cost))
    51         
    52         
    53 
    54     return parameters
    X_assess, Y_assess = nn_model_test_case()
    parameters = nn_model(X_assess, Y_assess, 4, num_iterations=10000, print_cost=False)
    print("W1 = " + str(parameters["W1"]))
    print("b1 = " + str(parameters["b1"]))
    print("W2 = " + str(parameters["W2"]))
    print("b2 = " + str(parameters["b2"]))

    结果:

     


     4.5 Predictions

     问题:通过构建predict()来使用您的模型进行预测。使用正向传播预测结果。

    提示:

    例如,如果您想根据阈值将矩阵X的项设置为0和1,您可以这样做:X_new = (X >阈值)

    # GRADED FUNCTION: predict
    
    def predict(parameters, X):
        """
        Using the learned parameters, predicts a class for each example in X
        
        Arguments:
        parameters -- python dictionary containing your parameters 
        X -- input data of size (n_x, m)
        
        Returns
        predictions -- vector of predictions of our model (red: 0 / blue: 1)
        """
        
        # Computes probabilities using forward propagation, and classifies to 0/1 using 0.5 as the threshold.
        ### START CODE HERE ### (≈ 2 lines of code)
        A2, cache = forward_propagation(X, parameters) #A2就是y hat
        predictions = np.round(A2)
        #round() 方法返回浮点数x的四舍五入值。
        ### END CODE HERE ###
        
        return predictions
    parameters, X_assess = predict_test_case()
    
    predictions = predict(parameters, X_assess)
    print("predictions mean = " + str(np.mean(predictions)))

    结果:

    现在是时候运行模型,看看它在平面数据集上的表现如何。运行下面的代码,用一个隐藏层来测试您的模型,nh隐藏的单位。

    # Build a model with a n_h-dimensional hidden layer
    parameters = nn_model(X, Y, n_h = 4, num_iterations = 10000, print_cost=True) #这里n_h = 4 是隐藏层的神经元个数哦
    
    # Plot the decision boundary
    plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
    plt.title("Decision Boundary for hidden layer size " + str(4))

    结果:

     

    # Print accuracy
    predictions = predict(parameters, X)
    print ('Accuracy: %d' % float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100) + '%')

    结果:

    逻辑回归相比,它的准确性真的很高。模特学会了花的叶子图案!  与逻辑回归不同,神经网络能够学习甚至高度非线性的决策边界

    现在,让我们尝试几种隐藏图层大小。


    4.6 - Tuning hidden layer size (optional/ungraded exercise) (4.6 -调整隐藏层大小(可选/未分级练习))

    运行以下代码。可能需要1-2分钟。您将观察不同隐藏层大小的模型的不同行为。

    # This may take about 2 minutes to run
    
    plt.figure(figsize=(16, 32))
    hidden_layer_sizes = [1, 2, 3, 4, 5, 10, 20]
    for i, n_h in enumerate(hidden_layer_sizes):
        plt.subplot(5, 2, i+1)
        plt.title('Hidden Layer of size %d' % n_h)
        parameters = nn_model(X, Y, n_h, num_iterations = 5000)
        plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
        predictions = predict(parameters, X)
        accuracy = float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100)
        print ("Accuracy for {} hidden units: {} %".format(n_h, accuracy))

    结果:

     解释:

    较大的模型(隐藏单元更多)能够更好地拟合训练集,直到最终最大的模型对数据进行过拟合
    •最好的隐藏层大小似乎是在n_h = 5左右。实际上,这里的值似乎很适合数据,而不会引起明显的过拟合。
    •稍后您还将学习正则化,它可以让您使用非常大的模型(如n_h = 50)而不会过度拟合。

    可选的问题:

    注意:记得提交作业,但点击右上角的蓝色“提交作业”按钮。

    一些可选的/未评分的问题,你可以探索,如果你愿意:

    •将tanh激活改为sigmoid激活或ReLU激活会发生什么?
    •玩学习率。会发生什么呢?
    •如果我们改变数据集会怎么样?(参见下面的第5部分!)

    **你已经学会:** -建立一个完整的带有隐含层的神经网络-充分利用非线性单元-实现前向传播和后向传播,训练一个神经网络-看看改变隐含层大小的影响,包括过拟合

    干得漂亮!!!


    5) Performance on other datasets (5)其他数据集的性能)

    如果需要,可以为以下每个数据集重新运行整个笔记本(减去数据集部分)。

    # Datasets
    noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure = load_extra_datasets()
    
    datasets = {"noisy_circles": noisy_circles,
                "noisy_moons": noisy_moons,
                "blobs": blobs,
                "gaussian_quantiles": gaussian_quantiles}
    
    ### START CODE HERE ### (choose your dataset)
    dataset = "gaussian_quantiles"
    ### END CODE HERE ###
    
    X, Y = datasets[dataset]
    X, Y = X.T, Y.reshape(1, Y.shape[0])
    
    # make blobs binary
    if dataset == "blobs":
        Y = Y%2
    
    # Visualize the data
    plt.scatter(X[0, :], X[1, :], c= np.squeeze(Y), s=40, cmap=plt.cm.Spectral);

    结果:

     祝贺你完成了这个编程任务!

    Reference:

    作者:Agiroy_70

    本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。

    博主的文章主要是记录一些学习笔记、作业等。文章来源也已表明,由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。

    博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的文章,请原谅博主成为一个无耻的文档搬运工!

  • 相关阅读:
    树链剖分 关于点权与边权的转换
    2018 CCPC 吉林站 H Lovers || HDU 6562 (线段树哦)
    统计学习方法(一)概念
    python学习心得(三)
    python学习心得
    Python学习:基本概念
    Python学习(一)
    SparkMLlib聚类学习之KMeans聚类
    SparkMLlib回归算法之决策树
    SparkMLlib学习之线性回归
  • 原文地址:https://www.cnblogs.com/hale547/p/13355938.html
Copyright © 2020-2023  润新知