您的位置:首页 >要闻 >

使用 TensorFlow Lite 在 Android 上进行印地语字符识别

时间:2022-11-22 12:16:04 来源:

介绍

如果你曾经想构建一个用于文本识别的图像分类器,我假设你可能已经从 TensorFlow 的官方示例中实现了经典的手写数字识别应用程序 。

该程序通常被称为计算机视觉的“Hello World”,它是 ML 初学者构建分类器应用程序的一个很好的起点。构建一个识别任何字符的自定义分类器不是很好吗?在这篇文章中,我们将构建一个印地语字符识别应用程序,但你可以随意选择你自己选择的数据集。

我们将构建一个能够识别印地语字符的机器学习模型,而且也可以从头开始。我们不仅会构建机器学习模型,还会将其部署在 Android 移动应用程序上。因此,本文将作为端到端教程,涵盖构建和部署 ML 应用程序所需的几乎所有内容。

端到端流

数据准备

我们需要大量数据来训练应该产生良好结果的机器学习模型。你一定听说过 MNIST 数据集,对吧?让我们回忆一下。

MNIST 数字数据库使用 TensorFlow Lite 在 Android 上进行印地语字符识别

MNIST 代表“Modified National Institute of Standards and Technology”,是一个流行的手写数字识别数据库,包含超过 60,000 张数字 0-9 的图像。现在,了解 MNIST 数据库的外观和格式很重要,因为我们将合成一个“类似于 MNIST”的印地语字符数据集。

MNIST 数据集中的每个数字都是一个 28 x 28 的二进制图像,颜色为白色,背景为黑色。

MNIST 数字示例

好的,现在我们有了想法,让我们为印地语字符合成我们的数据集。我已经将数据集保存在我的 GitHub 存储库中。

该数据集包含所有印地语元音、辅音和数字。

这些图像必须转换为 NumPy 数组 (.npz),以供模型训练使用。下面的脚本将帮助你进行转换。

导入依赖

import tensorflow as tf

from tensorflow import keras

from PIL import Image

import os

import numpy as np

import matplotlib.pyplot as plt

import random

!pip install -q kaggle

!pip install -q kaggle-cli

print(tf.__version__)

import os

os.environ['KAGGLE_USERNAME'] = ""

os.environ['KAGGLE_KEY'] = ""

!kaggle datasets download -d nstiwari/hindi-character-recognition --unzip

将 JPG 图像转换为 NPZ(NumPy 数组)格式

# Converts all the images inside HindiCharacterRecognition/raw_images/10 into NPZ format.

path_to_files = "/content/HindiCharacterRecognition/raw_images/10/"

vectorized_images = []

for _, file in enumerate(os.listdir(path_to_files)):

image = Image.open(path_to_files + file)

image_array = np.array(image)

vectorized_images.append(image_array)

np.savez("./10.npz", DataX=vectorized_images)

加载训练图像 NumPy 数组

训练图像被矢量化为 NumPy 数组。换句话说,训练图像的像素在值 [0, 255] 之间被矢量化到单个“.npz”文件中。

path = "./HindiCharacterRecognition/vectorized_images/numeral_images.npz"

with np.load(path) as data:

#load DataX as train_data

train_images = data['DataX']

加载训练标签 NumPy 数组

同样,各个训练图像的标签也被矢量化并捆绑到单个“.npz”文件中。与图像数组不同,标签数组包含从 0 到 n-1 的离散值,其中 n = 类的数量。

path = "./HindiCharacterRecognition/vectorized_labels/numeral_labels.npz"

with np.load(path) as data:

#load DataX as train_data

train_labels = data['DataX']

NO_OF_CLASSES = 5 # Change the no. of classes according to your custom dataset

在此示例中,我正在为 5 个类( - ?、?、?、? 和 ?)训练模型。该数据集涵盖了所有元音、辅音和数字,因此你可以随意选择任何类别。

标准化输入图像

在这里,我们通过将每个像素除以 255 来归一化输入图像,因此每个像素的值都在 [0, 1] 之间。

值为 0 的像素是黑色的,而值为 1 的像素是白色的。介于 0 和 1 之间的任何值都是灰色的,其强度取决于离得最近的一端。

色标

# Normalize the input image so that each pixel value is between 0 to 1.

train_images = train_images / 255.0

print('Pixels are normalized.')

检查图像和标签数组的形状

· 图像阵列的形状应为 (X, 28, 28),其中 X = 图像的数量。

· 标签数组的形状应为 (X, )。

注意:图像的数量和标签的数量应该相等。

train_images.shape

train_labels.shape

可视化训练数据

# Show the first 50 images in the training dataset.

j = 0

plt.figure(figsize = (10, 10))

