TensorFlow入门(十六、识别模糊手写图片)

news2024/10/5 17:17:06

TensorFlow在图像识别方面,提供了多个开源的训练数据集,比如CIFAR-10数据集、FASHION MNIST数据集、MNIST数据集。

CIFAR-10数据集有10个种类,由6万个32x32像素的彩色图像组成,每个类有6千个图像。6万个图像包含5万个训练图像和1万个测试图像。

FASHION MNIST数据集由衣服、鞋子等服饰组成,包含7万张图像,其中6万张训练图像加1万张测试图像,图像大小为28x28像素,都为单通道,共分10个类。

MNIST数据集是一个入门级的计算机视觉数据集,一共6万张训练图像和1万张测试图像,共有数字0-9共10个类别,包含了各种手写数字图片及每一张图片对应的标签。标签主要告诉我们每个图片中的数字是哪一个数字。

识别模糊手写图片的代码逻辑步骤包含:

        ①导入MNIST数据集

                获得MNIST数据集有两种方法:

                        第一种是从MNIST数据集的官网获取,登录后手动下载

                                训练集图片文件信息格式如下:

                                文件头信息包含4个unsinged int32整型数据,分别是魔数(magic number)、图片数、图片宽度、图片长度。其中魔数的值是0x00000803,转换成十进制是2051,数据存储的位置是0016,从0016开始后面的数据是所有图像的像素,每个byte一个像素点。图片的长度都是28,所以每张图片长度为20*28=784,每个像素点的取值范围是0~255。

                                如果训练集图片文件是黑白的图片,图片中黑色的地方数值为0;有图案的地方,数值为0~255之间的数字,数字的大小代表其颜色的深度。如果是彩色的图片,一个像素会由3个值来表示RGB(红、黄、蓝)。

                                训练集标签文件信息格式如下:

                                文件头信息包含2个unsinged int32整型数据,分别是魔数(magic number)、标签数。其中魔数的值是0x00000801,转换成十进制是2049。数据存储的位置是0008,从0008开始,后面的数据是所有的标签值。标签值的取值范围是0~9。

                        第二种是使用TensorFlow提供的库,直接自动下载与安装MNIST

示例代码如下:

import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow.keras as keras
(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

print(train_images.shape,train_labels.shape)
print(train_labels[:3])
train_labels = tf.one_hot(train_labels,depth = 10)
print(train_labels[:3])

plt.imshow(train_images[0])
plt.show()
plt.imshow(train_images[1])
plt.show()
plt.imshow(train_images[2])
plt.show()
plt.imshow(train_images[3])
plt.show()

        ②分析MNIST样本特点

        ③构建模型

                构建模型的代码示例如下:

model = keras.Sequential()

model.add(keras.layers.Flatten(input_shape = (28,28)))

model.add(keras.layers.Dense(128,activation = tf.nn.relu))

model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

                先使用序贯模型创建一个Sequential对象,通过add方法为对象添加了三个卷积层:

                        第一层是接受输入层,因minst数据集中图片的像素大小为28*28,因此将接受到的输入展平为一维向量28*28=784,获得图片输入

                        第二层是中间层,设置共有128个神经元,激活函数是relu

                        第三层是输出层,因为要分的类别为0~9,共10个,所以这里设置神经元为10个,激活函数是softmax

                激活函数relu示意图如下

                        relu函数 : 只有当输入的值是正数时,才会有相应的输出。如果输入的是负数,不论输入多大,输出总是0。

                激活函数softmax示意图如下

                        softmax函数 : 不论输入值的大小,把输出值压缩在0~1之间。

import tensorflow as tf
import tensorflow.keras as keras

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))
model.summary()

                中间层是100480。每个图片展平后是784个元素,784*128个神经元等于100352。因为模型自动为输入层和中间层加了一个bias,相当于一个截距。所以最终等于(784+1)再乘以128,正好等于100480。同样的道理,输出层的1290等于128个神经元+1后乘以10计算所得。这种输入层加一个bias,中间层加一个bias。输出层分为10个类别的网络结构,也叫作全连接网络结构。

        ④训练模型并输出中间状态参数

