基于CycleGAN的移动图像翻译系统

将介绍一个基于Cycle-Consistent Adversarial Networks(CycleGAN)的移动图像到图像翻译系统。将构建一个CycleGAN,它能够执行非成对的图像到图像的翻译,并展示一些既有趣又具有学术深度的例子。还将讨论如何将使用TensorFlow和Keras训练的网络转换为TensorFlow Lite,并在移动设备上作为应用程序使用。

假设熟悉深度学习的概念,以及Jupyter Notebooks和TensorFlow。欢迎下载项目代码。

在之前的文章中,保存并加载了TensorFlow Lite(.tflite)模型。在本文中,将在Android Studio中加载它,并选择正确的TensorFlow Lite Android支持库来运行推理。

准备Android Studio环境

构建Android应用程序的第一步是下载Android Studio。下载完成后,开始所谓的“机器学习(ML)和模块依赖绑定”,通过将.tflite模型导入Android Studio文件。

要将模型导入Android Studio,请右键单击希望使用TFLite模型的模块,或选择File > New > Other > TensorFlow Lite Model。然后,选择TFLite文件的位置。请注意,该工具将自动为配置模块的依赖关系,ML模型绑定和所有依赖项将自动插入到Android模块的build.gradle文件中。

完成后点击Finish。

选择TensorFlow Lite解释器和Android支持库

为了解释模型输出,必须将TensorFlow Lite Android支持库集成到应用程序中。这将提供高级API,帮助将原始输入数据转换和预处理,以适应模型期望的大小和格式。

此解释器库支持常见的输入和输出数据格式,包括图像和数组。此外,此库还包括一些预处理功能,如图像缩放和裁剪。

导入Gradle依赖项和其他设置

要导入Gradle依赖项,首先将.tflite模型文件复制到模型将运行的Android模块的assets目录中。指定文件不应被压缩,并在模块的build.gradle文件中添加TensorFlow Lite库:

dependencies { // Other dependencies // Import tflite dependencies implementation 'org.tensorflow:tensorflow-lite:0.0.0-nightly-SNAPSHOT' // The GPU delegate library is optional. If needed, select the second checkbox // for importing TensorFlow GPU if you want to use GPU acceleration. implementation 'org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly-SNAPSHOT' implementation 'org.tensorflow:tensorflow-lite-support:0.0.0-nightly-SNAPSHOT' }

在Android上部署模型

此时有一个存储在文件tflite_model.tflite中的神经网络。如果想使用它,需要创建一个新项目(例如命名为CycleGAN_App),并将模型文件放置在CycleGAN_App/app/src/main/assets文件夹中。由于Android Studio默认会为性能原因压缩资源文件,还需要明确告诉它不要压缩神经网络,方法是在gradle文件中添加以下行:

aaptOptions { noCompress "tflite" }

其次,需要添加所需的依赖项:更新gradle文件,添加以下行:

implementation 'org.tensorflow:tensorflow-lite:1.13.1'

为了演示移动图像到图像的翻译,创建了一个简单的Android应用程序,它有一个按钮来上传图像,通过TensorFlow Lite模型运行它,并显示翻译后的图像。

可以下载项目代码以查看其实际效果!尽管本文不讨论应用程序代码的完整讨论,但将探讨其最重要的部分。

导入基本图像操作和转换方法

在能够将图像输入模型之前,必须将其转换为模型可以处理的大小和格式。

为了使用TensorFlow Lite的图像操作和转换方法,必须创建一个ImagePreprocessor并添加所需的操作。要将图像转换为TensorFlow Lite解释器所需的张量格式,请创建一个TensorImage作为输入:

import org.tensorflow.lite.support.image.ImageProcessor; import org.tensorflow.lite.support.image.TensorImage; import org.tensorflow.lite.support.image.ops.ResizeOp; // Initialization code // Create an ImageProcessor with all ops required. For more ops, // refer to the ImageProcessor Architecture section in this README. ImageProcessor imageProcessor = new ImageProcessor.Builder() .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR)) .build(); // Create a TensorImage object. This creates the tensor of the corresponding // tensor type (uint8 in this case) that the TensorFlow Lite interpreter needs. TensorImage tImage = new TensorImage(DataType.UINT8); // Analysis code for every frame // Preprocess the image tImage.load(bitmap); tImage = imageProcessor.process(tImage);

创建输出对象并运行模型

要运行模型,需要创建将用于存储结果的容器对象(TensorBuffer):

import org.tensorflow.lite.support.tensorbuffer.TensorBuffer; // Create a container for the result and specify that this is // a quantized model. Hence, the 'DataType' is defined as UINT8 // (8-bit unsigned integer) TensorBuffer probabilityBuffer = TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8);

要加载模型并运行推理:

import org.tensorflow.lite.support.model.Model; // Initialise the model try { MappedByteBuffer tfliteModel = FileUtil.loadMappedFile(activity, "mobilenet_v1_1.0_224_quant.tflite"); Interpreter tflite = new Interpreter(tfliteModel); } catch (IOException e){ Log.e("tfliteSupport", "Error reading model", e); } // Run inference if (null != tflite) { tflite.run(tImage.getBuffer(), probabilityBuffer.getBuffer()); }

开发ImageProcessor架构

如上所述,ImageProcessor支持一些基本的图像操作方法;即裁剪、缩放和旋转:

int width = bitmap.getWidth(); int height = bitmap.getHeight(); int size = height > width ? width : height; ImageProcessor imageProcessor = new ImageProcessor.Builder() // Center crop the image to the largest square possible .add(new ResizeWithCropOrPadOp(size, size)) // Resize using Bilinear or Nearest neighbour .add(new ResizeOp(224, 224, ResizeOp.ResizeMethod.BILINEAR)); // Rotate counter-clockwise in 90 degree increments .add(new Rot90Op(rotateDegrees / 90)) .add(new NormalizeOp(127.5, 127.5)) .add(new QuantizeOp(128.0, 1/128.0)) .build();

实现量化

在初始化输入和输出对象,如TensorImage或TensorBuffer时,需要指定对象类型为DataType.UINT8或DataType.FLOAT32:

TensorImage tImage = new TensorImage(DataType.UINT8); TensorBuffer probabilityBuffer = TensorBuffer.createFixedSize(new int[]{1, 1001}, DataType.UINT8); TensorProcessor is used to quantize input tensors or dequantize output tensors: import org.tensorflow.lite.support.common.TensorProcessor; // Post-processor that dequantizes the result TensorProcessor probabilityProcessor = new TensorProcessor.Builder().add(new DequantizeOp(0, 1/255.0)).build(); TensorBuffer dequantizedBuffer = probabilityProcessor.process(probabilityBuffer);
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485