mnist手写数字识别(TensorFlow-GPU)-----------原理及代码

本文主要是对mnist手写数据集这中的迷糊数字进行识别,在Softmax Regression基础上建立了一个较为简单的机器学习模型。

通过这篇文章,可以对神经网络有一个大体的了解,还可以掌握简单的图像识别技术,本章的图片来源是于一个开源的训练数据集(mnist)

我们分以下几个部分来进行:

  1. 导入数据集。
  2. 分析mnist样本特点定义变量。
  3. 构建模型。
  4. 训练模型并输出中间状态参数。
  5. 测试模型。
  6. 保存模型。
  7. 读取模型。

一、导入手写图片的数据集

(1) mnist数据集

    mnist数据集里面包含各种手写数字图片,如下图一所示:

    它包含每一张图片对应的标签,告诉我们这个是数字几,并对下面的四张图片打上标签5,0,4,1

     

   (2) 利用TensorFlow代码下载mnist数据集

     通过TensorFlow所提供的库,进行下载minst数据集:

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2019/5/17 17:03
# @Author  : xhh
# @Desc    :  minist数据集下载
# @File    : mnist_data_load.py
# @Software: PyCharm
from tensorflow.examples.tutorials.mnist import  input_data
import pylab

mnist = input_data.read_data_sets("MINST_daya/", one_hot=True)
print("输入数据:",mnist.train.images)
print("数据的shape:",mnist.train.images.shape)

# 展示数据集中的一张图片
im = mnist.train.images[1]
im = im.reshape(-1,28)
pylab.imshow(im)
pylab.show()

运行上面的代码,会自动下载数据集,并将文本文件解压到当前所在的同级目录下的MNIST_daya文件夹下

注意:

代码中的one_hot=True,表示将样本标签转化为one_hot编码

onn_hot编码:

假如一共有10类编码。0的one_hot为1000000000, 1 的one_hot为0100000000,2 的one_hot为0010000000..........依次类推,只有一个位为1,1所在的位置就代表着第几类。

运行结果:

                 


      图二

看到上面的打印出来的训练集的图片信息,是一个55000行,784列的矩阵,也即训练集里面有55000张图片,每张的图片就是1行784(28*28)列的数据,括号中的每一个值代表一个像素。

mnist数据集如上图二的彩色图片所示,为彩色图片,它是3通道的,由RGB(红、黄、蓝)构成,图一的是黑白的是单通道图片,数值为0~255之间的数字,代表其颜色的深度。

(3)mnst数据集的组成

      在MNIST训练数据集中,mnist.train.images是一个形状为[55000,784]的张量。其中,第1个维度数字用来索引图片,第2个维度数字用来索引
每张图片中的像素点。此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0~255之间

 MNIST里包含3个数据集:

第一个是训练据集,另外两个分别是测试数据集(mnist.test)和验证数据集(mnist.validation)

如下图就是下载下来的mnist数据集压缩包:

二、分析图片的特点,定义变量

       由于输入图片是个550000×784的矩阵,所以先创建一个[None,784]的占位符x和一个[None,10]的占位符y,然后使用feed机制将图片和标签
输入进去。

代码如下:

from tensorflow.examples.tutorials.mnist import  input_data
import pylab
import tensorflow as tf

mnist = input_data.read_data_sets("MINST_daya/", one_hot=True)

tf.reset_default_graph()

# 定义占位符
x = tf.placeholder(tf.float32, [None, 784])  # mnist data 维度28*28=784
y = tf.placeholder(tf.float32, [None, 10])  #0-9 数字 ==>10class

     在定义占位符时,x和y中的None,表示此张量的第一个维度可以是任何长度的。x代表能够输入任意数量的mnist图像,每张图可以展成784维的向量。

三、构建模型

(1) 定义学习参数

    在TensorFlow里,使用Variable来定义学习参数。模型也需要权重值和偏置量,它们被统一叫做学习参数一个Variable代表一个可修改的张量,定义在TensorFlow的图(一个执行任务)中,其本身也是一种变量。使用Variable定义的学习参数可以用于计算输入值,也可以在计算中被修改。


# 定义学习参数
# 设置模型的权重
W = tf.Variable(tf.random_normal([784, 10]))  # W的维度是[784, 10]
b = tf.Variable(tf.zeros([10]))

在这里赋予tf.Variable不同的初值来创建不同的参数。一般将W设为一个随机值,将b设为0。

(2)  定义输出节点

有了输入和模型参数,接着便可以将它们串起来构建成真正的模型。


# 定义输出节点, 构建模型
pred = tf.nn.softmax(tf.matmul(x, W) + b)  # softmax分类

        首先,用tf.matmul(x,W)表示x乘以W,这里x是一个二维张量,拥有多个输入。然后再加上b,把它们的和输入tf.nn.softmax函数里。至此就构建好了正向传播的结构。也就是表明,只要模型中的参数合适,通过具体的数据输入,就能得到我们想要的分类。

(3) 定义反向传播结构


# 定义反向传播的结构,编译训练模型,得到合适的参数
cost = tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred), reduction_indices=1))

