深度学习第二课MINIST数字识别

数字识别

本次训练一个能够识别图片的手写数字的机器学习模型。

  1. 导入MNIST数据集
  2. 分析MNIST样本特点定义变量。
  3. 构建模型。
  4. 训练模型。
  5. 测试模型。
  6. 保存模型。
  7. 读取模型。

1.导入MNIST数据集

从第一课我们可以知道需要一个数据集来训练模型。
这个数据集就是图片,来源于一个开源的训练数据集—MNIST。
MNIST数据集的官网是 http://yann.lecun.com/exdb/mnist/
大家可以到官网去下载图片的数据集。
在这里插入图片描述

同时TensorFlow也提供了一个库,可以用来自动下载安装MNIST。
代码如下:

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

运行之后,会自动下载数据集并且解压到当前代码同级目录下面的MNIST_data文件夹下。

代码之中的one_hot = true,表示将样本标签转换为one_hot编码。因为本例是识别数字,计算机在得出结果后,会通过该种方式表达得到的结果。比如一张图片被识别为数字1,则计算机表达为[1.0.0.0.0.0.0.0.0.0],如果是被识别为数字2,则计算机表达为[0.1.0.0.0.0.0.0.0.0],被识别为3的话,则计算机表达为[0.0.1.0.0.0.0.0.0.0]。后面的以此类推,且只需要表示0~9的数字。

在MNIST数据集的图片,每张图片是28×28的像素值。
图片黑色的地方的RGB值为0。
关于像素值和RGB可以看看之前我写的图像处理的博客的前面一部分:
博文链接:https://blog.csdn.net/qq_44807642/article/details/98205162

我们先将数据集的信息打印出来,看一看具体内容。

import tensorflow as tf #导入tensorflow库
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
import pylab 

print ('输入数据:',mnist.train.images)
print('数据为:',mnist.train.images.shape)

im = mnist.train.images[1]
im = im.reshape(-1,28)
pylab.imshow(im)
pylab.show()
    

运行效果如下图:
在这里插入图片描述

在图中,输入数据是图每点的RGB值,数据是代表有55000张这样的图片。相当于一个55000×784的二维数组。
第一个维度的数字55000的可以用来识别是哪张图片。
第二个维度的数字784的可以识别该点的RGB值。

MNIST包含三个数据集,分别是
训练数据集:用于训练
测试数据集(mnist.test):用于评估训练中的准确度
验证数据集(mnist.validation):用于评估模型的准确度。

2.分析MNIST样本特点定义变量。

因为输入图片是个550000×784的矩阵。所以可以先创建一个[None,784]的占位符x和一个[None,10]的占位符y(因为电脑输出结果用one_hot编码表示,所以用到[None,10]的占位符)

tf.reset_default_graph()    #tf.reset_default_graph函数用于清除默认图形堆栈并重置全局默认图形。
# tf 输入
x = tf.placeholder(tf.float32, [None, 784]) # mnist data维度 28*28=784
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 数字

第三行代码中的None,表示此张量第一个的维度可以是任何长度的,x就代表能够输入任意数量的MNIST图像,每一张图可以展成784维的向量。

3.构建模型。

3.1定义学习参数

在这个模型里面一样需要定义w(权重值),b(偏执值)。

W = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.zeros([10]))

学过线性代数可以知道,比如两个矩阵[x,y]和[y,n]相乘,会得到一个[x,n]的新矩阵。
所以这里就是我们为什么要把W定为[784,10]的原因。
因为我们最后需要的是一个10维的one_hot编码。
我们用一个784维的图片向量去乘以W,就可以得到一个10维向量了。

3.2定义输出节点
pred = tf.nn.softmax(tf.matmul(x, W) + b)

其中matmul函数的源代码是

matmul(
    a,
    b,
    transpose_a=False,
    transpose_b=False,
    adjoint_a=False,
    adjoint_b=False,
    a_is_sparse=False,
    b_is_sparse=False,
    name=None
)

就是将矩阵 a 乘以矩阵 b,生成a * b。

softmax的功能就是把一个N*1的向量归一化为(0,1)之间的值。达到分类的效果。

3.3反向定义
# Minimize error using cross entropy
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)

将上面生成的pred与样本标签y进行一次交叉熵的运算,后取平均值。

tf.reduce_sum()函数计算一个张量的各个维度上元素的总和。
tf.reduce_mean()计算张量的各个维度上的元素的平均值。

不停更新W,b使其cost值越来越小。

4.训练模型。

在训练模型中,我们将模型迭代25次,一次取100条数据训练,间隔一次就进行显示状态。然后开始训练。

training_epochs = 25
batch_size = 100
display_step = 1
saver = tf.train.Saver()
model_path = "log/521model.ckpt"

# 启动session
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())# Initializing OP

    # 启动循环开始训练
    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( " Finished!")

5.使用模型

在训练完成之后,我们就可以直接使用啦。

 # 测试 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:", accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))

这一段代码为测试代码,可以先看下模型准确率

在这里插入图片描述

6.保存模型

	save_path = saver.save(sess, model_path)
    print("Model saved in file: %s" % save_path)

用这两句代码对模型进行保存,并输出保存路径。
并且在session创建之前添加saver和model_path的定义。

saver = tf.train.Saver()
model_path = "log/521model.ckpt"

然后我们就可以在代码的同级目录下找到log文件夹,里面有有如下文件。
在这里插入图片描述

7.读取模型

在模型储存好后,我们用两张图片来实验一下,用下面的session代码替换掉以前的session。

with tf.Session() as sess:
    # Initialize variables
    sess.run(tf.global_variables_initializer())
    # Restore model weights from previously saved model
    saver.restore(sess, 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:", 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 = sess.run([output,pred], feed_dict={x: batch_xs})
    print(outputval,predv,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()

运行效果如下,到这里我们就已经成功了!
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章