前面两篇随笔实现的单层神经网络 和多层神经网络, 在MNIST测试集上的正确率分别约为90%和96%。在换用多层神经网络后,正确率已有很大的提升。这次将采用卷积神经网络继续进行测试。

1、模型基本结构

  如下图所示,本次采用的模型共有8层(包含dropout层)。其中卷积层和池化层各有两层。

  在整个模型中,输入层负责数据输入;卷积层负责提取图片的特征;池化层采用最大池化的方式,突出主要特征,并减少参数维度;全连接层再将个特征组合起来;dropout层可以减少每次训练的计算量,并可以一定程度上避免过拟合问题;最后输出层再综合各特征数据,得出最终结果。

  Dropout层起始并没有增加训练参数,只是随机的将某些节点间的连接弧断开,使其在本次中暂时的不参与训练。

2、数据预处理

  首先读取用于训练的数据。

from tensorflow.examples.tutorials.mnist import input_data

mnist = input_data.read_data_sets('./data/mnist', one_hot=True)

  在前面的输入层中,输入的每个样本都是一维的数据,而卷积神经网络的样本数据将是多维的。因此我们需要将读取到的数据再reshape一下,使其符合要求。

data.reshape([batchSize, 28, 28, 1])

3、输入层

  输入层的shape为:bitchSize * 28 * 28 * 1,第一个参数表示每个mini-batch的样本数量,由传入None可以让TensorFlow自动推断;后面三个参数表示每个样本的高为28,宽为28,通道数为1。

inputLayer = tf.placeholder(tf.float32, shape=[None, 28, 28, 1])

4、卷积层

  第一个卷积层的卷积核大小为5 * 5,数量为32个。padding方式采用‘SAME’。第二个卷积层类似,只是通道数,输出维度不一样。

 convFilter1 = tf.Variable(tf.truncated_normal([5, 5, 1, 32], mean=0, stddev=0.1))
convBias1 = tf.Variable(tf.truncated_normal([32], mean=0, stddev=0.1))
convLayer1 = tf.nn.conv2d(input=inputLayer, filter=convFilter1, strides=[1, 1, 1, 1], padding='SAME')
convLayer1 = tf.add(convLayer1, convBias1)
convLayer1 = tf.nn.relu(convLayer1)

5、池化层

  滑动窗口的大小为 2 * 2,在高和宽的维度上的滑动步幅也为2,其他维度为1。本模型中第二个池化层与第一个池化层一样。