# 参数设置
learning_rate = 0.01
# 使用梯度下降优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

对反向传播结构的理解:

(1)将生成的pred与样本标签y进行一次交叉熵的运算,然后取平均值。
(2)将这个结果作为一次正向传播的误差,通过梯度下降的优化方法找到能够使这个误差最小化的b和W的偏移量。
(3)更新b和W,使其调整为合适的参数。整个过程就是不断地让损失值(误差值cost)变小。因为损失值越小,才能表明输出的结果跟标签数据越相近。当cost小到我们的需求时,这时的b和W就是训练出来的合适值。

(4) 训练模型并输出中间状态参数,并且进行模型的保存与测试

定义状态参数

training_epochs = 25   # 将整个训练样本迭代25次
batch_size = 100    # 在训练过程中每次随机抽取100条数据进行训练
display_step = 1   # 迭代的步数
saver = tf.train.Saver()
model_path = "mnist/521model.ckpt"

启动session:

# 开始训练
with tf.Session()  as sess:
    # 初始化节点
    sess.run(tf.global_variables_initializer())

    # 启动循环开始训练
    for epoch in range(training_epochs):
        avg_cost = 0.
        total_batch = int(mnist.train.num_examples/batch_size)
        # 遍历全部的数据集
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            # 运行和优化节点的损失函数值
            _, c = sess.run([optimizer, cost], feed_dict={x:batch_xs,
                                                          y: batch_ys})
            # 计算平均损失值
            avg_cost += c / total_batch

        # 显示训练中的详细信息
        if (epoch+1) % display_step ==0:
            print("Epoch:","%04d"%(epoch+1), "cost=",'{:.9f}'.format(avg_cost))

    print("训练成功!!")

    # 模型测试
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    # 计算准确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print("准确度:",accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))

    # 保存模型的权重
    save_path = saver.save(sess, model_path)
    print("模型文件在:%s"%save_path)

最终的运行结果:

Epoch: 0001 cost= 8.658398746
Epoch: 0002 cost= 4.599675331
Epoch: 0003 cost= 3.098299387
Epoch: 0004 cost= 2.414841038
Epoch: 0005 cost= 2.031551510
Epoch: 0006 cost= 1.787429208
Epoch: 0007 cost= 1.617599975
Epoch: 0008 cost= 1.491779541
Epoch: 0009 cost= 1.394358738
Epoch: 0010 cost= 1.316281419
Epoch: 0011 cost= 1.251967654
Epoch: 0012 cost= 1.197913221
Epoch: 0013 cost= 1.151722029
Epoch: 0014 cost= 1.111743248
Epoch: 0015 cost= 1.076424035
Epoch: 0016 cost= 1.045415161
Epoch: 0017 cost= 1.017401275
Epoch: 0018 cost= 0.992323116
Epoch: 0019 cost= 0.969426456
Epoch: 0020 cost= 0.948599738
Epoch: 0021 cost= 0.929346439
Epoch: 0022 cost= 0.911827402
Epoch: 0023 cost= 0.895336545
Epoch: 0024 cost= 0.880129020
Epoch: 0025 cost= 0.865876571

在最后对模型保存:
模型文件在:mnist/521model.ckpt

四、读取模型,并进行测试

# 读取模型
print("启动第二次session")
with tf.Session() as sess2:
    # 初始化参数
    sess2.run(tf.global_variables_initializer())
    #从保存的模型中获取权重
    saver.restore(sess2, model_path)

    # 测试 model
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    # 计算准确率
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    print("准确度:",accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))

    output = tf.argmax(pred, 1)
    batch_xs, batch_ys = mnist.train.next_batch(2)
    outputval, predv = sess2.run([output, pred], feed_dict={x:batch_xs})
    print(outputval, pred, batch_ys)

    im = batch_xs[0]
    im = im.reshape(-1, 28)
    pylab.imshow(im)
    pylab.show()

    im = batch_xs[1]
    im = im.reshape(-1, 28)
    pylab.imshow(im)
    pylab.show()

最终的运行结果:

准确度: 0.8296
[0 2] Tensor("Softmax:0", shape=(?, 10), dtype=float32) [[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]]

我们可以看到在测试集中随机取到两个数字进行预测的时候,在这里取的是0和2预测结果与所打的标签是相同的,对应的总的准确度有80%。

到此mnist手写数据集识别就完成了。

 

代码获取:扫下面的二维码关注公众号“ python爬虫scrapy”,  后台回复mnist代码,即可获取哦~~

