深入MNIST(1)

来源:互联网 发布:电玩游戏平台源码 编辑:程序博客网 时间:2024/06/05 08:41

Tensorflow是什么?它本身是一个用于大规模数值计算的库。但是它擅长的方面之一九十实现以及训练深度神经网络。这一节中将会重新实现手势识别的例子,但是重点是学习如果构建一个深度卷积神经网络。
安装
加载MNIST数据集,启动一个Tensorflow的session。
加载MNIST
启动Python,
导入:import tensorflow.examples.tutorials.mnist.input_data as input_data
加载:mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True)
这里的mnist是一个轻量级的类。它以Numpy数组的形式存储着训练/校验/测试的数据集。同时提供了一个函数,用于迭代中的获得minibatch。

运行TensorFlow的Interactive Session
TensorFlow依赖于一个高效的C++后端来进行计算。session就是与这个后端的连接。一般而言,使用TensorFlow程序的流程是先创建一个图,然后在session中启动它。
不过,使用InteractiveSession类会更加的方便。通过它可以更加灵活的构建代码,可以做到在运行图的时候,插入一些计算图,这些计算图都有某些operations构成。这对于使用交互式环境如IPython的人来说是非常便利的。如果我们决定不使用InteractiveSession的话,那么就需要在启动session之前构建整个计算图,然后启动该计算图。
这里使用InteractiveSession:
import tensorflow as tf
sess = tf.InteractiveSession()

计算图
为了让Python的数值计算过程更为高效,通常会借用外部语言来进行计算,但切换的开销仍然很大。而在GPU和分布式环境中,这个开销会更大。TensorFlow通过改进解决了这个问题。TF不采用在外部运行某个耗时的操作,而是先描述了一个交互操作图,然后将其运行在Python外部。这个做法和Theano或Torch类似。
因此,Python代码的主要作用是构建这个可以在外部运行的计算图,以及安排计算图的那一部分应该被运行。

构建Softmax回归模型
这一节建立一个有一个线性层的softmax回归模型。下一节将其扩展为一个拥有多层卷积网络的softmax回归模型
占位符
通过为输入图像和目标输出类别创建节点,来开始构建计算图:
x = tf.placeholder(“float”, shape=[None, 784])
y_ = tf.placeholder(“float”, shape=[None, 10])
这里的x和y_都只是占位符,可以在运行某一计算时再输入。
这里的图片x是一个2维的浮点数张量,这里,分配给他们的shape为[None,784],其中784是是MNIST图片的展开维度。None表示大小不确定,在这里作为第一个维度值,用以指代batch的大小,意思是x的数量是不定的。同样输出类别y_的含义类似。
placeholder的shape参数是可选的,用以捕捉由于维度不一致导致的错误。

变量
现在为模型定义权重w和偏置b.可以将他们当作额外的输入量,不过TF还有更好的处理方式,那就是变量。一个变量代表着TF计算图的一个值,能够在计算过程中使用,甚至进行修改,一般用Variable表示。
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
调用tf.Variable的时候传入初始值。在这个例子中,我们把w和b都初始化为零向量。w为784*10的矩阵,b是一个10维分量。
一个变量要通过session初始化后才能在session中使用。这一初始化步骤为,为初始值指定具体值,并将其分配给每个变量,可以一次性为所有的变量完成次操作:
sess.run(tf.initialize_all_variables())

类别预测与损失函数
同样,用一行来实现你回归模型,即图片x乘以权重w加上偏置b,然后计算每个分类的softmax概率值:
y = tf.nn.softmax(tf.matmul(x,W) + b)
接下来为训练过程指定最小化损失函数,我们的损失函数是目标类别和预测类别之间的交叉熵:cross_entropy = -tf.reduce_sum(y_*tf.log(y))
其中,tf.reduce_sum的意思是把minibatch里的每张图片的交叉熵都加起来,所以计算的交叉熵是指的整个minibatch的。

训练模型
定义好模型和所用的损失参数之后,训练过程其实很简单,TensorFlow这时已经知道整个计算图了,它可以使用自动微分法找到对于各个变量的损失的梯度值。TensorFlow本身有大量的内置的优化算法,鉴于未来是算法的天下,我们对算法的学习需要抓紧了,我们用最速下降法让交叉熵下降,步长为0.01:
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
这一行的意思其实是往计算图上添加了一个新操作,其中包括计算梯度,计算每个参数的步长变化,并且计算出新的参数值。
返回的tran_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复的运行train_step来完成。
for i in range(1000):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1]})
意思是每次迭代,加载50个训练样本,然后执行train_step,并通过feed_dict将x和y_张量占位符用训练数据替代。需要注意的是,在计算图中,你可以使用feed_dict来替代任何张量,并不仅限于替换占位符。

评估模型
找出预测正确的模型标签。tf.max是一个非常有用的函数,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签用0和1组成,因此最大值所在的索引位置就是类别标签,比如tf.argmax(y,1)返回的是模型对于任一输入x预测的标签值,而tf.argmax(y_,1)则代表正确标签,然后用tf.equal来检测我们的预测是否匹配:
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
此时的返回是一个希尔数组,转化为浮点型准确率:
accuracy = tf.reduce_mean(tf.cast(correct_prediction, “float”))
测试并打印:
print accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels})

下一步构建一个多层卷积网络来改善效果。

原创粉丝点击