安卓 图像清晰度识别_基于TensorFlow Lite模型的安卓图像识别

多亏了TensorFlow Lite(TFLite),我们可以构建适用于移动设备的深度学习模型。事实上,TFLite生成的模型专门针对移动和边缘部署进行了优化。在TensorFlow中创建深度学习模型后,开发人员可以使用TensorFlow Lite转换器将该模型转换为在移动设备中运行的格式。

在本教程中,我们将使用自定义数据集和卷积神经网络(CNN)构建一个用于在Android上识别图像的TensorFlow模型。

与从头创建CNN不同,我们将使用一个预先训练的模型并执行迁移学习,以使用我们的新数据集定制该模型。我们将使用的预训练模型是MobileNetV1,我们将在Fruits360数据集上训练它的一个版本。

在我们用转移学习构建了TensorFlow模型之后,我们将使用TFLite转换器来创建一个支持移动的模型变体。该模型随后将被用于一个Android应用程序中,该应用程序可以识别摄像头捕捉到的图像。

本教程构建的项目可以在GitHub或者码云上找到。经过测试,运行正常。建议您下载并使用它,如果有什么走不通的话。

本教程将创建一个运行在Google Colab中的Jupyter Notebook来构建定制模型。

要了解Google Colab中Jupyter笔记本的入门知识,请查看我之前的教程,其中介绍了一些核心功能。

本教程章节如下:

  • 准备MobileNet用于迁移学习
  • 下载数据集
  • 迁移学习
  • 下载Android Studio项目
  • 定制这个项目

准备MobileNet

TensorFlow中我们可以使用tensorflow.keras.applications模块下载预训练深度学习模型。在这个模块中,有几个类,分别对应负责一个模型。

例如,MobileNet类用于下载MobileNet模型。下面的代码下载MobileNet模型并将其保存在base_model变量中。MobileNet类的构造函数有两个参数:input_shape和include_top。

MobileNet使用固定的图像大小进行训练。当一个新的图像被送入这样一个预先训练的模型时,该图像必须与用于训练模型的图像大小相同。因为水果360数据集中的图像大小是(100100),所以我们将使用MobileNet版本,它是根据大小(128128)的图像进行训练的。原因是(128128)是最接近(100,100)的-其他大小是(160,160)和(224224,224)。

第二个参数设置为False,因为顶部的层是为MobileNet模型训练的数据集(ImageNet)使用的。

这样的层可以处理1000个类。我们将要使用的Fruits360数据集版本只有102个类,因此我们必须删除这些层,并添加可以与我们的数据集一起工作的其他层。

请注意,模型的trainable属性设置为False。这意味着模型的权重不会改变,而只会被使用。

from __future__ import absolute_import, division, print_function, unicode_literalstry:  # The %tensorflow_version magic only works in colab.  %tensorflow_version 2.xexcept Exception:  passimport tensorflow as tf IMG_SHAPE = (128, 128, 3)base_model = tf.keras.applications.MobileNet(input_shape=IMG_SHAPE, include_top=False)base_model.trainable = Falsemodel = tf.keras.Sequential([  base_model,  tf.keras.layers.GlobalAveragePooling2D(),  tf.keras.layers.Dense(102, activation='sigmoid')])model.summary()model.compile(optimizer=tf.keras.optimizers.RMSprop(lr=0.0001),              loss='binary_crossentropy',              metrics=['accuracy'])

为了在模型体系结构的顶部添加与我们的数据集一起工作的层,使用Sequential类。它接受层的列表以创建一个新的模型。

列表中的第一个元素是base_model。这意味着MobileNet中的所有层[除了顶层]都包含在新模型中。除这些层外,还增加了2个新的层,即平均池化层和全连接层。全连接层有102个神经元,因为我们的数据集有102个类。

Sequential类返回的新模型保存在model变量中,然后使用compile()方法进行编译。此方法接受优化器、损失函数和指标。唯一使用的指标是分类精度。

模型编译后,接下来是为迁移学习准备数据集。这里的迁移学习是指训练顶部结构新添加的层,以便它们可以用于新的数据集。

下载数据集

我们要使用的数据集可通过以下链接获得:

https://www.kaggle.com/moltean/fruits/version/48

在这个页面上,你会找到一个下载链接。点击它,下载就会开始了。您需要取消下载并复制开始下载的链接。之后,将下面代码中的链接替换为下载数据集时获取的链接。

请注意,下载链接将在几天后过期,如果它过期,则需要再次获取该链接。

