【从零开始学习Tensorflow】(三)第5章 MNIST数字识别问题

本文介绍了使用TensorFlow解决MNIST手写数字识别问题,包括数据处理、神经网络模型训练、模型效果对比以及模型的持久化。通过训练神经网络,比较不同优化方法对模型的影响,并探讨了变量管理和模型持久化的实现与原理。
摘要由CSDN通过智能技术生成

转载请注明作者和出处: https://blog.csdn.net/weixin_37392582
代码平台https://gitee.com/wuweijun
开发平台: Win10 + Python3.6 + Anaconda3
编  者: 无尾


文章性质:【从零开始学习Tensorflow】系列博客为 《TensorFlow+实战Google深度学习框架》一书的学习笔记。



5.1、MNIST数据处理

MNIST数据集,包含60000张图片作为训练数据(28*28),10000张图片作为测试数据,标签集用 ont_hot 编码表示手写数字(例:表示数字3→[0,0,0,1,0,0,0,0,0,0])。

TensorFlow提供了一个类来处理 MNIST 数据。这个类会自动下载并转换MNIST数据的格式,将数据从原始的数据包中解析成训练和测试神经网络时使用的格式。下面给出使用这个函数的样例程序。

from tensorflow.examples.tutorials.mnist import input_data

#载入 MNIST 数据集,若指定地址下没有,则自动从网上下载
mnist = input_data.read_data_sets("F:\MNIST_data",one_hot = True)

print('Training data size',mnist.train.num_examples)
print('Validating data size', mnist.validation.num_examples)
print('Testing data size', mnist.test.num_examples)
print('example training data label:',mnist.train.labels[0])

train 集合内有 55000 张图片,validation集合内有 5000 张图片,test集合内有 10000 张图片。每一张图片是一个长度为784的一维数组,对应了图片像素矩阵中的每一个数字(28*28 = 784)。

为了方便使用随机梯度下降, input_data.read_data_sets i n p u t _ d a t a . r e a d _ d a t a _ s e t s 函数生成的类还提供了 mnist.train.next_batch m n i s t . t r a i n . n e x t _ b a t c h 函数,它可以从所有的训练数据中读取一小部分作为一个训练 batch b a t c h 。代码如下:

batch_size = 100
#该函数每次执行都会从数据集中顺序读取
xs, ys = mnist.train.next_batch(batch_size)


# 从train集合中选取 batch_size 个训练数据
print("X shape:",xs.shape)
print("Y shape:",ys.shape)

OUTX shape: (100, 784)
Y shape: (100, 10)

5.2、神经网络模型训练及不同模型结果对比


5.2.1、TensorFlow 训练神经网络


给出一个完整的 Tensorflow 程序来解决 MNIST 手写体数字识别问题。

回顾第4章提到的主要概念。在神经网络的结构上,深度学习一方面需要使用激活函数实现神经网络模型的去线性化,另一方面需要使用一个或多个隐藏层使得神经网络的结构更深,以解决复杂问题。在训练神经网络时,第4章介绍了使用带指数衰减的学习率设置、使用正则化来避免过拟合,以及使用滑动平均模型来使得最终模型更加健壮。以下代码给出了一个在 MNIST 数据集上实现这些功能的完整的 TensorFlow 程序。

Click here to get the code:
【神经网络实现 MNIST 手写体识别】


5.2.2、使用验证数据集判断模型效果


将上一节中的代码做略微调整,使 validate_set 和 test_set 的正确率同时显示,发现 validate dataset 分布接近 test dataset 分布,可验证模型在验证数据上的表现可以很好的体现模型在测试数据上的表现。因此,对于验证数据的选择很重要。

        #迭代地训练神经网络
        for i in range(0,TRAINING_STEPS):
            if i % 1000 == 0:
                validate_acc = sess.run(accuracy, feed_dict = validate_feed)
                test_acc = sess.run(accuracy, feed_dict = test_feed)
                print("在 %d 次迭代后,验证数据集的正确率为 : %g , 测试数据集的正确率为 : %g" % (i, validate_acc,test_acc))
在 0 次迭代后,验证数据集的正确率为 : 0.093 , 测试数据集的正确率为 : 0.0965
在 1000 次迭代后,验证数据集的正确率为 : 0.9772 , 测试数据集的正确率为 : 0.9764
在 2000 次迭代后,验证数据集的正确率为 : 0.9828 , 测试数据集的正确率为 : 0.9804

CSDN 无尾君


5.2.3、不同模型效果比较


在第4章中,提到了设计神经网络时的 5 种优化方法。在神经网络结构的设计上,需要使用激活函数和多层隐藏层。在神经网络优化时,可以使用指数衰减的学习律、加入正则化的损失函数以及滑动平均模型。在图 5-3 中,给出了在相同神经网络参数下,使用不同优化方法没经过 30000 轮训练迭代后,得到的最终模型的正确率。

这里写图片描述

从图中的反映可以说明,神经网络的结构对最终模型的效果有本质性的影响。

我们看到,滑动平均模型和指数衰减的学习率对正确率的结果似乎没有什么影响,这是因为滑动平均模型和指数衰减的学习率在一定程度上都是限制神经网络中参数更新的速度,在 MNIST 数据集中,迭代在4000轮的时候就已经接近收敛,收敛速度很快,所以这两种优化对最终模型的影响不大。但是当问题更加复杂时,迭代不会这么快接近收敛,这时滑动平均模型和指数衰减的学习率可以发挥出更大的作用。比如 Cifar-10 图像分类数据集,使用滑动平均模型可以将错误率降低 11%,而使用指数衰减的学习率可以将错误率降低 7%。

正则化损失对于模型的影响较大。

这里写图片描述


5.3、变量管理

前面,将前向传播过程抽象成了一个函数,在训练和测试的过程中可以统一调用同一个函数来得到模型的前向传播结果。这个函数的定义为:

def inference(input_tensor, avg_class, weights1, biases1, weights2, biases2)

从定义中可以看到,这个函数的参数中包括了神经网络中的所有参数。然而,当网络结构更加复杂、参数更多时,就需要一个更好的方式来传递和管理神经网络中的参数了。TensorFlow 提供了通过变量名称来创建或获取一个变量的机制。通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递。 TensorFlow 中通过变量名称获取变量的机制主要是通过 tf.get_variable t f . g e t _ v a r i a b l e tf.variable_scope t f . v a r i a b l e _ s c o p e 函数实现的。

tf.g

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值