相关推荐
手写数字识别的Tensorflow完整代码,### 1. MNIST机器学习入门 **1.1.1 简介** 下载MNIST数据集,并打印一些基本信息: ``` python download.py ``` **1.1.2 实验:将MNIST数据集保存为图片** ``` python save_pic.py ``` **1.1.3 图像标签的独热表示** 打印MNIST数据集中图片的标签: ``` python label.py ``` **1.2.1 Softmax 回归** ``` python softmax_regression.py ``` **1.2.2 两层卷积网络分类** ``` python convolutional.py ``` #### 可能出现的错误 下载数据集时可能出现网络问题,可以用下面两种方法中的一种解决:1. 使用合适的代理 2.在MNIST的官方网站上下载文件train-images-idx3-ubyte.gz、train-labels-idx1-ubyte.gz、t10k-images-idx3-ubyte.gz、t10k-labels-idx1-ubyte.gz,并将它们存储在MNIST_data/文件夹中。 #### 拓展阅读 - 本章介绍的MNIST 数据集经常被用来检验机器学习模型的性能,在它的官网(地址:http://yann.lecun.com/exdb/mnist/ )中,可以找到多达68 种模型在该数据集上的准确率数据,包括相应的论文出处。这些模型包括线性分类器、K 近邻方法、普通的神经网络、卷积神经网络等。 - 本章的两个MNIST 程序实际上来自于TensorFlow 官方的两个新手教程,地址为https://www.tensorflow.org/get_started/mnist/beginners 和 https://www.tensorflow.org/get_started/mnist/pros 。读者可以将本书的内容和官方的教程对照起来进行阅读。这两个新手教程的中文版地址为http://www.tensorfly.cn/tfdoc/tutorials/mnist_beginners.html 和http://www.tensorfly.cn/tfdoc/tutorials/mnist_pros.html。 - 本章简要介绍了TensorFlow 的tf.Tensor 类。tf.Tensor 类是TensorFlow的核心类,常用的占位符(tf.placeholder)、变量(tf.Variable)都可以看作特殊的Tensor。读者可以参阅https://www.tensorflow.org/programmers_guide/tensors 来更深入地学习它的原理。 - 常用tf.Variable 类来存储模型的参数, 读者可以参阅[https://www.tensorflow.org/programmers_guide/variables](https://www.tensorflow.org/programmers_guide/variables) 详细了解它的运行机制, 文档的中文版地址为http://www.tensorfly.cn/tfdoc/how_tos/ variables.html。 - 只有通过会话(Session)才能计算出tf.Tensor 的值。强烈建议读者 在学习完tf.Tensor 和tf.Variable 后,阅读https://www.tensorflow.org/programmers_guide/graphs 中的内容,该文档描述了TensorFlow 中 计算图和会话的基本运行原理,对理解TensorFlow 的底层原理有很 大帮助。
<h3><span style="color: #3598db;">【为什么要学习这门课程】</span></h3> <p style="font-size: 16px;">深度学习框架如TensorFlow和Pytorch掩盖了深度学习底层实现方法,那能否能用Python代码从零实现来学习深度学习原理呢?</p> <p style="font-size: 16px;">本课程就为大家提供了这个可能,有助于深刻理解深度学习原理。</p> <p style="font-size: 16px;"><strong><span style="color: #ba372a;">左手原理、右手代码,双管齐下!</span></strong></p> <p style="font-size: 16px;">本课程详细讲解深度学习原理并进行Python代码实现深度学习网络。课程内容涵盖感知机、多层感知机、卷积神经网络、循环神经网络,并使用Python 3及Numpy、Matplotlib从零实现上述神经网络。本课程还讲述了神经网络的训练方法与实践技巧,且开展了代码实践演示。课程对于核心内容讲解深入细致,如基于计算图理解反向传播算法,并用数学公式推导反向传播算法;另外还讲述了卷积加速方法im2col。</p> <p><span style="color: #3598db;"><strong>【课程收获】</strong></span></p> <p style="font-size: 16px;">本课程力求使学员通过深度学习原理、算法公式及Python代码的对照学习,摆脱框架而掌握深度学习底层实现原理与方法。</p> <p style="font-size: 16px;">本课程将给学员分享深度学习的Python实现代码。课程代码通过Jupyter Notebook演示,可在Windows、ubuntu等系统上运行,且不需GPU支持。</p> <h3 class="MsoNormal" align="left"><span style="color: #3598db;">【优惠说明】</span></h3> <p align="left"><strong><span style="color: #ba372a;"><span lang="EN-US"> </span>课程正在优惠中!</span></strong></p> <p> </p> <p class="MsoNormal" align="left"><span lang="EN-US"> </span>备注:购课后可加入白勇老师课程学习交流<span lang="EN-US">QQ</span>群:<span lang="EN-US">957519975</span></p> <h3><span style="color: #3598db;">【相关课程】</span></h3> <p style="font-size: 16px;">学习本课程的前提是会使用Python语言以及Numpy和Matplotlib库。</p> <p>相关课程链接如下:</p> <p>《Python编程的术与道:Python语言入门》https://edu.csdn.net/course/detail/27845</p> <p>《玩转Numpy计算库》https://edu.csdn.net/lecturer/board/28656</p> <p>《玩转Matplotlib数据绘图库》https://edu.csdn.net/lecturer/board/28720</p> <h3><strong><span style="color: #3598db;">【课程内容导图及特色】</span></strong></h3> <p style="font-size: 16px;"><img src="https://img-bss.csdn.net/202002061409525148.jpg" alt="" /></p> <p style="font-size: 16px;"><img src="https://img-bss.csdn.net/202002061410073901.jpg" alt="" /></p>
©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页