手写体识别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函数

相关推荐
Microvision维视智造6 分钟前
解析大尺寸液晶屏视觉检测,装配错位如何避免?
人工智能·计算机视觉·视觉检测
lilye6623 分钟前
精益数据分析(11/126):辨别虚荣指标,挖掘数据真价值
大数据·人工智能·数据分析
微学AI23 分钟前
详细介绍:MCP(大模型上下文协议)的架构与组件,以及MCP的开发实践
前端·人工智能·深度学习·架构·llm·mcp
Samuel-Gyx32 分钟前
2025第十六届蓝桥杯python B组满分题解(详细)
python·职场和发展·蓝桥杯
豆包MarsCode1 小时前
玩转MCP | 一文看懂如何在 Trae IDE 中解锁 MCP
人工智能·mcp·trae
行者无疆xcc1 小时前
【Django】设置让局域网内的人访问
后端·python·django
患得患失9491 小时前
【后端】【python】Python 爬虫常用的框架解析
开发语言·爬虫·python
我不是小upper1 小时前
详解机器学习各算法的优缺点!!
人工智能·算法·机器学习
小君1 小时前
New 版本Trea 对比 Cursor 选择你的下一代 AI 编程伙伴
前端·人工智能·trae
研一计算机小白一枚1 小时前
第一章:自然语言处理
人工智能·自然语言处理