poolLayer1 = tf.nn.max_pool(value=convLayer1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

 6、全连接层

  全连接层将前面在每个样本中提取到的多维特征展开成一维,作为全连接层的输入。

 fullWeight = tf.Variable(tf.truncated_normal(shape=[7 * 7 * 64, 1024], mean=0, stddev=0.1))
fullBias = tf.Variable(tf.truncated_normal(shape=[1024], mean=0.0, stddev=0.1))
fullInput = tf.reshape(poolLayer2, [-1, 7 * 7 * 64])
fullLayer = tf.add(tf.matmul(fullInput, fullWeight), fullBias)
fullLayer = tf.nn.relu(fullLayer)

7、Dropout层

  dropout层可以防止过拟合问题。这里指定的保留率为0.8。

dropLayer = tf.nn.dropout(fullLayer, keep_prob=0.8)

8、输出层

  最终输出10个数字的分类。

 outputWeight = tf.Variable(tf.truncated_normal(shape=[1024, 10], mean=0.0, stddev=0.1))
outputBias = tf.Variable(tf.truncated_normal(shape=[10], mean=0, stddev=0.1))
outputLayer = tf.add(tf.matmul(dropLayer, outputWeight), outputBias)

  模型的其他部分与前面的多层神经网络差不多,这里不再赘述。

9、模型在训练集与测试集上的表现

  从模型图上可以看到,本次采用的模型的复杂度比前面的多层神经网络高很多。正因如此,每次迭代计算也比前面的耗时的多,后者单次耗时为前者的1500多倍。可见虽然只增加了几层(当然除了层数的增加还有节点数的增加),但增加的计算量非常的多。

  下面两张图为卷积神经网络前面部分和后面部分迭代的输出结果,可以发现到最后卷积神经网络在训练集上已经接近100%的准确率。

  在测试集上的准确率也达到了 98% 99%,比多层神经网络提供了约2个百分点。

附:

  完整代码如下:

 import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import time # 读取数据
mnist = input_data.read_data_sets('./data/mnist', one_hot=True) # 输入层
inputLayer = tf.placeholder(tf.float32, shape=[None, 28, 28, 1]) # 卷积层(1)
convFilter1 = tf.Variable(tf.truncated_normal([5, 5, 1, 32], mean=0, stddev=0.1))
convBias1 = tf.Variable(tf.truncated_normal([32], mean=0, stddev=0.1))
convLayer1 = tf.nn.conv2d(input=inputLayer, filter=convFilter1, strides=[1, 1, 1, 1], padding='SAME')
convLayer1 = tf.add(convLayer1, convBias1)
convLayer1 = tf.nn.relu(convLayer1) # 池化层(1)
poolLayer1 = tf.nn.max_pool(value=convLayer1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # 卷积层(2)
convFilter2 = tf.Variable(tf.truncated_normal([5, 5, 32, 64], mean=0, stddev=0.1))
convBias2 = tf.Variable(tf.truncated_normal([64], mean=0, stddev=0.1))
convLayer2 = tf.nn.conv2d(input=poolLayer1, filter=convFilter2, strides=[1, 1, 1, 1], padding='SAME')
convLayer2 = tf.add(convLayer2, convBias2)
convLayer2 = tf.nn.relu(convLayer2) # 池化层(2)
poolLayer2 = tf.nn.max_pool(value=convLayer2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') # 全连接层
fullWeight = tf.Variable(tf.truncated_normal(shape=[7 * 7 * 64, 1024], mean=0, stddev=0.1))
fullBias = tf.Variable(tf.truncated_normal(shape=[1024], mean=0.0, stddev=0.1))
fullInput = tf.reshape(poolLayer2, [-1, 7 * 7 * 64])
fullLayer = tf.add(tf.matmul(fullInput, fullWeight), fullBias)
fullLayer = tf.nn.relu(fullLayer) # dropout层
dropLayer = tf.nn.dropout(fullLayer, keep_prob=0.8) # 输出层
outputWeight = tf.Variable(tf.truncated_normal(shape=[1024, 10], mean=0.0, stddev=0.1))
outputBias = tf.Variable(tf.truncated_normal(shape=[10], mean=0, stddev=0.1))
outputLayer = tf.add(tf.matmul(dropLayer, outputWeight), outputBias) # 标签
outputLabel = tf.placeholder(tf.float32, shape=[None, 10]) # 损失函数及目标函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=outputLabel, logits=outputLayer))
target = tf.train.AdamOptimizer().minimize(loss) # 记录起始训练时间
startTime = time.time() # 训练
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
batchSize = 64
for i in range(1000):
batch = mnist.train.next_batch(batchSize)
inputData = batch[0].reshape([batchSize, 28, 28, 1])
labelData = batch[1]
sess.run([target, loss], feed_dict={inputLayer: inputData, outputLabel: labelData}) corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
accuracy = tf.reduce_mean(tf.cast(corrected, tf.float32))
accuracyValue = sess.run(accuracy, feed_dict={inputLayer: inputData, outputLabel: labelData})
print(i, 'train set accuracy:', accuracyValue) # 打印结束时间
endTime = time.time()
print('train time:', endTime - startTime) # 测试
corrected = tf.equal(tf.argmax(outputLabel, 1), tf.argmax(outputLayer, 1))
accuracy = tf.reduce_mean(tf.cast(corrected, tf.float32))
testImages = mnist.test.images.reshape([-1, 28, 28, 1])
testLabels = mnist.test.labels
accuracyValue = sess.run(accuracy, feed_dict={inputLayer: testImages, outputLabel: testLabels})
print("accuracy on test set:", accuracyValue) sess.close()

本文地址:https://www.cnblogs.com/laishenghao/p/9738912.html

TensorFlow训练MNIST数据集(3) —— 卷积神经网络的更多相关文章

  1. MNIST数据集上卷积神经网络的简单实现(使用PyTorch)

    设计的CNN模型包括一个输入层,输入的是MNIST数据集中28*28*1的灰度图 两个卷积层, 第一层卷积层使用6个3*3的kernel进行filter,步长为1,填充1.这样得到的尺寸是(28+1* ...

  2. TensorFlow 训练MNIST数据集(2)—— 多层神经网络

    在我的上一篇随笔中,采用了单层神经网络来对MNIST进行训练,在测试集中只有约90%的正确率.这次换一种神经网络(多层神经网络)来进行训练和测试. 1.获取MNIST数据 MNIST数据集只要一行代码 ...

  3. TensorFlow训练MNIST数据集(1) —— softmax 单层神经网络

    1.MNIST数据集简介 首先通过下面两行代码获取到TensorFlow内置的MNIST数据集: from tensorflow.examples.tutorials.mnist import inp ...

  4. 基于MNIST数据的卷积神经网络CNN

    基于tensorflow使用CNN识别MNIST 参数数量:第一个卷积层5x5x1x32=800个参数,第二个卷积层5x5x32x64=51200个参数,第三个全连接层7x7x64x1024=3211 ...

  5. 2、TensorFlow训练MNIST

    装载自:http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html TensorFlow训练MNIST 这个教程的目标读者是对机器学习和T ...

  6. 使用caffe训练mnist数据集 - caffe教程实战(一)

    个人认为学习一个陌生的框架,最好从例子开始,所以我们也从一个例子开始. 学习本教程之前,你需要首先对卷积神经网络算法原理有些了解,而且安装好了caffe 卷积神经网络原理参考:http://cs231 ...

  7. 实践详细篇-Windows下使用VS2015编译的Caffe训练mnist数据集

    上一篇记录的是学习caffe前的环境准备以及如何创建好自己需要的caffe版本.这一篇记录的是如何使用编译好的caffe做训练mnist数据集,步骤编号延用上一篇 <实践详细篇-Windows下 ...

  8. 一个简单的TensorFlow可视化MNIST数据集识别程序

    下面是TensorFlow可视化MNIST数据集识别程序,可视化内容是,TensorFlow计算图,表(loss, 直方图, 标准差(stddev)) # -*- coding: utf-8 -*- ...

  9. TensorFlow训练MNIST报错ResourceExhaustedError

    title: TensorFlow训练MNIST报错ResourceExhaustedError date: 2018-04-01 12:35:44 categories: deep learning ...

随机推荐

  1. Oracle EBS 新增 OAFM 个数

    在 $INST_TOP/ora/10.1.3/opmn/conf/opmn.xml中 找到 <process-type id="oafm" module-id="O ...

  2. 一张思维导图纵观MySQL数据安全体系!

    杨奇龙 2017-06-29 09:52:10 786 作者介绍 杨奇龙,前阿里数据库团队资深DBA,主要负责淘宝业务线,经历多次双十一,有海量业务访问DB架构设计经验.目前就职于有赞科技,负责数据库 ...

  3. 获取 MySQL 崩溃时的 core file

    对于一般进程,要让进程崩溃时能生成 core file 用于调试,只需要设置 rlimit 的 core file size > 0 即可.比如,用在 ulimit -c unlimited 时 ...

  4. 快速开发QCombox以及业务样式自定义

    这是我在项目实战中的个人总结,写的仓促,有些东西也不一定准确,有些是自己推断的,还希望各位多多指教,多多评论. 关于QCombox如果不需要自定义,其实写UI是很简单的. 创建实例:QComboBox ...

  5. 实现一个协程版mysql连接池

    实现一个协程版的mysql连接池,该连接池支持自动创建最小连接数,自动检测mysql健康:基于swoole的chanel. 最近事情忙,心态也有点不积极.技术倒是没有落下,只是越来越不想写博客了.想到 ...

  6. [python] 列表解析式的高效与简洁

    方法一(列表解析式): list1 = ["abc","efg","hij"] list2 = [i[0] for i in list1] ...

  7. String----是一个对象

    * 字符串可以看成是字符组成的数组,但是js中没有字符类型 * 字符是一个一个的,在别的语言中字符用一对单引号括起来 * 在js中字符串可以使用单引号也可以使用双引号 * 因为字符串可以看成是数组,所 ...

  8. h5实现手机端等级进度条

    h5实现等级进度条 需求如下: 实现一个动画进度条,页面一打开实现一个进度条动画,因为App这个页面会经常改,所以没有使用原审Android或者IOS来实现,希望通过H5来做: 服务器端返回如下数据: ...

  9. Python2.7-stat

    stat模块,用于解释 os.stat(),os.lstat(),os.fstat() 返回的结果,定义了许多表示文件或路径的各个状态的常数和测试各个状态的函数具体参考 官方文档 和 http://w ...

  10. jqgrid 配置行号及行号的宽度

    有时,我们想把jqgrid的行号按指定的宽度显示出来,如何实现? 通过 rownumbers:true  设置启用行号 通过 rownumWidth 配置行号列的宽度 $("#jqGrid& ...