【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)

这篇具有很好参考价值的文章主要介绍了【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需要源码和数据集请点赞关注收藏后评论区留言私信~~~

一、数据集简介

下面用到的数据集基于IAM数据集的英文手写字体自动识别应用,IAM数据库主要包含手写的英文文本,可用于训练和测试手写文本识别以及执行作者的识别和验证,该数据库在ICDAR1999首次发布,并据此开发了基于隐马尔可夫模型的手写句子识别系统,并于ICPR2000发布,IAM包含不受约束的手写文本,以300dpi的分辨率扫描并保存为具有256级灰度的PNG图像,IAM手写数据库目前最新的版本为3.0,其主要结构如下

约700位作家贡献笔迹样本

超过1500页扫描文本

约6000个独立标记的句子

超过一万行独立标记的文本

超过十万个独立标记的空间

展示如下 有许多张手写照片 

 【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)

 【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)

二、实现步骤 

1:数据清洗

删除文件中备注说明以及错误结果,统计正确笔迹图形的数量,最后将整理后的数据进行随机无序化处理

2:样本分类

接下来对数据进行分类 按照8:1:1的比例将样本数据集分为三类数据集,分别是训练数据集 验证数据集和测试数据集,针对训练数据集进行训练可以获得模型,而测试数据集主要用于测试模型的有效性

3:实现字符和数字映射

利用Tensorflow库的Keras包的StringLookup函数实现从字符到数字的映射 主要参数说明如下

max_tokens:单词大小的最大值

num_oov_indices:out of vocabulary的大小

mask_token:表示屏蔽输入的大小

oov_token:仅当invert为True时使用 OOV索引的返回值 默认为UNK

4:进行卷积变化 

通过Conv2D函数实现二维卷积变换 主要参数说明如下

filters:整数值 代表输出空间的维度

kernel_size:一个整数或元组列表 指定卷积窗口的高度和宽度

strides:一个整数或元组列表 指定卷积沿高度和宽度的步幅

padding:输出图像的填充方式

activation:激活函数

三、效果展示 

读取部分手写样本的真实文本信息如下

【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)

训练结束后 得到训练模型 导入测试手写文本数据 进行手写笔迹预测 部分结果如下

【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)

 

四、结果总结 

观察预测结果可知,基于均值池化以及训练过程预警极值,大部分的英文字符能够得到准确的预测判定,训练的精度持续得到改善,损失值控制在比较合理的区间内,没有发生预测准确度连续多次无法改进的场景,模型稳定性较好

五、代码

部分代码如下 需要全部代码请点赞关注收藏后评论区留言私信~~~



from tensorflow.keras.layers.experimental.preprocessing import StringLookup
from tensorflow import keras


import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import os
plt.rcParams['font.family'] = ['Microsoft YaHei']

np.random.seed(0)
tf.random.set_seed(0)


# ## 切分数据

# In[ ]:


corpus_read = open("data/words.txt", "r").readlines()
corpus = []
length_corpus=0
for word in corpus_read:
    if lit(" ")[1] == "ok"):
        corpus.append(word)
np.random.shuffle(corpus)
length_corpus=len(corpus)
print(length_corpus)
corpus[400:405]


# 划分数据,按照 80:10:10 比例分配给训练:有效:测试   数据

# In[ ]:


train_flag = int(0.8 * len(corpus))
test_flag = int(0.9 * len(corpus))

train_data = corpus[:train_flag]
validation_data = corpus[train_flag:test_flag]
test_data = corpus[test_flag:]

train_data_len=len(train_data)
validation_data_len=len(validation_data)
test_data_len=len(test_data)

print("训练样本大小:", train_data_len)
print("验证样本大小:", validation_data_len)
print("测试样本大小:",test_data_len )


# In[ ]:


image_direct = "data\images"


def retrieve_image_info(data):
    image_location = []
    sample = []
    for (i, corpus_row) in enumerate(data):
        corpus_strip = corpus_row.strip()
        corpus_strip = corpus_strip.split(" ")
        image_name = corpus_strip[0]
        leve1 = image_name.split("-")[0]
        leve2 = image_name.split("-")[1]
        image_location_detail = os.path.join(
            image_direct, leve1, leve1 + "-" + leve2, image_name + ".png"
        )
        if os.path.getsize(image_location_detail) >0 :
            image_location.append(image_location_detail)
            sample.append(corpus_row.split("\n")[0])
    print("手写图像路径:",image_location[0],"手写文本信息:",sample[0])

    return image_location, sample


train_image, train_tag = retrieve_image_info(train_data)
validation_image, validation_tag = retrieve_image_info(validation_data)
test_image, test_tag = retrieve_image_info(test_data)


# In[ ]:


# 查找训练数据词汇最大长度
train_tag_extract = []
vocab = set()
max_len = 0

