本文是讲关于tensorflow基于mnist的手写数字的识别代码详解,主要分为2个部分
参考链接:
https://www.youtube.com/watch?v=BhpvH5DuVu8&index=46&list=PLQVvvaa0QuDfKTOs3Keq_kaG2P55YRn5vhttps://pythonprogramming.net/tensorflow-deep-neural-network-machine-learning-tutorial/
1. 程序中具体函数详细解释
首先我们先回顾上一篇的博文的函数和知识点,实现一个两个常量的乘法运算,但是中间包含了tensorflow最基本的操作:
- 构造模型
- 启动Session
- 带入值运算
|
|
那么最后的结果就是5X6=30,但是这个30是在tensor里面的,所以会显示成[30]
好,那么快速来说明这篇基础代码中所需要的函数和说明吧。
首先,我们需要了解一下我们整个代码的逻辑结构:
我们的目的是,使用我们现有的数据去训练我们的神经网络(training data去不断的feed我们的NN),然后,使用test data去测试我们这个NN的识别率是多少。
注:我们这里有三层hidden layer
如何训练自己的神经网络(转自知乎答案,简单形象又有趣的讲解神经网络):
最开始输入层输入特征向量,网络层层计算获得输出,输出层发现输出的正确的类号不一样,这时它就让最后一层神经元进行参数调整,最后一层神经元不仅自己调整参数,还会勒令它的倒数第二层神经元调整,层层往回退着调整(这就完成了一个epoch)。经过调整后的网络会在样本中继续测试,如果输出还是老分错,继续来一轮回退调整,直到网络输出满意为止。
那整体训练的过程就是:
1.首先取出我们的input data(batch_size个数据/1个iteration/第一次epoch的前半段)传递给hidden layer1。通过hidden layer1的W和b运算出了l1,得到:
|
|
|
|
把hidden layer1的输出值当成hidden layer2的输入值。之前要经过activation function(激活函数,这一个可以看看这块参考资料:https://www.zhihu.com/question/22334626)
2.以此类推,把hidden layer2 输出值(经过activation function后)当成hidden layer3的输入值,把hidden layer3的输出值(经过activation function后)当成output layer的输入值。
3.然后得到的结果与预期结果进行比较,得到一个loss function,然后使用optimaizer function(一般我们使用SGD)去最逐步减小我们的loss function(一般就是使用backpropagation算法,去一点一点得使得我们参数(hidden layer的weight和bias)接近我们的正确答案)。
这就是我们整体的一个训练过程,中间还有一些概念需要理解:
1.在backpropagation的时候,我们会有一个learning rate(学习率)的概念,它是一个loss function在调解我们的参数时快慢的一个影响因素:
学习率决定了权值的更新速度,设置太大会使权值越过最优值,太小会使下降速度过慢,算法长时间不能收敛。靠人为干预调整参数需要不断的调整学习率。
2.1个epoch的时间=feed+backpro的过程,不能设置太多,有时候会overfitting。
最后,在经历过所有的epoch之后,我们就可以拿我们的test data去测试整改神经网络的准确率了。
是不是很意外,很特么惊喜,说了这么多,我都等不及了,赶紧看看如何用代码实现吧。
1. import data:
|
|
这一块就是导入我们所需要的dataset(数据包中就已经处理好了,可以直接用)
2. 声明模型中变量:
|
|
n_classes: 就是我们的标签数,有10个(0~9)所以是10个
batch_size: the number of samples for each batch
这是我网上找的关于batch_size的解释。
我的理解是:每次我们直接的进行神经网络的训练的时候,需要给我们的neural network 去feed很多数据量,那么这个batch_size就是指每次去feed这些数据量的大小。(每次训练在训练集中取batchsize个样本训练)
这里规定100,但是其实规定多少都是很有讲究的,大了的话,太耗时间,小了的话,训练速度更是缓慢。
如何选用合适的batch_size,更是以后调参的关键。
参考资料:
http://blog.csdn.net/ycheng_sjtu/article/details/49804041
这里顺便提一下其他几个词: epoch,iteration
epoch:
1个epoch相当于使用所有数据集(所有样本)去训练NN(neural net work,以下省略)一次。(1epoch=feed+backpro)
iteration:
1个iteration等于使用batchsize个样本训练一次(这里我是引用其他人的理解)
placeholder
上一篇文章我已经讲解了对于placeholder的理解和看法.
这里的placeholder的X指的是以后我们会填充的数据集(即一张一张的手写图片:dataset)
这里的Y值的就是这些数据集所对应的label(标签)
3. 定义NN结构:
|
|
这一段是设计我们的神经网络,也就是tensorflow中的第一步:构建flow graph,把NN中的结构和里面所需要的参数规划好(input data作为hidden layer1的输入,经过激活函数(这里用的是relu)后,hidden layer1的输出作为hidden layer2的输入…etc)。
4. 训练神经网络
我们已经实现了我们的基本网络结构,我们需要去设置我们的training process。
调用NN模型
那么首先,我们要在训练NN的函数中,调用我们之前已经声明好的NN
|
|
然后我们会产生一个预测值,是根据数据的经过我们的neural_network_model函数后,得到的一个output值。
那么,我们可以看到我们的输出,是one hot array,就是[0,0,0,1,0,0,0,0,0,0](如果答案是3)。
损失函数
现在我们去创造一个损失的变量,是测量我们与实际值差了多少。
cost=tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits =prediction,labels =y) )
(
这里要强调一下
tf.nn.softmax_cross_entropy_with_logits
这里强调一下这个函数的作用。
tf.nn.softmax_cross_entropy_with_logits computes the cross entropy of the result after applying the softmax function (but it does it all together in a more mathematically careful way). It’s similar to the result of:
sm = tf.nn.softmax(x)
ce = cross_entropy(sm)or:
It is only used during training. The logits are the unnormalized log probabilities output the model (the values output before the softmax normalization is applied to them).官网解释:
Computes softmax cross entropy between logits and labels.
Measures the probability error in discrete classification tasks in which the classes are mutually exclusive (each entry is in exactly one class).https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits
)
然后这个变量会通过不断的操作weight去不断的变小。
利用AdamOptimizer函数去缩小损失函数。(比较常用的函数之一,类似于SGD或mini-batch GD,AdaGrad等等)
|
|
在AdamOptimizer函数中,可以设定我们的学习率,这里我们使用默认的0.001
启动Session
设置好我们的参数以后,我们需要启动Session并设置我们的epoch数(1个epoch=feed+backpropagation)
|
|
在session中,所有变量要初始化才能使用(上一篇博客详细说明过)
主要训练过程
|
|
这是整篇过程中最主要的代码段,下面我们来进行下详细的解释。
首先解释一下python中for _ 的用法:
|
|
那么在python中对于无需关注其实际含义的变量可以用来代替。
(这次for 循环结束后,就不用管了,我们只要这个循环的过程)
对于每一个epoch来说,我们需要把batch个数目的data放入NN中,然后去优化还有调成weight去减少cost。
设置第一个for做epoch循环.
第二个for做一个epoch中batch_size个data的处理:
每一次for调用一次,调用cost和optimizer去改变weight的值。<br>
评估当前在第几个epoch中,损失量是多少。
在我们训练完weight之后,得到的output要把一开始的label(y)进行比较,确定是否正确,然后再计算准确率。
2. 实现代码
整块代码如下:
|
|