import tensorflow as tfimport oszip_file = tf.keras.utils.get_file(origin="https://storage.googleapis.com/kaggle-datasets/5857/414958/fruits-360_dataset.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1566314394&Signature=rqm4aS%2FIxgWrNSJ84ccMfQGpjJzZ7gZ9WmsKok6quQMyKin14vJyHBMSjqXSHR%2B6isrN2POYfwXqAgibIkeAy%2FcB2OIrxTsBtCmKUQKuzqdGMnXiLUiSKw0XgKUfvYOTC%2F0gdWMv%2B2xMLMjZQ3CYwUHNnPoDRPm9GopyyA6kZO%2B0UpwB59uwhADNiDNdVgD3GPMVleo4hPdOBVHpaWl%2F%2B%2BPDkOmQdlcH6b%2F983JHaktssmnCu8f0LVeQjzZY96d24O4H85x8wdZtmkHZCoFiIgCCMU%2BKMMBAbTL66QiUUB%2FW%2FpULPlpzN9sBBUR2yydB3CUwqLmSjAcwz3wQ%2FpIhzg%3D%3D", fname="fruits-360.zip", extract=True)base_dir, _ = os.path.splitext(zip_file)print(base_dir)

数据集将作为名为fruits-360.zip的压缩文件下载,该文件是自动提取的,因为extract参数设置为True。提取文件的内容如下。我们将使用的文件夹是Test和Training,它们相应地保存测试和训练数据。

['readme.md', 'Test', 'papers', 'test-multiple_fruits', 'Training', 'LICENSE']

在下载数据集之后,接下来我们需要将其数据输入到MobileNet模型中,以便进行迁移学习,我们将在下一节中介绍这一点。

迁移学习和模型转换

下面给出的代码准备返回批量图像的数据生成器,用于训练新模型。最后,新模型被保存为MobileNet_TransferLearning_Fruits360v48.h5。

import osfrom __future__ import absolute_import, division, print_function, unicode_literalstry:  # The %tensorflow_version magic only works in colab.  %tensorflow_version 2.xexcept Exception:  passimport tensorflow as tfimport numpyzip_file = tf.keras.utils.get_file(origin="https://storage.googleapis.com/kaggle-datasets/5857/414958/fruits-360_dataset.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1568066045&Signature=apl0VAR2eb1vz8XOJAbxsf8KuSUmMqOCtoJ0HwDBh%2F2YkqtAnOtypYq5rpQF020%2ByqKGGTqbyVMZ1RC84CclDHxMratQlkHQP7Dh8W%2FBW5K4nxuNsInBG27kqIdx%2Ff%2Fere1WZOiqvUtXgf1uXNwbOjijqyIT77ypJFPhWt%2Bcg4cjjkbrFjumo1RAGbJ77u1A3nQu4VhxhH46tZ6xtEU0lrzSpMA3U8GkvHK0H65qTD3GzfZD%2FmjhDtD712mT3H5zPgvRFbbSenaGgE%2BdaqG5Z9EBK95FT19N2tSSOMQFGxhmG9VpiODHEn%2FIHDlyyH2E%2F7%2BpMDFMuB4n93NyFu%2FnMQ%3D%3D",                                   fname="fruits-360.zip", extract=True)base_dir, _ = os.path.splitext(zip_file)train_dir = os.path.join(base_dir, 'Training')validation_dir = os.path.join(base_dir, 'Test')image_size = 128batch_size = 32train_datagen = tf.keras.preprocessing.image.ImageDataGenerator()train_generator = train_datagen.flow_from_directory(directory=train_dir, target_size=(image_size, image_size), batch_size=batch_size)validation_datagen = tf.keras.preprocessing.image.ImageDataGenerator()validation_generator = validation_datagen.flow_from_directory(directory=validation_dir, target_size=(image_size, image_size), batch_size=batch_size)IMG_SHAPE = (image_size, image_size, 3)base_model = tf.keras.applications.MobileNet(input_shape=IMG_SHAPE, include_top=False)base_model.trainable = Falsemodel = tf.keras.Sequential([  base_model,  tf.keras.layers.GlobalAveragePooling2D(),  tf.keras.layers.Dense(102, activation='softmax')])model.summary()model.compile(optimizer=tf.keras.optimizers.Adam(),              loss='categorical_crossentropy',              metrics=['accuracy'])epochs = 1steps_per_epoch = numpy.ceil(train_generator.n / batch_size)validation_steps = numpy.ceil(validation_generator.n / batch_size)history = model.fit_generator(generator=train_generator,                              steps_per_epoch = steps_per_epoch,                              epochs=epochs,                              validation_data=validation_generator,                              validation_steps=validation_steps)