train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#用测试数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5,callbacks = [callbacks])
#用evaluate函数评估成效、模型的效果
test_images = test_images/255.0
model.evaluate(test_images,test_labels)

                一共分为三步:

                        第一步:指定优化的方法、损失函数和训练时的精度

                        第二步:用测试数据集进行训练,这里设置训练5轮

                        第三步:用evaluate函数评估训练的成效和模型的效果

                第一步中的adam是常用的优化方法。当输出的数据是类别且需要判断类别时,需要用Categorical。Categorical分为SparseCategoricalCrossentropy()与CategoricalCrossentropy()两种:目标是one-hot编码,比如二分类[0,1][1,0]时,损失函数用categorical_crossentropy;目标是数字编码,比如二分类0,1,损失函数用sparse_categorical_crossentropy。因为现在label是整数9,所以就用sparse_categorical_crossentropy。

                为了让训练的效果更好,可以对输入的数据做归一处理,将数据变成0~1之间的数。

import tensorflow as tf
import tensorflow.keras as keras

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5)

        ⑤测试模型

                测试模型的代码示例如下:

test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)

示例代码如下:

import tensorflow as tf
import tensorflow.keras as keras

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])

#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5)

#归一化
test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)

                过拟合

                        过拟合就是神经网络模型对它判别过的图片识别得很准确,但对新的图片识别得很差

                        当训练时候的损失loss和测试时候的损失loss出现分叉的时候,过拟合现象就出现了

                        在训练过程中,需要设置一些条件,及时终止训练,防止过拟合现象的发生。这些条件可以通过Python代码自定义为一个回调类,生成一个实例;也可以直接使用TensorFlow的回调函数callbacks;在使用model.fit方法训练模型时,作为参数,传递给callbacks,从而使得程序在满足条件后终止训练。

示例代码如下:

import tensorflow as tf
import tensorflow.keras as keras

class myCallback(keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs = {}):
        if (logs.get("loss") < 0.4):
            self.model.stop_training-True
            
callbacks = myCallback()

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])

#用训练数据集训练,训练5轮
model.fit(train_images,train_labels,epochs = 5,callbacks = [callbacks])

#归一化
test_images = test_images/255.0
#用evaluate函数评估成效、模型的效果
model.evaluate(test_images,test_labels)

                我们也可以稍微改下代码,使数据可视化

示例代码如下:

import tensorflow as tf
import matplotlib.pyplot as plt
import tensorflow.keras as keras

class myCallback(keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs = {}):
        if (logs.get("loss") < 0.4):
            self.model.stop_training-True
            
callbacks = myCallback()

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#归一化
test_images = test_images/255.0
#用训练数据集训练,训练5轮
history = model.fit(train_images,train_labels,validation_data = (test_images,test_labels),epochs = 5,callbacks = [callbacks])

# 绘制训练损失和验证损失随训练轮次变化的曲线图
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

# 绘制训练准确率和验证准确率随训练轮次变化的曲线图
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

        ⑥保存模型

                训练好模型,指定了模型保存的路径后,使用keras的回调函数(callbacks)的断点方法(ModelCheckpoint)将模型保存到指定的路径。该方法的作用是按照一定的频率保存模型到指定的路径,通常是每结束一轮训练即保存一次,和model.compile()、model.fit()结合使用。该方法的具体参数如下:

keras.callbacks.ModelCheckpoint(filepath,monitor = "val_loss",verbose = 0,save_best_only = False,save_weights_only = False,mode = "auto",period = 1)

                其中

                filepath接收的参数是个字符串,指保存模型的路径。

                monitor为被监测的数据,值为精度(val_acc)或损失值(val_loss)。一般和model.compile()函数中metrics的值相同。如compile()函数中指定metrics = ["accuracy"],则monitor = "accuracy"。

                verbose指详细展示模式,值为0或者1。0为不打印输出信息,1为打印输出信息。

                save_best_only,用于设置是否保存在验证集上性能最好的模型,如果save_best_only = True,将覆盖之前的模型,只保存在验证集上性能最好的模型。

                save_weights_only,用于设置是否只保存模型参数,如果为True,那么只保存模型参数,如果为False,则保存整个模型。二者的区别在于,只保存模型参数的情况下,想用模型参数时,需要先将整个网络结构写出来,然后将模型参数文件导入到网络中。

                mode,该参数的值为{auto,min,max}的其中之一,具体为哪个值和前面的参数设置有关。如果save_best_only = True,则是否覆盖保存文件的决定就取决于被监测数据(monitor)的最大值或最小值。如果是精度(val_acc),mode则为max;如果是损失值(val_loss),mode则为min。在auto模式下,评价准则由被监测值的名字自动推断。

                period,该参数指每个检查点之间的间隔,即训练轮数。