for tag in train_tag:
    tag = tag.split(" ")[-1].strip()
    for i in tag:
        vocab.add(i)

    max_len = max(max_len, len(tag))
    train_tag_extract.append(tag)

print("最大长度: ", max_len)
print("单词大小: ", len(vocab))
print("单词内容: ", vocab)


train_tag_extract[40:45]


# In[ ]:


print(train_tag[50:54])
print(validation_tag[10:14])
print(test_tag[80:84])

def extract_tag_info(tags):
    extract_tag = []
    for tag in tags:
        tag = tag.split(" ")[-1].strip()
        extract_tag.append(tag)
    return extract_tag


train_tag_tune = extract_tag_info(train_tag)
validation_tag_tune = extract_tag_info(validation_tag)
test_tag_tune = extract_tag_info(test_tag)

print(train_tag_tune[50:54])
print(validation_tag_tune[10:14])
print(test_tag_tune[80:84])


# In[ ]:


AUTOTUNE = tf.data.AUTOTUNE

# 映射单词到数字
string_to_no = StringLookup(vocabulary=list(vocab),  invert=False)

# 映射数字到单词
no_map_string = StringLookup(
    vocabulary=string_to_no.get_vocabulary(),  invert=True)


# In[ ]:


def distortion_free_resize(image, img_size):
    w, h = img_size
    image = tf.image.resize(image, size=(h, w), preserve_aspect_ratio=True, antialias=False, name=None)

    # 计算填充区域大小
    pad_height = h - tf.shape(image)[0]
    pad_width = w - tf.shape(image)[1]

   
    if pad_height % 2 != 0:
        height = pad_height // 2
        pad_height_top = height + 1
        pad_height_bottom = height
    else:
        pad_height_top = pad_height_bottom = pad_height // 2

    if pad_width % 2 != 0:
        width = pad_width // 2
        pad_width_left = width + 1
        pad_width_right = width
    else:
        pad_width_left = pad_width_right = pad_width // 2

    image = tf.pad(
        image,
        paddings=[
            [pad_height_top, pad_height_bottom],
            [pad_width_left, pad_width_right],
            [0, 0],
        ],
    )

    image = tf.transpose(image, perm=[1, 0, 2])
    image = tf.image.flip_left_right(image)
    return image


# In[ ]:


batch_size = 64
padding_token = 99
image_width = 128
image_height = 32


def preprocess_image(image_path, img_size=(image_width, image_height)):
    image = tf.io.read_file(image_path)
    image = tf.image.decode_png(image, 1)
    image = distortion_free_resize(image, img_size)
    image = tf.cast(image, tf.float32) / 255.0
    return image


def vectorize_tag(tag):
    tag = string_to_no(tf.strings.unicode_split(tag, input_encoding="UTF-8"))
    length = tf.shape(tag)[0]
    pad_amount = max_len - length
    tag = tf.pad(tag, paddings=[[0, pad_amount]], constant_values=padding_token)
    return tag


def process_images_tags(image_path, tag):
    image = preprocess_image(image_path)
    tag = vectorize_tag(tag)
    return {"image": image, "tag": tag}


def prepare_dataset(image_paths, tags):
    dataset = tf.data.Dataset.from_tensor_slices((image_paths, tags)).map(
        process_images_tags, num_parallel_calls=AUTOTUNE
    )
    return dataset.batch(batch_size).cache().prefetch(AUTOTUNE)


# In[ ]:


train_final = prepare_dataset(train_image, train_tag_extract )
validation_final = prepare_dataset(validation_image, validation_tag_tune )
test_final = prepare_dataset(test_image, test_tag_tune )
print(train_final.take(1))
print(train_final)


# In[ ]:


plt.rcParams['font.family'] = ['Microsoft YaHei']

