吴恩达深度学习——第一课第三周课后编程作业Debug经历

Miss思的踩坑历程

    • DeepLearning Course1 Week3
    • 本次作业Bug
    • 给自己挖的坑(一个起因很二表现很诡异的bug)
    • 心得与体会

DeepLearning Course1 Week3

学吴恩达的深度学习课程,自然是要认真完成课后编程题的,于是贫穷的我扫荡到了整套的课后习题,开始了我的编程之旅。
然后,面对这节课的坑,我不仅没爬出来,还给自己挖了一个更深的。。。
仅以此文,记录下我艰难的Debug经历,也同时提醒自己,在深度学习的练习中,时刻警醒和谨记向量维度的重要性。

本次作业Bug

  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)

给自己挖的坑(一个起因很二表现很诡异的bug)

一个调试了一下午的Bug,该bug的诡异之处在于,其他地方的运行结果都准确无误,却在这一行单单出错,且回到前向传播函数,A2.shape与X.shape这个等式也是相等的…
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第1张图片
原因在于调用函数的时候没有严格按照参数格式传入,把后把Y改为Y.reshape(1,400)就可以运行成功(然而貌似治标不治本):
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第2张图片
原因在于nn_model( )的传入参数的shape是固定的,应该是(1,400)
那么,为什么Y的shape变了?什么时候变的?
这就需要对代码更深层的理解了。

Y – labels of shape (output size, number of examples)
n_x – size of the input layer
n_y – the size of the output layer

吴恩达深度学习——第一课第三周课后编程作业Debug经历_第3张图片

对于我们想要构建的模型,是输入层为2,隐层为4,输出层为1的神经网络,而Y.shape从起初导入就为(1,400)

吴恩达深度学习——第一课第三周课后编程作业Debug经历_第4张图片模型构建:1.初始化参数W1,b1,W2,b2,放入parameters字典
2.The Loop—forward_propagation()【注意,这里是出错的地方!】

错误:
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第5张图片 吴恩达深度学习——第一课第三周课后编程作业Debug经历_第6张图片 可以看到: 此时,A2.shape == (1,X.shape[1])

    这里要注意,打印出的cost是用测试数据计算的,因此Y.shape[1](即样本数量)为3,本题应为400!
    与上面错误相比,这里将Y改为Y.shape[1],即严格遵循参数输入。
    我灵机一动,直接输入Y,惊讶的发现,也可以正确运行!
	这说明在上面某个地方,Y的shape被我更改错了,所以在运行模型时必须强制reshape才可以!

我再从头看一遍:

  1. 导入库->载入数据->可视化数据(c=Y改为c=np.squeeze(Y))->打出X和Y的shape
    2.使用sklearn先用LogisticRegression分一波->在画图时依旧要注意改Y为np.squeeze(Y)->准确率为47%
    3.构造浅层神经网络(2,4,1)
    1)定义结构(n_x为输入层数,n_h为隐层数,n_y为输出层数)
    2)初始化参数W1,b1,W2,b2
    3)进循环:前向传播(计算一波Z1,A1,Z2,A2,存进cache里,返回A2,cache,按理说这里计算不出错,就不会有shape的问题),经计算A2.shape为(1,400);
    计算损失函数,这里Y.shape依然为(1,400);
    后向传播(计算一波dZ2,dW2,db2,dZ1,dW1,db1,放进grads里;
    更新参数,学到最合适的w1,b1,w2,b2
    4)模型整合:初始化参数,此时再打印Y.shape依旧(1,400)【离成功不远啦!】,进循环:计算一波前向传播,计算损失函数,计算一波后向传播,更新参数,学到最佳参数然后返回
    5)进行预测:此时直接输入parameters = nn_model(X, Y, n_h = 4, num_iterations = 10000, print_cost=True),无需强制reshape 就可学到结果!!!
所以,肯定是在某一步骤,我更改了Y的shape,导致模型运行不出来,一定是这样

因此我打算在打开那个错误的文件夹看一波

吴恩达深度学习——第一课第三周课后编程作业Debug经历_第7张图片Y是怎么偷偷变成(400,)的?

未完待续

次日起床,继续debug

发现错误在此:使用plot_decision_boundary函数时,将np.squeeze(Y)赋值给了Y,使得Y的shape变成了(400,)

吴恩达深度学习——第一课第三周课后编程作业Debug经历_第8张图片
返回数据集导入处,重新运行后发现,Y.shape如此就不会改变
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第9张图片
至于下面运行的所有结果都是对的,是因为下面使用的数据都是测试集里的测试数据!

在跑模型时数据成了训练集,而Y又是一个错误的shape,当然会报错,模型准确率也大大下降。

成功输出正确结果:
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第10张图片使用其他数据集跑出来的效果:
吴恩达深度学习——第一课第三周课后编程作业Debug经历_第11张图片

心得与体会

至此,困扰我一个下午的bug调试完毕。

现在让我们回到那个bug的诡异之处:

1.其他地方的运行结果都准确无误——因为其他地方都是使用测试数据作为数据
2.却在这一行单单出错——因为实际模型传入的参数是训练集中的X,Y,且Y已经更改了维度
3.且回到前向传播函数,A2.shape与X.shape这个等式也是相等的——因为在那个函数中,A2.shape与X.shape都是使用测试数据得出的结果,当然都是(1,3)

起因在于绘制图形此函数的参数要求,详见:https://blog.csdn.net/zenghaitao0128/article/details/78512715

而最坑之处在于自己自作聪明加了新的代码,原编程传入模型参数的nn_model(X,Y,….)是没有问题的!

因此这份作业的最大bug就是绘图时的错误(c=np.squeeze(Y), plot_decison_boundary(……,np.squeeze(Y))

谁曾想过会导致如此诡异的错误,又如此简单的“删掉一行代码”就可解决?
谁又曾想经过这一波又一波反复的查看,自己对神经网络的理解会变得更加深入?
这也正是作业和Debug存在的意义吧。

在这里特此感谢被我叨扰一圈的小天才,睿,万,强和找出Bug所在的飞等小伙伴们,谢谢你们不厌其烦的帮我一起看代码和调试,也感谢坚持不放弃的自己✧(≖ ◡ ≖✿)嘿嘿

神奇的CS,受教了!我会继续前行!

2018/12/15 Miss思于北京

你可能感兴趣的:(深度学习)