示例代码如下:

import tensorflow as tf
import tensorflow.keras as keras

class myCallback(keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs = {}):
        if (logs.get("loss") < 0.4):
            self.model.stop_training-True
            
callbacks = myCallback()

save_model_cb = tf.keras.callbacks.ModelCheckpoint(filepath='model.keras', save_freq='epoch')

(train_images,train_labels),(test_images,test_labels) = keras.datasets.mnist.load_data()

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28,28)))
model.add(keras.layers.Dense(128,activation = tf.nn.relu))
model.add(keras.layers.Dense(10,activation = tf.nn.softmax))

#归一化
train_images = train_images/255.0
#指定优化的方法、损失函数和训练时的精度
model.compile(optimizer = "adam",loss = "sparse_categorical_crossentropy",metrics = ["accuracy"])
#归一化
test_images = test_images/255.0
#用训练数据集训练,训练5轮
history = model.fit(train_images,train_labels,validation_data = (test_images,test_labels),epochs = 5,callbacks = [callbacks,save_model_cb])

        ⑦读取模型

                读取模型,即向模型传入新的图片,实现图片的识别。一共分为三步:

                        第一步 : 查找到模型文件

                        第二步 : 加载模型

                        第三步 : 使用模型判断图片中的数字是哪个标签类别的概率

示例代码如下:

import tensorflow as tf
import tensorflow.keras as keras
import numpy as np
from PIL import Image
import os

class model(object):
  def __init__(self):
    #创建一个Sequential对象,以便堆叠各个卷积层。
    model=keras.Sequential()
    #给模型添加第一个输入层,将输入展平为一维向量28*28=784,获得图片输入
    model.add(keras.layers.Flatten(input_shape=(28,28)))
    #给模型添加第二个中间层,共有128个神经元
    model.add(keras.layers.Dense(128, activation=tf.nn.relu))
    #输出层为10的普通的神经网络,激活函数是softmax,10位恰好可以表达0-9十个数字。
    model.add(keras.layers.Dense(10, activation=tf.nn.softmax))
    #用来打印定义的模型的结构
    model.summary()
    self.model = model

class Predict(object):
    def __init__(self):
        #加载由keras保存的模型
        loaded_model = keras.models.load_model('model.keras')
        #print("===========///===========: ",loaded_model.get_weights())
        self.model=model()
        #使用Keras加载模型的权重,并将其设置为当前模型的权重
        self.model.model.set_weights(loaded_model.get_weights())
    def predict(self, image_path):
        # 以灰度图像方式读取图片
        img=Image.open(image_path).convert('L')
        #将PIL图像对象转换为大小为(28, 28)的NumPy数组
        flatten_img = np.reshape(img, (28, 28))
        #将形状重塑后的图像数组包装成一个数组 x,这是因为模型期望以批次的形式接收输入,即使只有一张图像也要如此
        x = np.array([flatten_img])
        #使用模型对输入的图像进行预测,得到预测结果
        y = self.model.model.predict(x,verbose=1)

        print("image_path: ",image_path)
        # 因为x只传入了一张图片,取y[0]即可
        # np.argmax()取得最大值的下标,即代表的数字
        print('神经网络 -> 预测结果:您写入的数字为:', np.argmax(y))


if __name__ == "__main__":
    image_predict = Predict()
    file_dir = 'D:/anaconda3/envs/tensorflow/Lib/site-packages/tensorflow/python/client/test_image'
    for filename in os.listdir(file_dir):
        image_path = os.path.join(file_dir, filename)  # 拼接文件路径
        image_predict.predict(image_path)

                其中的model.keras是之前保存的模型,file_dir是存放图片的路径,如下图