for i in range(550, 600): # Try playing with difference ranges in interval of 50. Example: range(250, 300)

j = j + 1

plt.subplot(10, 5, j)

plt.xticks([])

plt.yticks([])

plt.grid(False)

plt.imshow(train_images[i], cmap = plt.cm.gray)

plt.xlabel(train_labels[i])

plt.show()

数据集预览

我们的数据集现在看起来很完美,可以接受训练了。

模型训练

让我们从模型训练开始。

在下面的单元格中,我们定义了模型的层并设置了超参数,例如优化器、损失函数、指标、类和epoch的数量来量化模型性能。

# Define the model architecture.

model = keras.Sequential([

keras.layers.InputLayer(input_shape=(28, 28)),

keras.layers.Reshape(target_shape = (28, 28, 1)),

keras.layers.Conv2D(filters=32, kernel_size = (3, 3), activation = tf.nn.relu),

keras.layers.Conv2D(filters=64, kernel_size = (3, 3), activation = tf.nn.relu),

keras.layers.MaxPooling2D(pool_size = (2, 2)),

keras.layers.Dropout(0.25),

keras.layers.Flatten(),

keras.layers.Dense(NO_OF_CLASSES)

])

# Define how to train the model

model.compile(optimizer = 'adam', loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits = True), metrics = ['accuracy'])

# Train the digit classification model

model.fit(train_images, train_labels, epochs = 50)

model.summary()

我花了大约 30-45 分钟来训练 5 个类的模型,每个类有大约 200 张图像。训练模型的时间将根据你为用例选择的每个类和图像的数量而有所不同。在模型训练时,去喝杯咖啡。

量化(Quantization)

我们已经完成了这个博客的一半。TensorFlow 模型已准备就绪。但是,要在移动应用程序上使用此模型,我们需要对其进行量化并将其转换为 TF Lite 格式,这是原始 TF 模型的更轻量级版本。

量化允许在模型的准确性和大小之间进行有价值的权衡。随着精度的轻微下降,模型大小可以大大减小,从而使其部署更容易。

将 TF 模型转换为 TF Lite 格式

# Convert Keras model to TF Lite format.

converter = tf.lite.TFLiteConverter.from_keras_model(model)

tflite_float_model = converter.convert()

with open('model.tflite', 'wb') as f:

f.write(tflite_float_model)

# Show model size in KBs.

float_model_size = len(tflite_float_model) / 1024

print('Float model size = %dKBs.' % float_model_size)

# Re-convert the model to TF Lite using quantization.

converter.optimizations = [tf.lite.Optimize.DEFAULT]

tflite_quantized_model = converter.convert()

# Show model size in KBs.

quantized_model_size = len(tflite_quantized_model) / 1024

print('Quantized model size = %dKBs,' % quantized_model_size)

print('which is about %d%% of the float model size.' % (quantized_model_size * 100 / float_model_size))

# Save the quantized model to file to the Downloads directory

f = open('mnist.tflite', "wb")

f.write(tflite_quantized_model)

f.close()

# Download the digit classification model

from google.colab import files

files.download('mnist.tflite')

print('`mnist.tflite` has been downloaded')

我们现在已经准备好将 TF Lite 模型部署到 Android 应用程序上。

部署模型

已经开发了一个用于字符识别的 Android 应用程序。在第 1 步中,你可能已经克隆了存储库。在那里,你应该找到Android_App目录。

复制 Hindi-Character-Recognition-on-Android-using-TensorFlow-Lite/Android_App/app/src/main/assets 目录中的 mnist.tflite 模型文件。

接下来,在 Android Studio 中打开项目并让它自己构建一段时间。构建项目后,打开DigitClassifier.kt文件并编辑第 333 行,将其替换为模型中输出类的数量。

同样,在DigitClassifier.kt文件中,通过根据你的自定义数据集设置标签名称来编辑 第 118 行到第 132 行。

最后,再次构建项目并将其安装在你的 Android 手机上,并享受你自己定制的印地语字符识别应用程序。

最终应用

结论

快速总结一下:

· 我们从数据准备开始,合成一个类似于 MNIST 的数据集,用于印地语字符识别,由元音、辅音和数字组成;向量化图像和标签以输入神经网络。

· 接下来,我们通过添加 Keras 层来构建模型,配置超参数并开始模型训练。

· 在训练完 TF 模型后,我们将其量化并转换为 TF Lite 格式,以使其准备好部署。

· 最后,我们构建了一个 Android 应用程序,并在其上部署了我们的分类器模型。

原文标题:使用 TensorFlow Lite 在 Android 上进行印地语字符识别


郑重声明:文章仅代表原作者观点,不代表本站立场;如有侵权、违规,可直接反馈本站,我们将会作修改或删除处理。