工作中需要实现 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 实例.

下载安装

1
sudo pip install —upgrade https://storage.googleapis.com/tensorflow/mac/tensorflow-0.8.0-py2-none-any.whl

初步使用

  • 使用图 (graph) 来表示计算任务.
  • 在被称之为 会话 (Session) 的上下文 (context) 中执行图.
  • 使用 tensor 表示数据.
  • 通过 变量 (Variable) 维护状态.
  • 使用 feed 和 fetch 可以为任意的操作(arbitrary operation) 赋值或者从其中获取数据.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 常量
a = tf.constant([3.0, 3.0])
# 变量,变量要进行初始化
x = tf.Variable([1.0, 2.0])
# 变量初始化
init_op = tf.initialize_all_variables()
# 矩阵乘法
product = tf.matmul(matrix1, matrix2)
# 减法
sub = tf.sub(x, a)
# 加法
new_value = tf.add(state, one)
# Fetch
# 启动默认图
sess = tf.Session()
# 执行矩阵乘法。函数调用 'run(product)' 触发了图中三个 op (两个常量 op 和一个矩阵乘法 op) 的执行
result = sess.run(product)
# 任务完成, 关闭会话.
sess.close()
# Session 对象在使用完后需要关闭以释放资源. 除了显式调用 close 外, 也可以使用 "with" 代码块 来自动完成关闭动作.
with tf.Session() as sess:
result = sess.run([product])
print result
# 取回多个 tensor:
input1 = tf.constant(3.0)
input2 = tf.constant(2.0)
input3 = tf.constant(5.0)
intermed = tf.add(input2, input3)
mul = tf.mul(input1, intermed)
with tf.Session() as sess:
result = sess.run([mul, intermed])
print result
# Feed
#feed 使用一个 tensor 值临时替换一个操作的输出结果. 你可以提供 feed 数据作为 run() 调用的参数. feed 只在调用它的方法内有效, 方法结束, feed 就会消失. 最常见的用例是将某些特殊的操作指定为 "feed" 操作, 标记的方法是使用 tf.placeholder() 为这些操作创建占位符.
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.mul(input1, input2)
with tf.Session() as sess:
print sess.run([output], feed_dict={input1:[7.], input2:[2.]})

单层 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] 的数字矩阵。

1
2
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

运行 TensorFlow 的 InteractiveSession

Tensorflow 依赖于一个高效的C++后端来进行计算。与后端的这个连接叫做session。一般而言,使用TensorFlow程序的流程是先创建一个图,然后在session中启动它。这里,我们使用更加方便的InteractiveSession类。通过它,你可以更加灵活地构建你的代码。它能让你在运行图的时候,插入一些计算图,这些计算图是由某些操作(operations)构成的。这对于工作在交互式环境中的人们来说非常便利,比如使用IPython。如果你没有使用InteractiveSession,那么你需要在启动session之前构建整个计算图,然后启动该计算图。

1
2
import tensorflow as tf
sess = tf.InteractiveSession()

构建 Softmax 回归模型

y = softmax(Wx + b)

1
2
3
4
5
6
7
8
9
10
11
# x 是一个占位符placeholder,在TensorFlow运行计算时输入这个值。我们希望能够输入任意数量的MNIST图像,每一张图展平成784维的向量。我们用2维的浮点数张量来表示这些图,这个张量的形状是[None,784 ]。(这里的None表示此张量的第一个维度可以是任何长度的。)
x = tf.placeholder(tf.float32, [None, 784])
# 权重值
W = tf.Variable(tf.zeros([784,10]))
# 偏离值
b = tf.Variable(tf.zeros([10]))
# 类别预测 - softmax 模型。(激活函数,线性输出->概率分布)
y = tf.nn.softmax(tf.matmul(x,W) + b)

我们在调用tf.Variable的时候传入初始值。在这个例子里,我们把 W 和 b 都初始化为零向量。W 是一个784x10的矩阵(因为我们有784个特征和10个输出值)。b 是一个10维的向量(因为我们有10个分类)。

构建代价函数

指标

交叉熵

代码

1
2
3
4
5
# 正确值
y_ = tf.placeholder("float", [None,10])
# 损失函数
cross_entropy = -tf.reduce_sum(y_*tf.log(y))

注意,tf.reduce_sum把minibatch里的每张图片的交叉熵值都加起来了。我们计算的交叉熵是指整个minibatch的。

训练模型

1
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵。梯度下降算法(gradient descent algorithm)是一个简单的学习过程,TensorFlow只需将每个变量一点点地往使成本不断降低的方向移动。

TensorFlow在这里实际上所做的是,它会在后台给计算图增加一系列新的计算操作单元用于实现反向传播算法和梯度下降算法。然后,它返回给你的只是一个单一的操作,当运行这个操作时,它用梯度下降算法训练你的模型,微调你的变量,不断减少成本。