代码运行结果如下:

需要注意的是:

        在使用图像处理工具包打开图片路径的时候,该路径下的图片需要和训练时输入的图片保持像素大小以及不同像素分布特点上的一致。这是因为,在构建模型时,设置的输入图片的形状大小,就是28*28像素。因此读取环节,向模型输入的图片也需要是28*28像素。为了保证识别得准确度,最后向模型输入的图片,是将下载的mnist数据集解析后,从解析的图片中挑选出来的。

文件解析的方法与原理icon-default.png?t=N7T8http://t.csdnimg.cn/rCY0q

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1077285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件行业与就业(导师主讲)

在企业软件应用的整体架构体系中&#xff0c;有一部分被称为中间件&#xff0c;那么什么叫中间件&#xff1f; 中间件&#xff08;Middleware&#xff09;是指位于操作系统和应用程序之间的一层软件层&#xff0c;它提供了一组工具和服务&#xff0c;用于简化和增强企业软件应用…

Generative AI 新世界 | 文生图领域动手实践:预训练模型的微调

在上期文章&#xff0c;我们探讨了预训练模型的部署和推理&#xff0c;包括运行环境准备、角色权限配置、支持的主要推理参数、图像的压缩输出、提示工程 (Prompt Engineering)、反向提示 (Negative Prompting) 等内容。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资…

掌握C语言:开启编程世界的大门

掌握C语言&#xff1a;开启编程世界的大门 C语言编写的程序通常更高效&#xff0c;代码行数更少&#xff0c;适用于需要高性能的场景。掌握C语言还为你打开了学习其他高级编程语言的大门。C语言拥有庞大的开源社区和丰富的现成代码库&#xff0c;为你快速开发算法和函数提供了…

Nginx配置ssl证书(https证书)

Nginx配置ssl证书(https证书) 安装nginxNginx 的 SSL 模块安装下载Nginx 服务证书配置nginx.conf 安装nginx 搭建服务器,安装docker-compose https://blog.csdn.net/qq_33240556/article/details/124789530 安装docker-compose nginx https://blog.csdn.net/qq_33240556/artic…

做运维有前途吗?

不管男生女生&#xff0c;都不建议做运维&#xff01;&#xff01;就一个原因&#xff0c;性价比太低&#xff01;需要会的东西多&#xff0c;没有一个统一的运维标准&#xff01;你心目中的运维和别人心目中的运维&#xff0c;不是一个运维&#xff01;也不建议做测试&#xf…

【软件测试】博客系统项目测试报告(ssm项目)

文章目录 一. 报告概要二. 引言三. 测试环境四. 测试执行概况及功能测试1. 手工测试1.1 编写测试用例1.2 执行部分测试用例 2. 自动化测试Selenium2.1 编写测试用例2.2自动化测试代码1. 自动化测试工具类2. 博客登录页测试3. 博客注册页4. 博客详情页5. 博客编辑页6. 博客列表页…

易点易动:解决纸质固定资产审批痛点,助您高效自定义审批流程

固定资产审批是企业日常管理中不可或缺的环节&#xff0c;然而&#xff0c;传统的纸质审批流程常常面临繁琐、低效的问题。易点易动作为一款先进的固定资产管理系统&#xff0c;以其自定义设置流程的特点&#xff0c;为企业打破审批瓶颈&#xff0c;实现高效审批提供了理想解决…

轻量级虚拟化技术草稿

Support Tech ST.1 virtiofs ST.1.1 fuse framework 引用wiki中关于fuse的定义&#xff1a; Filesystem in Userspace (FUSE) is a software interface for Unix and Unix-like computer operating systems that lets non-privileged users create their own file systems w…

Python 编程基础概念

目录 1 Python程序的构成1.1 使用\行连接符 2 对象3 引用4 标识符4.1 Python标识符命名规则 5 变量和简单赋值语句5.1 变量的声明和赋值5.2 删除变量和垃圾回收机制5.3 链式赋值5.4 系列解包赋值5.5 常量 6 最基本内置数据类型和运算符6.1 基本运算符6.2 整数6.3 浮点数6.4 类型…

华为数通方向HCIP-DataCom H12-831题库(多选题:241-259)