在定制了MobileNet来处理Fruits360数据集之后,定制的MobileNet仍然是一个TensorFlow模型,我们仍然需要将其转换为TensorFlow Lite,以便在Android上使用它。下面显示的代码使用TFLiteConverter 将模型转换为TFLite。

saved_model_dir = '/content/TFLite'tf.saved_model.save(model, saved_model_dir)converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)tflite_model = converter.convert()with open('model.tflite', 'wb') as f:    f.write(tflite_model)

为了构建一个Android应用程序可以根据Fruts360数据集中的类对图像进行分类,必须有一个保存类名的文本文件。下一个代码片段将创建这样一个文本文件。模型对输入图像进行预测后,利用预测得分来寻找图像的类标签。

labels = ''.join(sorted(train_generator.class_indices.keys()))with open('labels.txt', 'w') as f:    f.write(labels)

现在,我们已经创建了TFLite模型,图片类名也准备好了。下载数据集和模型、在MobileNet上执行迁移学习并以TFLite格式保存返回的模型的完整代码粘贴在下面。如果要在Colab中运行,你只需要更改数据集的下载链接即可:

import osfrom __future__ import absolute_import, division, print_function, unicode_literalstry:  # The %tensorflow_version magic only works in colab.  %tensorflow_version 2.xexcept Exception:  passimport tensorflow as tfimport numpyzip_file = tf.keras.utils.get_file(origin="https://storage.googleapis.com/kaggle-datasets/5857/414958/fruits-360_dataset.zip?GoogleAccessId=web-data@kaggle-161607.iam.gserviceaccount.com&Expires=1568066045&Signature=apl0VAR2eb1vz8XOJAbxsf8KuSUmMqOCtoJ0HwDBh%2F2YkqtAnOtypYq5rpQF020%2ByqKGGTqbyVMZ1RC84CclDHxMratQlkHQP7Dh8W%2FBW5K4nxuNsInBG27kqIdx%2Ff%2Fere1WZOiqvUtXgf1uXNwbOjijqyIT77ypJFPhWt%2Bcg4cjjkbrFjumo1RAGbJ77u1A3nQu4VhxhH46tZ6xtEU0lrzSpMA3U8GkvHK0H65qTD3GzfZD%2FmjhDtD712mT3H5zPgvRFbbSenaGgE%2BdaqG5Z9EBK95FT19N2tSSOMQFGxhmG9VpiODHEn%2FIHDlyyH2E%2F7%2BpMDFMuB4n93NyFu%2FnMQ%3D%3D",                                   fname="fruits-360.zip", extract=True)base_dir, _ = os.path.splitext(zip_file)train_dir = os.path.join(base_dir, 'Training')validation_dir = os.path.join(base_dir, 'Test')image_size = 128batch_size = 32train_datagen = tf.keras.preprocessing.image.ImageDataGenerator()train_generator = train_datagen.flow_from_directory(directory=train_dir, target_size=(image_size, image_size), batch_size=batch_size)validation_datagen = tf.keras.preprocessing.image.ImageDataGenerator()validation_generator = validation_datagen.flow_from_directory(directory=validation_dir, target_size=(image_size, image_size), batch_size=batch_size)IMG_SHAPE = (image_size, image_size, 3)base_model = tf.keras.applications.MobileNet(input_shape=IMG_SHAPE, include_top=False)base_model.trainable = Falsemodel = tf.keras.Sequential([  base_model,  tf.keras.layers.GlobalAveragePooling2D(),  tf.keras.layers.Dense(102, activation='softmax')])model.summary()model.compile(optimizer=tf.keras.optimizers.Adam(),              loss='categorical_crossentropy',              metrics=['accuracy'])epochs = 25steps_per_epoch = numpy.ceil(train_generator.n / batch_size)validation_steps = numpy.ceil(validation_generator.n / batch_size)history = model.fit_generator(generator=train_generator,                              steps_per_epoch = steps_per_epoch,                              epochs=epochs,                              validation_data=validation_generator,                              validation_steps=validation_steps)saved_model_dir = '/content/TFLite'tf.saved_model.save(model, saved_model_dir)converter = tf.lite.TFLiteConverter.from_saved_model(saved_model_dir)tflite_model = converter.convert()with open('model.tflite', 'wb') as f:  f.write(tflite_model)labels = ''.join(sorted(train_generator.class_indices.keys()))with open('labels.txt', 'w') as f:  f.write(labels)

