参考的文章《零基础入门深度学习(3) - 神经网络和反向传播算法》:https://www.zybuluo.com/hanbingtao/note/476663
接上一篇,参考文章里面这一部分作者太不负责任了。。。代码没写全就跑路了。。这一部分分为两块:传统方法代码,向量化方法代码。
传统方法篇
先介绍传统方法。再次吐槽,作者给的读取图像的代码,太不合时宜了,Python2.7简直了,我用Python3.6怎么跑也跑不通,后来发现了这个,(可能适用于Py3.5)
这篇文章作者也是用Python3(3.5)在跑原代码也遇到了问题,他自己解决了,我本以为看到了一线生机,激动得我不要不要的,谁成想3.6和3.5也是难以逾越的鸿沟。。。我又一次陷入了无奈中,最后我忽然想到了git hub,果不其然,找到了另一种读取mnist数据集的方法。。。github万岁!!!放链接!
github:https://github.com/sivapvarma/MNIST.py/blob/master/mnist.py
我copy了代码做了些许修改和标注:
github:https://github.com/leiseraiesecqd/DL/blob/master/read.py
然后就是要分析一下mnist数据集到底长啥样:
train_data_set,
train_labels
test_data_set,
test_labels
数据类型全部是:
我们读取train_set中的一张,探索其结构(只是截取了部分截图):是一个28*28的结构,也就是一个大[ ]里有28个小[ ],每个小[ ]里面有28个元素。train_set有60000个这样的大[ ]。
我们读取train_label中前五个元素:可见是个1*60000的结构,也就是一个[ ]里有60000个元素组成。
目前,对于dataset和label我们没动。接下来,要reshap了,这是一门学问!!!务必要自己学会探索。先说一下为啥要reshape,因为我们的网络结构定义为输入层784个节点,输出层10个节点。
(1)dataset的处理
将每张图片展成1*728的向量。train_data_set[0].reshape(1,784),取一张照片然后可以看到(截取了部分)如下图:也就是一个大[ ]里面有一个小[ ],这个小[ ]里有784个元素。下一个问题,对整个dataset怎么处理?用 train_data_set.reshape(60000,784),结构变成了一个大[ ]里面有60000个小[ ],每个小[ ]有784的元素。整个数据集shape是(60000,784).
(2)label的处理
接下来,我们需要对labe做两步处理。
第一、进行one-hot encoding,也就是那个norm函数,是每个元素表示成,如[0,1,0,0,0,0,0,0,0,0,0]的结构,十个元素对应输出层的10个节点,这样子我们再取train_label的前五个元素,就变成如图。一个大[ ]里有60000个小[ ],每个小[ ]里面有10个有元素。此时对于整个数据集,它的shape是(60000,10)
第二、reshape变形。我们取onehot处理后的数据的第一个数据。train_labels[0].reshap(10,1),如图:[ ]中每个元素都加了[ ] .这种数据才是我们需要的。而不是上图那种,因为涉及到每个元素要和对应的每个输出节点的值相减。那么如何reshape全部呢?答案不是train_labels.reshap(10,60000),而是train_labels.reshape(60000,10,1). 显然,此时整个数据集shape是(60000,10,1)。
休息一下,让我们总结一下(10,)和(10,1)的区别:
前者:[ 1,2,3,4,5]
后者:[[1],[2],[3],[4],[5]]
小结:对于深度学习框架,tensorflow。我们经常调侃,每个tensor都在flow。其实对于数据结构的理解相当重要,数据在网络里面是怎么跑的,这个理解是很重要的。拿本例子来说,输入train_set是一个60000*784的结构,每次输入,都输入一张照片,即一个元素,这个元素里有784个数据,对应输入层784个节点;对应的,trian_label是一个60000*10*1的结构,每次输入一个元素,这个元素里有10个数据,对应输出层10个节点。归纳起来,系统是一个一个样本的跑,一个样本包括一张照片和它对应的label。test的样本同理。
关于数据集我们就讲这么多。下面就是另一个坑。关于我们之前写好的那个network,他其实是跑不通的。。。作者太不负责任了。主要问题是networ.predict它返回的是一个map,这样会和我们mnisy.py里面evaluate函数代码不匹配,所以我做了修改network2.0.py,主要是把predict函数返回做了修改,使它返回预测值,而不是一个map。而中间过程真的是特别心塞,说到底,就是我对之前的作者写的network知识照葫芦画瓢,没有真正理解他每一步是怎么跑的。具体结构解析在我的上一篇文章里有。http://www.jianshu.com/writer#/notebooks/17670616/notes/18346188
再唠叨一句,迭代次数和训练的样本数不是一个东西,迭代一次,会把你输入的样本数跑完。而不是迭代一次,跑一个样本。比如:我输入20个样本,迭代一次,那么我就把这20样本跑完了,这样算一完成一次迭代。还有,迭代次数设置是在训练的时候,测试时不用迭代,因为就跑一遍得出准确率。
最后附一下我的代码(基于Py3.6)https://github.com/leiseraiesecqd/DL,
本节内容参考里面的read+network2.0.py+mnist.py
提示一下,由于cpu实在是弱鸡,建议大家跑程序的时候先训练一个样本,测试一个样本;如果能跑通,再训练10张,测试10张。这样就差不多了,重在理解。。如果你妄想把60000个训练集训练完,把10000个测试集测试完。那就等到几年后吧。。。
ps:下一节我们讲向量化编程。会使效率提升很多。
网友评论