返回的train_step操作对象,在运行时会使用梯度下降来更新参数。因此,整个模型的训练可以通过反复地运行train_step来完成。

训练

1
2
3
4
5
6
7
8
9
10
11
# 初始化变量
init = tf.initialize_all_variables()
# 在session里启动模型
sess = tf.Session()
sess.run(init)
# 开始训练模型,这里我们让模型循环训练1000次!
for i in range(1000):
batch = mnist.train.next_batch(50)
sess.run(train_step,feed_dict={x: batch[0], y_: batch[1]})

每一步迭代,我们都会随机加载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 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)

1
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

这里返回一个布尔数组。为了计算我们分类的准确率,我们将布尔值转换为浮点数来代表对、错,然后取平均值。例如:[True, False, True, True]变为[1,0,1,1],计算出平均值为0.75。

1
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

最后,我们可以计算出在测试数据上的准确率,大概是90.92%。

1
print sess.run(accuracy,feed_dict={x: mnist.test.images, y_: mnist.test.labels})

多层卷积网络模型

CNN 对模式分类非常适合,最初是为识别二维形状而特殊设计的,这种二维形状对平移、比例缩放、倾斜或其他形式对变形有高度不变性。详见 卷积神经网络 CNN 笔记

TensorFlow 实现

初始化权重和偏置项

为了创建这个模型,我们需要创建大量的权重和偏置项。这个模型中的权重在初始化时应该加入少量的噪声来打破对称性以及避免 0 梯度。由于我们使用的是 ReLU 神经元,因此比较好的做法是用一个较小的正数来初始化偏置项,以避免神经元节点输出恒为 0 的问题(dead neurons)。为了不在建立模型的时候反复做初始化操作,我们定义两个函数用于初始化。

1
2
3
4
5
6
7
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)

卷积和池化

我们的卷积使用 1 步长(stride size),0 边距(padding size)的模板,保证输出和输入是同一个大小。
我们的池化用简单传统的 2x2 大小的模板做 max pooling。为了代码更简洁,我们把这部分抽象成一个函数。

1
2
3
4
5
6
7
8
# 卷积函数
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
# 池化函数
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')

第一层卷积

第一层卷积由一个卷积接一个 max pooling 完成。卷积在每个 5x5 的 patch 中算出 32 个特征。卷积的权重张量形状是[5, 5, 1, 32],前两个维度是 patch 的大小,接着是输入的通道数目,最后是输出的通道数目。 而对于每一个输出通道都有一个对应的偏置量。

1
2
3
4
5
6
7
8
9
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
# 把 x 变成一个4d向量,其第2、第3维对应图片的宽、高,最后一维代表图片的颜色通道数(因为是灰度图所以这里的通道数为1,如果是 rgb 彩色图,则为3)。
x_image = tf.reshape(x, [-1,28,28,1])
# 把 x_image 和权值向量进行卷积,加上偏置项,然后应用 ReLU 激活函数,最后进行 max pooling。
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

第二层卷积

为了构建一个更深的网络,我们会把几个类似的层堆叠起来。第二层中,每个 5x5 的 patch 会得到64个特征。

1
2
3
4
5
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

密集连接层(全连接层)

经过第一次池化,图片尺寸减小到 14*14,经过第二次池化,图片尺寸减小到 7x7。我们加入一个有 1024 个神经元的全连接层,用于处理整个图片。我们把池化层输出的张量reshape成一些向量,乘上权重矩阵,加上偏置,然后对其使用ReLU。

1
2
3
4
5
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

Dropout

为了减少过拟合,我们在输出层之前加入 dropout。我们用一个 placeholder 来代表一个神经元的输出在dropout中保持不变的概率。这样我们可以在训练过程中启用 dropout,在测试过程中关闭 dropout。 TensorFlow的tf.nn.dropout 操作除了可以屏蔽神经元的输出外,还会自动处理神经元输出值的scale。所以用dropout的时候可以不用考虑scale。

1
2
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

输出层

最后,我们添加一个softmax层,就像前面的单层softmax regression一样。

1
2
3
4
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

训练和评估模型

使用与之前简单的单层SoftMax神经网络模型几乎相同的一套代码,只是我们会用更加复杂的ADAM优化器来做梯度最速下降,在feed_dict中加入额外的参数keep_prob来控制dropout比例。然后每100次迭代输出一次日志。最后的准确率是 99.2%

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess.run(tf.initialize_all_variables())
for i in range(20000):
batch = mnist.train.next_batch(50)
if i % 100 == 0:
train_accuracy = sess.run(
accuracy, feed_dict={x: batch[0], y_: batch[1], keep_prob: 1.0})
print "step %d, training accuracy %g" % (i, train_accuracy)
sess.run(train_step, feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
print "test accuracy %g" % sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0})

代码

参考链接:

