吴恩达深度学习第一课第三周单隐层神经网络实现,相关文件、数据集下载以及bug修改心得

最近在学习吴恩达老师深度学习的课程,实现了单隐藏层神经网络的实现,现在将自己在编程过程中遇到的问题记录下。
先将需要用到文件的分享
链接:https://pan.baidu.com/s/148VvXV-SWW-PrFS7mVK_oA 密码:rkk7
导入需要的库

import numpy as np
#Python绘制图形的库
import matplotlib.pyplot as plt
#testCases提供了一些测试示例来评估函数的正确性
from testCases import *
# sklearn为数据挖掘和数据分析提供了简单而有效的工具。
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import   plot_decision_boundary , sigmoid , load_planar_dataset,load_extra_datasets
np.random.seed(1)

对于每一个库的作用,我都加以解释了。需要注意的是我们添加了一个np.random.seed(1)种子,添加这句话的目的以及使用方法,可以参考我上一篇博客,这里不再赘述。

2.导入数据集以及可视化数据集

#获取要处理的数据集
X , Y=load_planar_dataset()
print(X.shape,Y.shape)
#可视化数据集
plt.scatter(X[0,:],X[1,:],c=np.squeeze(Y),s=40,cmap=plt.cm.Spectral)
shape_X=X.shape
shape_Y=Y.shape
m=shape_X[1]

在这里要注意,吴恩达老师在下面这段代码中c=Y,这是不正确的,应该改成c=np.squeeze(Y)

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

数据导入好之后,我们可以直接用sklearn内置的函数检查线性回归在数据集上的表现

clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X.T, Y.T)
plot_decision_boundary(lambda x: clf.predict(x), X,Y.ravel())
plt.title("Logistic Regression")
plt.show()
# Print accuracy
LR_predictions = clf.predict(X.T)
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)")

在这里同时需要注意,不然会有bug出现。

plot_decision_boundary(lambda x: clf.predict(x), X,Y.ravel())

我们来看一下这段代码,如果我们按照吴恩达老师给的讲解中直接使用

plot_decision_boundary(lambda x: clf.predict(x), X,Y)

会发现有警告,图像也画不出来,我们根据警告的提示修改代码,至于为什么要这么修改,我暂时的理解是因为这个函数的参数的限定,如果以后深入学习了发现有理解不对的,再回来修改。同时呢,我一开始直接用

Y=Y.ravel()

这样会导致Y的维数发生改变,会导致后面使用模型时输入的参数不匹配,导致出错。当然你也可以这样修改,不过在使用模型时记得reshape一下Y的维度。

下图为在线性回归下的表现:
吴恩达深度学习第一课第三周单隐层神经网络实现,相关文件、数据集下载以及bug修改心得_第1张图片
在这里插入图片描述

我们可以看出效果是非常不好的。所以我们要考虑使用其他的模型,接下来就让我们一起实现第一个单隐藏层的神经网络模型吧。
首先我们定义神经网络结构

def layer_sizes(X,Y):
    n_x=X.shape[0]
    n_h=4
    n_y=Y.shape[0]
    return (n_x,n_h,n_y)

为了便于理解,我来说明一下语句含义,n_x:输入单元;n_h=4:隐藏层大小;n_y:输出单元。

初始化模型的参数

def initialize_parameters(n_x,n_h,n_y):
    np.random.seed(2)
    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

对于如何初始化参数,吴恩达老师的视频中已经做了详细的说明,可以参照视频中的讲解。

-实现正向传播

def forward_propagation(X,parameters):
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]

    Z1 = np.dot(W1,X)+b1
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2,A1)+b2
    A2 = sigmoid(Z2)
    assert (A2.shape == (1,X.shape[1]))
    cache = {"Z1":Z1,
             "A1":A1,
             "Z2":Z2,
             "A2":A2}
    return A2,cache

对于如何实现正向传播,吴恩达老师的视频中也已经做了详细的说明,可以参照视频中的讲解。

