工作中需要实现 CNN、RNN 模型,于是开始学习 TensorFlow。这是第一篇,MNIST的实战。官方文档讲的很详细,这里我不过是用我的思路整理一遍,方便日后的查阅。
TensorFlow 介绍
综述
TensorFlow 是一个编程系统, 使用图来表示计算任务. 图中的节点被称之为 op (operation 的缩写). 一个 op 获得 0 个或多个 Tensor, 执行计算, 产生 0 个或多个 Tensor. 每个 Tensor 是一个类型化的多维数组. 例如, 你可以将一小组图像集表示为一个四维浮点数数组, 这四个维度分别是 [batch, height, width, channels].
一个 TensorFlow 图描述了计算的过程. 为了进行计算, 图必须在 会话 里被启动. 会话 将图的 op 分发到诸如 CPU 或 GPU 之类的 设备 上, 同时提供执行 op 的方法. 这些方法执行后, 将产生的 tensor 返回. 在 Python 语言中, 返回的 tensor 是 numpy ndarray 对象; 在 C 和 C++ 语言中, 返回的 tensor 是 tensorflow::Tensor 实例.
下载安装
|
|
初步使用
- 使用图 (graph) 来表示计算任务.
- 在被称之为 会话 (Session) 的上下文 (context) 中执行图.
- 使用 tensor 表示数据.
- 通过 变量 (Variable) 维护状态.
- 使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据.
|
|
单层 SoftMax 神经网络模型
加载 MNIST 数据
60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)。
每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。图片设为“xs”,标签设为“ys”。训练数据集和测试数据集都包含xs和ys,比如训练数据集的图片是 mnist.train.images ,训练数据集的标签是 mnist.train.labels。
每一张图片包含28X28个像素点。我们把这个数组展开成一个向量,长度是 28x28 = 784。
在 MNIST 训练数据集中,mnist.train.images 是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0和1之间。
相对应的 MNIST 数据集的标签是介于0到9的数字,用来描述给定图片里表示的数字。为了用于这个教程,我们使标签数据是”one-hot vectors”。 一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。所以在此教程中,数字n将表示成一个只有在第n维度(从0开始)数字为1的10维向量。比如,标签0将表示成([1,0,0,0,0,0,0,0,0,0,0])。因此, mnist.train.labels 是一个 [60000, 10] 的数字矩阵。
|
|
运行 TensorFlow 的 InteractiveSession
Tensorflow 依赖于一个高效的C++后端来进行计算。与后端的这个连接叫做session。一般而言,使用TensorFlow程序的流程是先创建一个图,然后在session中启动它。这里,我们使用更加方便的InteractiveSession类。通过它,你可以更加灵活地构建你的代码。它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。如果你没有使用InteractiveSession,那么你需要在启动session之前构建整个计算图,然后启动该计算图。
构建 Softmax 回归模型
y = softmax(Wx + b)
|
|
我们在调用tf.Variable的时候传入初始值。在这个例子里,我们把 W 和 b 都初始化为零向量。W 是一个784x10的矩阵(因为我们有784个特征和10个输出值)。b 是一个10维的向量(因为我们有10个分类)。
构建代价函数
指标
代码
|
|
注意,tf.reduce_sum把minibatch里的每张图片的交叉熵值都加起来了。我们计算的交叉熵是指整个minibatch的。
训练模型
|
|
TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵。梯度下降算法(gradient descent algorithm)是一个简单的学习过程,TensorFlow只需将每个变量一点点地往使成本不断降低的方向移动。
TensorFlow在这里实际上所做的是,它会在后台给计算图增加一系列新的计算操作单元用于实现反向传播算法和梯度下降算法。然后,它返回给你的只是一个单一的操作,当运行这个操作时,它用梯度下降算法训练你的模型,微调你的变量,不断减少成本。
返回的train_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复地运行train_step来完成。
训练
每一步迭代,我们都会随机加载50个训练样本,然后执行一次train_step,并通过feeddict将x 和 y张量占位符用训练训练数据替代。
使用一小部分的随机数据来进行训练被称为随机训练(stochastic training)- 在这里更确切的说是随机梯度下降训练。在理想情况下,我们希望用我们所有的数据来进行每一步的训练,因为这能给我们更好的训练结果,但显然这需要很大的计算开销。所以,每一次训练我们可以使用不同的数据子集,这样做既可以减少计算开销,又可以最大化地学习到数据集的总体特性。
评估模型
找出预测正确的标签
tf.argmax 给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签。tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值
tf.argmax(y_,1) 代表正确的标签
tf.equal 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)
这里返回一个布尔数组。为了计算我们分类的准确率,我们将布尔值转换为浮点数来代表对、错,然后取平均值。例如:[True, False, True, True]变为[1,0,1,1],计算出平均值为0.75。
最后,我们可以计算出在测试数据上的准确率,大概是90.92%。
多层卷积网络模型
CNN 对模式分类非常适合,最初是为识别二维形状而特殊设计的,这种二维形状对平移、比例缩放、倾斜或其他形式对变形有高度不变性。详见 卷积神经网络 CNN 笔记
TensorFlow 实现
初始化权重和偏置项
为了创建这个模型,我们需要创建大量的权重和偏置项。这个模型中的权重在初始化时应该加入少量的噪声来打破对称性以及避免 0 梯度。由于我们使用的是 ReLU 神经元,因此比较好的做法是用一个较小的正数来初始化偏置项,以避免神经元节点输出恒为 0 的问题(dead neurons)。为了不在建立模型的时候反复做初始化操作,我们定义两个函数用于初始化。
卷积和池化
我们的卷积使用 1 步长(stride size),0 边距(padding size)的模板,保证输出和输入是同一个大小。
我们的池化用简单传统的 2x2 大小的模板做 max pooling。为了代码更简洁,我们把这部分抽象成一个函数。
第一层卷积
第一层卷积由一个卷积接一个 max pooling 完成。卷积在每个 5x5 的 patch 中算出 32 个特征。卷积的权重张量形状是[5, 5, 1, 32],前两个维度是 patch 的大小,接着是输入的通道数目,最后是输出的通道数目。 而对于每一个输出通道都有一个对应的偏置量。
第二层卷积
为了构建一个更深的网络,我们会把几个类似的层堆叠起来。第二层中,每个 5x5 的 patch 会得到64个特征。
密集连接层(全连接层)
经过第一次池化,图片尺寸减小到 14*14,经过第二次池化,图片尺寸减小到 7x7。我们加入一个有 1024 个神经元的全连接层,用于处理整个图片。我们把池化层输出的张量reshape成一些向量,乘上权重矩阵,加上偏置,然后对其使用ReLU。
Dropout
为了减少过拟合,我们在输出层之前加入 dropout。我们用一个 placeholder 来代表一个神经元的输出在dropout中保持不变的概率。这样我们可以在训练过程中启用 dropout,在测试过程中关闭 dropout。 TensorFlow的tf.nn.dropout 操作除了可以屏蔽神经元的输出外,还会自动处理神经元输出值的scale。所以用dropout的时候可以不用考虑scale。
输出层
最后,我们添加一个softmax层,就像前面的单层softmax regression一样。
训练和评估模型
使用与之前简单的单层SoftMax神经网络模型几乎相同的一套代码,只是我们会用更加复杂的ADAM优化器来做梯度最速下降,在feed_dict中加入额外的参数keep_prob来控制dropout比例。然后每100次迭代输出一次日志。最后的准确率是 99.2%
参考链接:
中文文档
github 项目地址
http://blog.csdn.net/zouxy09/article/details/8781543
http://blog.csdn.net/celerychen2009/article/details/8973218
卷积神经网络(CNN)学习笔记 - LeNet5网络详解