中文文档
github 项目地址
http://blog.csdn.net/zouxy09/article/details/8781543
http://blog.csdn.net/celerychen2009/article/details/8973218
卷积神经网络(CNN)学习笔记 - LeNet5网络详解

原文地址: http://www.shuang0420.com/2016/06/20/TensorFlow%E5%AE%9E%E6%88%98-MNIST/

TensorFlow 实战 MINST相关推荐

  1. 【TensorFlow实战笔记】对于TED(en-zh)数据集进行Seq2Seq模型实战,以及对应的Attention机制(tf保存模型读取模型)

    个人公众号 AI蜗牛车 作者是南京985AI硕士,CSDN博客专家,研究方向主要是时空序列预测和时间序列数据挖掘,获国家奖学金,校十佳大学生,省优秀毕业生,阿里天池时空序列比赛rank3.公众号致力于 ...

  2. 免费教材丨第55期:Python机器学习实践指南、Tensorflow 实战Google深度学习框架

    小编说  时间过的好快啊,小伙伴们是不是都快进入寒假啦?但是学习可不要落下哦!  本期教材  本期为大家发放的教材为:<Python机器学习实践指南>.<Tensorflow 实战G ...

  3. Tensorflow实战之下载MNIST数据,自动分成train, validation和test三个数据集

    TensorFlow 实战Google深度学习框架 第2版 ,郑泽宇之P96.下载MNIST数据,自动分成train, validation和test三个数据集,源码如下: #!/usr/bin/en ...

  4. TensorFlow实战-AlexNet

    1 # 导入数据 2 from tensorflow.examples.tutorials.mnist import input_data 3 # 读取数据 4 mnist=input_data.re ...

  5. Tensorflow实战系列之五:

    打算写实例分割的实战,类似mask-rcnn. Tensorflow实战先写五个系列吧,后面新的技术再添加~~ 转载于:https://www.cnblogs.com/wmr95/p/8846887. ...

  6. 《Tensorflow 实战google深度学习框架》第二版源代码

    <<Tensorflow 实战google深度学习框架–第二版>> 完整资料github地址: https://github.com/caicloud/tensorflow-t ...

  7. 06.图像识别与卷积神经网络------《Tensorflow实战Google深度学习框架》笔记

    一.图像识别问题简介及经典数据集 图像识别问题希望借助计算机程序来处理.分析和理解图片中的内容,使得计算机可以从图片中自动识别各种不同模式的目标和对象.图像识别问题作为人工智能的一个重要领域,在最近几 ...

  8. tensorflow63 《深度学习原理与TensorFlow实战》03 Hello TensorFlow

    00 基本信息 <深度学习原理与TensorFlow实战>书中涉及到的代码主要来源于: A:Tensorflow/TensorflowModel/TFLean的样例, B:https:// ...

  9. 【TensorFlow实战笔记】卷积神经网络CNN实战-cifar10数据集(tensorboard可视化)

    IDE:pycharm Python: Python3.6 OS: win10 tf : CPU版本 代码可在github中下载,欢迎star,谢谢 CNN-CIFAR-10 一.CIFAR10数据集 ...

最新文章

  1. P1087 FBI树
  2. python怎么导入同一包的模块
  3. 京东11.11大促背后,那些系统架构经历了些什么
  4. Java类之File记录
  5. linux删除文件夹提示没找到,Win10中遇到删除文件夹提示找不到该项目的解决过程...
  6. FZU - 2268 Cutting Game
  7. [剑指offer]面试题19:二叉树的镜像
  8. 数据库连接 未将对象引用到实例
  9. 我们应该如何写好HTMLCSS
  10. 个人课中所学vlan相关知识整理
  11. VMware 软件被曝其史上最严重的信息泄露漏洞之一,影响大量虚拟机和主机
  12. 《Web漏洞防护》读书笔记——第12章,CSRF跨站点请求伪造防护
  13. Openlayers3中如何优雅的表示等值面
  14. R语言循环函数编写三境界
  15. 乐拼拼购系统开发(源码成品)
  16. 用unionID作为oneID的实质:不管理账号和密码
  17. 天威诚信:数字认证体系助推车联网积极稳妥发展
  18. 符合这8种性格的人都长寿
  19. brendan eich_编程领域的变革者:Brendan Eich
  20. 7.4 初等矩阵和可逆性

热门文章

  1. 【编程题目】对称子字符串的最大长度 ★
  2. spring bean中scope=prototype“的作用
  3. WordPress yolink Search插件‘s’参数跨站脚本漏洞
  4. 复制文件时怎么保留权限
  5. 程设13次作业总结--运算符重载
  6. C++十进制转二进制
  7. 科大星云诗社动态20201122
  8. python中with的用法
  9. Python实现一个简单数据库查询接口编写
  10. docker yml mysql_Docker安装Mysql(docker-compose.yml)