在上面的代码运行之后,TFlite模型和文本文件将被列在Jupyter笔记本存储器中,如下图所示。你必须保留文件名(model.tflite和labels.txt). 用这样的名称命名这些文件的原因将在下一节中阐明。

968480db0072dd4db0c236288a2744e5.png

现在,我们有了TensorFlow Lite进行预测所需的数据。下一步是在Android Studio项目中使用这些文件。在项目内部,您需要访问相机,捕捉图像,将图像输入模型进行预测,最后在屏幕上显示结果。

我们可以利用一个实现上述功能的现有项目,而不是从头开始构建Android应用程序。我们只需要在正确的位置插入TFLite模型和类标签。让我们在下一节下载并测试Android Studio项目。

下载Android Studio项目

使用MobileNet进行图像识别的Android Studio项目可以从Github上TensorFlow示例仓库上的一组示例中下载。

你可以克隆这个项目,它包含的不仅仅是我们将要使用的Android Studio项目。它有几个项目,只要把它们导入Android Studio就可以使用了。为此,只需执行以下命令:

git clone https://github.com/tensorflow/examples.git

成功克隆项目后,您可以在目录/examples/lite/examples中找到几个可以使用的Android Studio项目。这些项目不仅适用于Android,也适用于iOS和Raspberry Pi。

我们需要的项目可以在这个目录中找到:

/examples/lite/examples/image_classification/android

您也可以从以下位置下载此项目目录:

https://github.com/tensorflow/examples/tree/master/lite/examples/image_classification/android

下载完成后,打开Android Studio并导入项目。导入项目需要一段时间才能完成Gradle同步。成功导入项目后,可以运行来看看它是怎么工作的。

运行应用程序后,你只需将摄像头放在一个对象的前面,应用程序将返回一些可能与该对象匹配的类标签,以及每个标签的分类概率分数。下一个图给出了一个例子。这只是为了按原样使用项目。但是使用我们之前生成的模型呢?我们将在下一节中实现。

b7c31fd6de36687305962695381e7255.png

定制工程

应用程序中两个文件model.tflite和labels.txt在下面目录中:

/examples/lite/examples/image_classification/android/app/src/main/assets

转到这个目录并将这两个新文件粘贴到那里。但这这么做还不够,在项目中需要进行一些必要的更改,以允许使用新的模型。

当TF模型转换为TFLite模型时,生成的TFLite模型根本没有得到优化。模型以浮点数模型保存。这意味着权重保存为浮点数。为了通知应用程序使用浮点数模型,需要进行3个更改。

1. 首先是编辑strings.xml资源文件。该文件位于以下目录中:

/examples/lite/examples/image_classification/android/app/src/main/res/values/strings.xml

只需将元素 替换为以下内容:

FloatQuantized

2. 第二个变化是ClassifierFloatMobileNet.java,文件在:

examples/lite/examples/image_classification/android/app/src/main/java/org/tensorflow/lite/examples/classification/tflite/ClassifierFloatMobileNet.java

将getModelPath()方法中的return语句更改如下:

return "model.tflite";

3. 第三个变化取决于输入图像的大小。如果您使用的是MobileNet模型的版本接受大小为(224×224)的图像,那么您无需做任何事情。

否则,您需要编辑ClassifierFloatMobileNet.java文件,getImageSizeX()方法返回图像的X大小,getImageSizeY()返回图像的Y大小。在我们的例子中,我们使用一个大小为(128×128)的图像,因此我们必须编辑这两个方法。

如果在做这些更改时出现错误,请检查与教程关联的GitHub项目:

https://github.com/ahmedfgad/AndroidTFLite

昨晚这些更改后,下一步是重新运行应用程序。打开app,。下图给出了一个例子:

660664014111256ab071d24e22a4f53b.png

总结

本教程讨论如何使用TensorFlow Lite模型格式构建在Android设备上运行的深度卷积神经网络。我们通过使用TensorFlow将预先训练的模型(MobileNet)的学习转移到新的数据集来实现这一点。

从这个迁移学习过程中返回的模型随后被转换成TensorFlow Lite模型,该模型被用于Android Studio项目,用于预测新图像的类标签。

原文链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值