第241题 设备产生的信息可以向多个方向输出信息,为了便于各个方向信息的输出控制,信息中心定义了10条信息通道,使通道之间独立输出,缺省情况下,以下哪些通道对应的输出方向可以接收Trap信息? A、console通道 B、logbuffer通道 C、snmpagent通道 D、trapbuffer通道 答案:…

山西电力市场日前价格预测【2023-10-11】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-11&#xff09;山西电力市场全天平均日前电价为507.37元/MWh。其中&#xff0c;最高日前电价为873.70元/MWh&#xff0c;预计出现在18: 45。最低日前电价为313.23元/MWh&#xff0c;预计…

互联网从业者如何调节压力

互联网从业者面临着多种压力源&#xff0c;如工作性质、竞争、项目失败、对失败的恐惧等&#xff0c;这些压力会影响身心健康以及工作效率。因此&#xff0c;采取有效的压力调节方法是必要的&#xff0c;接下来我们从三个方向探讨下互联网从业者有关压力来源、应对压力的方法及…

leetcode每日一练-第977题-有序数组的平方

一、思路 双指针 二、 解题方法 i指向起始位置&#xff0c;j指向终止位置。 定义一个新数组result&#xff0c;和A数组一样的大小&#xff0c;让k指向result数组终止位置。 如果A[i] * A[i] < A[j] * A[j] 那么result[k--] A[j] * A[j]; 。 如果A[i] * A[i] > A[j…

Echarts使用感受

目录 数据处理 遇到的问题 更换echart主题 Y轴数字后添加百分比号 eCharts饼图显示百分比 echarts自定义主题的手把手教学 查看UI图 点击下方链接页面的定制主题按钮 点击下载主题 点击主题下载的JSON版本&#xff0c;点击复制 ​编辑 新建js文件&#xff0c;把复制的…

【Java】什么是API

API (Application Programming Interface,应用程序编程接口) Java中的API 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层封装起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只需要学习这些类如何使用即可&#xff0c;我们可以通过帮助文档…

二、监控搭建-Prometheus-采集端部署

二、监控搭建-Prometheus-采集端部署 1、背景2、目标3、传承4、操作 1、背景 在上一篇中我们搭建了Prometheus平台&#xff0c;平台的搭建跟Linux系统上面安装了vim软件一样&#xff0c;给的只是一个很好的铸剑玄铁&#xff0c;具体的使用需要打磨和配件的运用。 2、目标 使…

XGBoost 2.0:对基于树的方法进行了重大更新

XGBoost是处理不同类型表格数据的最著名的算法&#xff0c;LightGBM 和Catboost也是为了修改他的缺陷而发布的。9月12日XGBoost发布了新的2.0版&#xff0c;本文除了介绍让XGBoost的完整历史以外&#xff0c;还将介绍新机制和更新。 这是一篇很长的文章&#xff0c;因为我们首…

转守为攻,亚马逊云换帅背后的战略转向

点击关注 文&#xff5c;刘雨琦 一则人事任命&#xff0c;揭开了亚马逊云在大中华区反击战的序幕。 10月9日&#xff0c;亚马逊云科技全球销售、市场和服务高级副总裁 Matt Garman 宣布了大中华区领导人变更任命&#xff0c;储瑞松将接替张文翊担任该职位&#xff0c;继续带领…

2023年网络安全岗位有哪些?金九银十别错过秋招!

网络安全有哪些岗位&#xff1f; 1. 安全服务工程师 7-10k 网络安全工程师、安全项目经理&#xff1a;主要负责甲方设备安全调试工作。需精通服务器、网络技术以及安全设备原理与配置。 2. 安全运维工程师 7-10k 安全运维工程师&#xff0c;主要对己方安全防御体系的运维和应急…

如何在 Spring Boot 中提高应用程序的安全性

如何在 Spring Boot 中提高应用程序的安全性 Spring Boot是一种流行的Java开发框架&#xff0c;用于构建Web应用程序和微服务。在构建应用程序时&#xff0c;安全性是至关重要的因素。不论您的应用程序是面向公众用户还是企业内部使用&#xff0c;都需要采取适当的措施来确保数…