计算损失

def computer_cost(A2,Y,parameters):
    m = Y.shape[1]
    logprobs = Y * np.log(A2) + (1-Y)* np.log(1-A2)
    cost = -1/m * np.sum(logprobs)
    cost = np.squeeze(cost)
    assert (isinstance(cost,float))
    return cost
A2, Y_assess, parameters = compute_cost_test_case()

print("cost = " + str(computer_cost(A2, Y_assess, parameters)))

在这里需要理解的就是cost = np.squeeze(cost),为了实现降维,因为我们cost想要的是一个数值。

实现反向传播以获得梯度

def backward_propagation(parameters,cache,X,Y):
    m=X.shape[1]
    W1 = parameters["W1"]
    W2 = parameters["W2"]

    A1 = cache["A1"]
    A2 = cache["A2"]

    dZ2 = A2-Y
    dW2 = 1/m * np.dot(dZ2,A1.T)
    db2 = 1/m * np.sum(dZ2,axis=1,keepdims=True)
    dZ1 = np.dot(W2.T,dZ2)*(1-np.power(A1,2))
    dW1 = 1/m * np.dot(dZ1 , X.T)
    db1 = 1/m * np.sum(dZ1,axis=1,keepdims=True)
    grads = { "dW1":dW1,
              "db1": db1,
              "dW2":dW2,
              "db2":db2}
    return grads

更新参数(梯度下降)

def update_parameters(parameters,grads,learning_rate = 1.2):
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    dW1 = grads["dW1"]
    db1 = grads["db1"]
    dW2 = grads["dW2"]
    db2 = grads["db2"]

    W1 = W1 - learning_rate * dW1
    b1 = b1 - learning_rate * db1
    W2 = W2 - learning_rate * dW2
    b2 = b2 - learning_rate * db2
    parameters = {"W1":W1,
                  "b1":b1,
                  "W2":W2,
                  "b2":b2}
    return parameters

创建模型

def nn_model(X,Y,n_h,num_iterations = 10000, print_cost=False):
    np.random.seed(3)
    n_x = layer_sizes(X,Y)[0]
    n_y = layer_sizes(X,Y)[2]
    parameters = initialize_parameters(n_x,n_h,n_y)
    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]


    for i in range(0, num_iterations):
        A2,cache = forward_propagation(X,parameters)
        cost = computer_cost(A2,Y,parameters)
        grads = backward_propagation(parameters,cache,X,Y)
        parameters = update_parameters(parameters,grads)
        if print_cost and i % 1000 == 0:
            print("cost after iteration %i: %f" % (i, cost))

    return parameters

预测

def predict(parameters,X):
    A2,cache = forward_propagation(X,parameters)
    predictions = np.round(A2)
    return predictions

接下来就可以训练啦

parameters, X_assess = predict_test_case()
predictions = predict(parameters, X_assess)
print("predictions mean = " + str(np.mean(predictions)))
#单隐藏层
parameters = nn_model(X,Y, n_h = 4, num_iterations = 10000, print_cost=True)
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y.ravel())
plt.title("Decision Boundary for hidden layer size " + str(4))
plt.show()
predictions=predict(parameters,X)
print("Accuracy:%d" % float((np.dot(Y,predictions.T)+np.dot(1-Y,1-predictions.T))/float(Y.size)*100)+"%")

吴恩达深度学习第一课第三周单隐层神经网络实现,相关文件、数据集下载以及bug修改心得_第2张图片
在这里插入图片描述

我们可以看到效果是非常好的,准确率达到了90%

他作业中还比对了不同隐藏层大小对模型效果的影响,当隐藏层过多时就会出现过拟合,代码如下:

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.ravel())
    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))
    plt.show()

综上就是我在完成课后作业过程中遇到的一些问题以及代码分享。初学深度学习,多有理解误差,欢迎指正。

你可能感兴趣的:(深度学习第三周,数据集分享,BUG调试)