手写体识别Tensorflow实现

简介:本文先讲解了手写体识别中涉及到的知识,然后分步讲解了代码的详细思路,完成了手写体识别案例的讲解,希望能给大家带来帮助,也希望大家多多关注我。本文是基于TensorFlow1.14.0的环境下运行的

手写体识别Tensorflow实现

  • [1 MNIST数据集处理](#1 MNIST数据集处理)
  • [2 神经网络](#2 神经网络)
  • [3 Softmax函数](#3 Softmax函数)
    • [3.1 什么时候用softmax](#3.1 什么时候用softmax)
    • [3.2 softmax的优越性](#3.2 softmax的优越性)
  • [4 代码实现分步讲解](#4 代码实现分步讲解)
    • [4.1 导包](#4.1 导包)
    • [4.2 载入数据](#4.2 载入数据)
    • [4.3 批次batch](#4.3 批次batch)
    • [4.4 placeholder的定义](#4.4 placeholder的定义)
    • 4.5神经网路模型的构建
    • [4.6 损失函数](#4.6 损失函数)
    • 4.7使用梯度下降
    • [4.8 初始化 variable](#4.8 初始化 variable)
    • [4.9 预测结果](#4.9 预测结果)
      • [4.9.1 tf.equal函数](#4.9.1 tf.equal函数)
      • [4.9.2 tf.argmax函数](#4.9.2 tf.argmax函数)
    • 4.10计算准确率
      • [4.10.1 tf.cast数据类型转换](#4.10.1 tf.cast数据类型转换)
      • [4.10.2 tf.reduce_mean](#4.10.2 tf.reduce_mean)
    • [4.13 对输入进行处理](#4.13 对输入进行处理)
    • [4.12 使用Session进行训练](#4.12 使用Session进行训练)
    • 4.13代码汇总
  • 致谢

1 MNIST数据集处理

数据集的网址如下:https://yann.lecun.com/exdb/mnist/
他的数据集有训练集 测试集图片与标签四部分组成

被分为两部分 6万行训练数据集和1万行的测试数据集

每一张图片包含2828个像素,把他展开成一维向量,长度是284 284 = 784,所以训练集是shape为[60000,784]的张量,第一个维度数字用来索引图片,第二个维度数字用来索引图片中的像素点

他的标签是介于0-9的数字,我们要把它转化为one - hot,也叫做独热 ,比如3 转化为 [0,0,1,0,0,0,0,0,0],他是几就让第几个数字为1.。所以labels将会被转化为一个shape为[60000,10]的矩阵

2 神经网络

根据第一节的内容我们可以设计一个简单的神经网络实现手写体识别,如果想提升准确率,可以在中间加入隐藏层。

3 Softmax函数

就用手写体识别这个举例子,比如说预测了某张图片的shape为[1,10]的可能是[15,3,1,0,2,4,5,1,1,0],我们希望将他转化为概率 ,且需要所有概率和为1,我们来看softmax的数学公式

这个zi就是对应[1,10]矩阵中的权重,zj这个分母部分是所有的和

这样子计算既满足了归一化的需求

3.1 什么时候用softmax

一般是用在神经网络的输出层,用于分类或者回归

3.2 softmax的优越性

  • 满足了人们对归一化的需求
  • 指数函数容易求偏导
  • 指数函数咋信息论和统计学中常用,可以联系这些,为神经网络的构建提供数学依据

4 代码实现分步讲解

4.1 导包

因为环境和版本等种种原因,他经常会报一些无关痛痒的小警告,所以我们要把这些警告屏蔽掉,然后导入TensorFlow等包

python 复制代码
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

4.2 载入数据

python 复制代码
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train)
print(y_train)

4.3 批次batch

这些图片不会一次性处理运算量太大了,比如设置为100,每次都会处理100张图片

python 复制代码
batch_size = 100

还需要计算一共有多少个批次

python 复制代码
n_batch = len(x_train) // batch_size
print(n_batch)

4.4 placeholder的定义

python 复制代码
x = tf.compat.v1.placeholder(tf.float32,[None,784])
y = tf.compat.v1.placeholder(tf.float32,[None,10])

4.5神经网路模型的构建

python 复制代码
Weight = tf.compat.v1.Variable(tf.zeros([784,10]))
bias = tf.compat.v1.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x,Weight)+bias)

4.6 损失函数

python 复制代码
loss = tf.reduce_mean(tf.square(y-prediction))

4.7使用梯度下降

如果您不会用,请阅读我的文章: 线性回归,在该文章中讲解了该函数的具体用法

python 复制代码
train_step = tf.compat.v1.train.GradientDescentOptimizer(0.2).minimize(loss)

4.8 初始化 variable

python 复制代码
init_option = tf.compat.v1.global_variables_initializer()

4.9 预测结果

4.9.1 tf.equal函数

他的作用是判断预测和真实是否一致

4.9.2 tf.argmax函数

因为我们计算的是某张图是那个数字的概率,所以需要把最大的拿出来当做是这个图的预测结果

最后我们的道德结果是一个由False和True组成的列表

python 复制代码
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))

4.10计算准确率

4.10.1 tf.cast数据类型转换

我们需要先把布尔类型的结果转化为浮点类型 1...0和0

4.10.2 tf.reduce_mean

他的作用是计算张量的平均值

python 复制代码
accuracy_rate = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))

4.13 对输入进行处理

python 复制代码
# 将输入数据重塑为二维形式(原本图像数据是二维的,这里要展平为一维向量作为神经网络输入)
# 例如原来是 (60000, 28, 28) 变成 (60000, 784),60000是样本数量,784是28*28(图像像素数量)
x_train = x_train.reshape(x_train.shape[0], -1)
x_test = x_test.reshape(x_test.shape[0], -1)

4.12 使用Session进行训练

python 复制代码
with tf.compat.v1.Session() as calculate:
    calculate.run(init_option)
    
    y_train = calculate.run(tf.one_hot(y_train, depth=10))
    # 将测试集标签进行独热编码,显式指定会话参数
    y_test = calculate.run(tf.one_hot(y_test, depth=10))

    for epoch in range(21):
        for batch in range(n_batch):
            # 计算当前batch的起始索引和结束索引
            start_index = batch * batch_size
            end_index = start_index + batch_size
            # 从训练数据集中提取当前batch的输入数据和标签数据
            batch_x = x_train[start_index:end_index]
            batch_y = y_train[start_index:end_index]
            # 将当前batch的数据喂入计算图进行训练
            calculate.run(train_step, feed_dict={x: batch_x, y: batch_y})
        # 在每个epoch结束后,在测试集上计算并打印当前的准确率
        acc = calculate.run(accuracy_rate, feed_dict={x: x_test, y: y_test})
        print("Epoch {}: Accuracy {}".format(epoch + 1, acc))

4.13代码汇总

python 复制代码
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
print(x_train)
print(y_train)
batch_size = 100
n_batch = len(x_train) // batch_size
print(n_batch)
x = tf.compat.v1.placeholder(tf.float32,[None,784])
y = tf.compat.v1.placeholder(tf.float32,[None,10])
Weight = tf.compat.v1.Variable(tf.zeros([784,10]))
bias = tf.compat.v1.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x,Weight)+bias)
loss = tf.reduce_mean(tf.square(y-prediction))
train_step = tf.compat.v1.train.GradientDescentOptimizer(0.2).minimize(loss)
init_option = tf.compat.v1.global_variables_initializer()
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
accuracy_rate = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
# 将输入数据重塑为二维形式(原本图像数据是二维的,这里要展平为一维向量作为神经网络输入)
# 例如原来是 (60000, 28, 28) 变成 (60000, 784),60000是样本数量,784是28*28(图像像素数量)
x_train = x_train.reshape(x_train.shape[0], -1)
x_test = x_test.reshape(x_test.shape[0], -1)
with tf.compat.v1.Session() as calculate:
    calculate.run(init_option)
    
    y_train = calculate.run(tf.one_hot(y_train, depth=10))
    # 将测试集标签进行独热编码,显式指定会话参数
    y_test = calculate.run(tf.one_hot(y_test, depth=10))

    for epoch in range(21):
        for batch in range(n_batch):
            # 计算当前batch的起始索引和结束索引
            start_index = batch * batch_size
            end_index = start_index + batch_size
            # 从训练数据集中提取当前batch的输入数据和标签数据
            batch_x = x_train[start_index:end_index]
            batch_y = y_train[start_index:end_index]
            # 将当前batch的数据喂入计算图进行训练
            calculate.run(train_step, feed_dict={x: batch_x, y: batch_y})
        # 在每个epoch结束后,在测试集上计算并打印当前的准确率
        acc = calculate.run(accuracy_rate, feed_dict={x: x_test, y: y_test})
        print("Epoch {}: Accuracy {}".format(epoch + 1, acc))

致谢

本文参考了一些博主的文章,博取了他们的长处,也结合了我的一些经验,对他们表达诚挚的感谢,使我对 Tensorflow在手写体识别的使用有更深入的了解,也推荐大家去阅读一下他们的文章。纸上学来终觉浅,明知此事要躬行:
Softmax函数

相关推荐
岑梓铭9 分钟前
(CentOs系统虚拟机)Standalone模式下安装部署“基于Python编写”的Spark框架
linux·python·spark·centos
边缘计算社区12 分钟前
首个!艾灵参编的工业边缘计算国家标准正式发布
大数据·人工智能·边缘计算
游客52023 分钟前
opencv中的各种滤波器简介
图像处理·人工智能·python·opencv·计算机视觉
一位小说男主23 分钟前
编码器与解码器:从‘乱码’到‘通话’
人工智能·深度学习
Eric.Lee202126 分钟前
moviepy将图片序列制作成视频并加载字幕 - python 实现
开发语言·python·音视频·moviepy·字幕视频合成·图像制作为视频
Dontla30 分钟前
vscode怎么设置anaconda python解释器(anaconda解释器、vscode解释器)
ide·vscode·python
深圳南柯电子39 分钟前
深圳南柯电子|电子设备EMC测试整改:常见问题与解决方案
人工智能
Kai HVZ40 分钟前
《OpenCV计算机视觉》--介绍及基础操作
人工智能·opencv·计算机视觉
biter00881 小时前
opencv(15) OpenCV背景减除器(Background Subtractors)学习
人工智能·opencv·学习
吃个糖糖1 小时前
35 Opencv 亚像素角点检测
人工智能·opencv·计算机视觉