for data in train_final.take(1):
    images, tags = data["image"], data["tag"]

    _, ax = plt.subplots(4, 4, figsize=(15, 8))

    for i in range(16):
        img = images[i]
        img = tf.image.flip_left_right(img)
        img = tf.transpose(img, perm=[1, 0, 2])
        img = (img * 255.0).numpy().clip(0, 255).astype(np.uint8)
        img = img[:, :, 0]

        
        tag = tags[i]
        indices = tf.gather(tag, tf.where(tf.math.not_equal(tag, padding_token)))
       
        tag = tf.strings.reduce_join(no_map_string(indices))
        tag = tag.numpy().decode("utf-8")

        ax[i // 4, i % 4].imshow(img)
        ax[i // 4, i % 4].set_title(u"真实文本:%s"%tag)
        ax[i // 4, i % 4].axis("on")


plt.show()


# In[ ]:


class CTCLoss(keras.layers.Layer):

    def call(self, y_true, y_pred):
        batch_len = tf.cast(tf.shape(y_true)[0], dtype="int64")
        input_length = tf.cast(tf.shape(y_pred)[1], dtype="int64")
        tag_length = tf.cast(tf.shape(y_true)[1], dtype="int64")

        input_length = input_length * tf.ones(shape=(batch_len, 1), dtype="int64")
        tag_length = tag_length * tf.ones(shape=(batch_len, 1), dtype="int64")
               
        loss = keras.backend.ctc_batch_cost(y_true, y_pred, input_length, tag_length)
        self.add_loss(loss)
        
        return loss


def generate_model():
    # Inputs to the model
    input_img = keras.Input(shape=(image_width, image_height, 1), name="image")
    tags = keras.layers.Input(name="tag", shape=(None,))

    # First conv block.
    t = keras.layers.Conv2D(
        filters=32,
        kernel_size=(3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="ConvolutionLayer1")(input_img)
    t = keras.layers.AveragePooling2D((2, 2), name="AveragePooling_one")(t)

    # Second conv block.
    t = keras.layers.Conv2D(
        filters=64,
        kernel_size=(3, 3),
        activation="relu",
        kernel_initializer="he_normal",
        padding="same",
        name="ConvolutionLayer2")(t)
    t = keras.layers.AveragePooling2D((2, 2), name="AveragePooling_two")(t)
    

    #re_shape = (t,[(image_width // 4), -1])
    #tf.dtypes.cast(t, tf.int32)
    re_shape = ((image_width // 4), (image_height // 4) * 64)
    t = keras.layers.Reshape(target_shape=re_shape, name="reshape")(t)
    t = keras.layers.Dense(64, activation="relu", name="denseone",use_bias=False,
    kernel_initializer='glorot_uniform',
    bias_initializer='zeros')(t)
    t = keras.layers.Dropout(0.4)(t)

    # RNNs.
    t = keras.layers.Bidirectional(
        keras.layers.LSTM(128, return_sequences=True, dropout=0.4)
    )(t)

    t = keras.layers.Bidirectional(
        keras.layers.LSTM(64, return_sequences=True, dropout=0.4)
    )(t)
    
    


    t = keras.layers.Dense(
        len(string_to_no.get_vocabulary())+2, activation="softmax", name="densetwo"
    )(t)

    # Add CTC layer for calculating CTC loss at each step.
    output = CTCLoss(name="ctc_loss")(tags, t)

    # Define the model.
    model = keras.models.Model(
        inputs=[input_img, tags], outputs=output, name="handwriting"
    )
    # Optimizer.
    
    # Compile the model and return.
    model.compile(optimizer=keras.optimizers.Adam())
    
    
    
    
    
    return model


# Get the model.
model = generate_model()
model.summary()


# In[ ]:


validation_images = []
validation_tags = []

for batch in validation_final: 
    validation_images.append(batch["image"])
    validation_tags.append(batch["tag"])


# In[ ]:


#epochs = 20 

model = generate_model()
  
prediction_model = keras.models.Model(
    model.get_layer(name="image").input, model.get_layer(name="densetwo").output)
#edit_distance_callback = EarlyStoppingAtLoss()


epochs = 60
early_stopping_patience = 10
# Add early stopping
early_stopping = keras.callbacks.EarlyStopping(
    monitor="val_loss", patience=early_stopping_patience, restore_best_weights=True
)

# Train the model.
history = model.fit(
    train_final,
    validation_data=validation_final,
    epochs=60,callbacks=[early_stopping]
)


# ## Inference

# In[ ]:


plt.rcParams['font.family'] = ['Microsoft YaHei']
# A utility function to decode the output of the network.
def handwriting_prediction(pred):
    input_len = np.ones(pred.shape[0]) * pred.shape[1]
  = []
    for j in results:
        j = tf.gather(j, tf.where(tf.math.not_equal(j, -1)))
        j = tf.strings.reduce_join(no_map_string(j)).numpy().decode("utf-8")
        output_text.append(j)
    return output_text


#  Let's check results on some test samples.
for test in test_final.take(1):
    test_images = test["image"]
    _, ax = plt.subplots(4, 4, figsize=(15, 8))

    predit = prediction_model.predict(test_images)
    predit_text = handwriting_prediction(predit)

    for k in range(16):
        img = test_images[k]
        img = tf.image.flip_left_right(img)
        img = tf.transpose(img, perm=[1, 0, 2])
        img = (img * 255.0).numpy().clip(0, 255).astype(np.uint8)
        img = img[:, :, 0]

        title = f"预测结果: {predit_text[k]}"
     

# In[ ]:




创作不易 觉得有帮助请点赞关注收藏~~~文章来源地址https://www.toymoban.com/news/detail-403300.html

到了这里,关于【Tensorflow深度学习】实现手写字体识别、预测实战(附源码和数据集 超详细)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • (九)人工智能应用--深度学习原理与实战--前馈神经网络实现MNST手写数字识别

    目标: 识别手写体的数字,如图所示: 学习内容: 1、掌握MNIST数据集的加载和查看方法 2、熟练掌握Keras建立前馈神经网络的步骤【重点】 3、掌握模型的编译及拟合方法的使用,理解参数含义【重点】 4、掌握模型的评估方法 5、掌握模型的预测方法 6、掌握自定义图片的处理与

    2024年02月13日
    浏览(44)
  • CNN卷积神经网络实现手写数字识别(基于tensorflow)

    卷积网络的 核心思想 是将: 局部感受野 权值共享(或者权值复制) 时间或空间亚采样 卷积神经网络 (Convolutional Neural Networks,简称: CNN )是深度学习当中一个非常重要的神经网络结构。它主要用于用在 图像图片处理 , 视频处理 , 音频处理 以及 自然语言处理 等等。

    2024年02月11日
    浏览(41)
  • 跟姥爷深度学习1 浅用tensorflow做个天气预测

    (说明下,本篇的源码有点问题导致预测的温度有问题,请继续往后面的章节看,有原因和解决办法) 一、 前言 最近人工智能、深度学习又火了,我感觉还是有必要研究一下。三年前浅学了一下原理没深入研究框架,三年后感觉各种框架都成熟了,现成的教程也丰富了,所

    2023年04月16日
    浏览(34)
  • 深度学习(六):paddleOCR理解及识别手写体,手写公式,表格

    光学字符识别(Optical Character Recognition, OCR),ORC是指对包含文本资料的图像文件进行分析识别处理,获取文字及版面信息的技术,检测图像中的文本资料,并且识别出文本的内容。 那么有哪些应用场景呢? 其实我们日常生活中处处都有ocr的影子,比如在疫情期间身份证识别

    2024年02月05日
    浏览(47)
  • 【深度学习】2-4 神经网络-手写数字识别

    在实现对手写数字图像的分类,可以先假设学习已经全部结束,我们使用学习到的参数,先实现神经网络的“推理处理”。该处理也称为神经网络的 前向传播 。 和求解机器学习问题的步骤(分成学习和推理两个阶段进行)一样 使用神经网络解决问题时,也需要 首先使用训练数

    2024年02月09日
    浏览(58)
  • [深度学习实战]基于PyTorch的深度学习实战(下)[Mnist手写数字图像识别]

    PyTorch——开源的Python机器学习库   首先感谢所有点开本文的朋友们!基于PyTorch的深度学习实战可能要告一段落了。本想着再写几篇关于 PyTorch神经网络深度学习 的文章来着,可无奈项目时间紧任务重,要求 短时间内出图并做好参数拟合 。所以只得转战 Matlab 编程,框架旧

    2024年02月16日
    浏览(51)
  • 深度学习篇之tensorflow(2) ---图像识别

    研究图像识别离不开两样东西:第一,大量的样本数据;第二,好的算法。从某种意义上来说,数据比算法更重要,算法只是决定了图像识别的准确率,但如果没有样本数据,图像识别就无从谈起了。 图像识别的关键:特征 和特征之间的相对位置。 首先是特征,我们记住一

    2024年02月08日
    浏览(31)
  • python与深度学习(一):ANN和手写数字识别

    神经网络是学者通过对生物神经元的研究,提出了模拟生物神经元机制的人工神经网络的数学模型,生物神经元的模型抽象为如图所示的数学结构。 神经元输入向量𝒙 = [𝑥1,   𝑥2, 𝑥3, … , 𝑥𝑛]T,经过函数映射:𝑓: 𝒙 → 𝑦后得到输出𝑦。 考虑一种简化的情况,

    2024年02月16日
    浏览(44)
  • 【深度学习】基于华为MindSpore的手写体图像识别实验

    1 实验介绍 1.1 简介 Mnist手写体图像识别实验是深度学习入门经典实验。Mnist数据集包含60,000个用于训练的示例和10,000个用于测试的示例。这些数字已经过尺寸标准化并位于图像中心,图像是固定大小(28x28像素),其值为0到255。为简单起见,每个图像都被平展并转换为784(28*28)个

    2023年04月08日
    浏览(34)
  • 从手写数字识别入门深度学习丨MNIST数据集详解

    就像无数人从敲下“Hello World”开始代码之旅一样,许多研究员从“MNIST数据集”开启了人工智能的探索之路。 MNIST数据集(Mixed National Institute of Standards and Technology database)是一个用来训练各种图像处理系统的二进制图像数据集,广泛应用于机器学习中的训练和测试。 作为一

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包