使用 Coral 进行现实世界 ML:制造业
2021 年 7 月 16 日

作者:Michael Brooks,Coral

在过去三年多的时间里,Coral 一直致力于通过低功耗、高性能的 产品 实现隐私保护的边缘 ML。我们发布了许多 示例项目,旨在帮助您快速加速针对特定需求的 ML。在探索 Coral 模型 和项目之后,我们收到的最常见问题之一是:如何迁移到生产环境?

为此,我们推出了第一个面向特定用例的演示。这些演示旨在充分利用 Coral Edge TPU™,并提供高性能、生产级代码,这些代码易于定制以满足您的 ML 需求。在本演示中,我们重点关注特定于制造的用例:工人安全和质量分级/视觉检查。

演示概述

Coral 制造业演示 针对的是具有 OpenGL 加速功能的 x86 或功能强大的 ARM64 系统,该系统可以处理和显示两个同时输入。使用包含的示例视频的默认演示如下所示

two gifs side by side demonstrating the Coral manufacturing demo

正在运行的两个示例是

  • 工人安全:执行通用人员检测(由 COCO 训练的 SSDLite MobileDet 提供支持),然后运行一个简单的算法来检测边界框碰撞,以查看人员是否处于不安全区域。
  • 视觉检查:执行苹果检测(使用与工人安全相同的 COCO 训练的 SSDLite MobileDet),然后将帧裁剪到检测到的苹果上,并运行经过重新训练的 MobileNetV2 来对新鲜苹果和腐烂苹果进行分类。

通过将这两个示例结合起来,我们能够展示多个可以实现这种处理的 Coral 功能,包括

  • 联合编译
  • 级联模型(使用一个模型的输出来馈送另一个模型)
  • 分类重新训练
  • 实时处理多个输入

创建演示

在设计新的 ML 应用程序时,务必确保您能够满足延迟和准确性要求。对于这里描述的两个应用程序,我们经历了以下过程来选择模型,训练这些模型,并将它们部署到 EdgeTPU - 此过程应在开始任何 Coral 应用程序时使用。

选择模型

在决定使用哪个模型时,新的 Coral 模型页面 是最佳起点。对于本演示,我们知道我们需要一个检测模型(用于检测人员和苹果),以及一个分类模型。

检测

检测模型页面 中选择检测模型时,我们需要寻找模型的四个方面

  1. 训练数据集:在模型页面中,我们所有的正常检测模型都使用 COCO 数据集。参考 标签,我们可以找到苹果和人,因此我们可以使用同一个模型来完成这两个检测任务。
  2. 延迟:我们需要每帧运行至少 3 次推断,并且需要它跟上我们的输入(30 FPS)。这意味着我们的检测需要尽可能快。从模型页面上,我们可以看到两个不错的选择:SSDLite MobileNet v2(7.4 毫秒)和 MobileDet(8.0 毫秒)。这是我们第一次看到 Coral 的明显优势 - 查看我们 x86+USB CTS 输出 底部的基准测试,我们可以看到,即使在功能强大的工作站上,这也分别为 90 毫秒和 123 毫秒。
  3. 准确性/精度:我们还需要尽可能准确的模型。这使用 COCO 评估指标 中的主要挑战指标进行评估。我们在这里看到,MobileDet(32.8%)明显优于 MobileNet V2(25.7%)。
  4. 大小:为了完全将此检测模型与下面的分类模型进行联合编译,我们需要确保我们能够将两个模型都容纳在 Edge TPU 上的 8MB 缓存中。这意味着我们希望模型尽可能小。MobileDet 为 5.1 MB,而 MobileNet V2 为 6.6 MB。

考虑到以上因素,我们选择了 SSDLite MobileDet。

分类

对于新鲜苹果或腐烂苹果的分类,Coral 分类页面 上有更多选择。我们想要检查的仍然是

  1. 训练数据集:我们将对新数据集进行重新训练,因此这在该应用程序中并不关键。
  2. 延迟:我们希望分类尽可能快。幸运的是,我们页面上的许多模型相对于我们要求的 30 FPS 帧速率来说都非常快。考虑到这一点,我们可以消除所有 Inception 模型和 ResNet-50。
  3. 准确性:提供 Top-1 和 Top-5 的准确性。我们希望 Top-1 尽可能准确(因为我们只检查新鲜苹果和腐烂苹果) - 但仍然需要考虑延迟。考虑到这一点,我们消除了 MobileNet v1。
  4. 大小:如上所述,我们希望确保我们可以容纳检测和分类模型(或尽可能多地容纳),因此我们可以轻松地消除 EfficientNet 选项。

这将我们留下了 MobileNet v2 和 MobileNet v3。我们选择了 v2,因为它有现有的关于重新训练此模型的教程。

重新训练分类

在完成模型决策后,现在我们需要重新训练分类模型来识别新鲜苹果和腐烂苹果。Coral.ai 提供了 CoLab(使用训练后量化)和 Docker(使用量化感知训练)格式的训练教程 - 但我们也包含了此演示存储库中的重新训练 Python 脚本。

我们的新鲜/腐烂苹果数据来自 “用于分类的新鲜和腐烂水果” 数据集 - 我们只是省略了除了苹果之外的所有内容。

在我们的 脚本 中,我们首先加载标准 Keras MobileNetV2 - 冻结前 100 层,并在末尾添加几层额外的层

base_model = tf.keras.applications.MobileNetV2(input_shape=input_shape,
                                                    include_top=False,
                                                    classifier_activation='softmax',
                                                    weights='imagenet')
# Freeze first 100 layers
base_model.trainable = True
for layer in base_model.layers[:100]:
  layer.trainable = False
model = tf.keras.Sequential([
    base_model,
    tf.keras.layers.Conv2D(filters=32, kernel_size=3, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.GlobalAveragePooling2D(),
    tf.keras.layers.Dense(units=2, activation='softmax')
])
model.compile(loss='categorical_crossentropy',
              optimizer=tf.keras.optimizers.RMSprop(lr=1e-5),
              metrics=['accuracy'])
print(model.summary())

接下来,将数据集下载到 ./dataset 后,我们训练模型

train_datagen = ImageDataGenerator(rescale=1./255,
                                   zoom_range=0.3,
                                   rotation_range=50,
                                   width_shift_range=0.2,
                                   height_shift_range=0.2,
                                   shear_range=0.2,
                                   horizontal_flip=True,
                                   fill_mode='nearest')
val_datagen = ImageDataGenerator(rescale=1./255)
dataset_path = './dataset'
train_set_path = os.path.join(dataset_path, 'train')
val_set_path = os.path.join(dataset_path, 'test')
batch_size = 64
train_generator = train_datagen.flow_from_directory(train_set_path,
                                                    target_size=input_size,
                                                    batch_size=batch_size,
                                                    class_mode='categorical')
val_generator = val_datagen.flow_from_directory(val_set_path,
                                                target_size=input_size,
                                                batch_size=batch_size,
                                                class_mode='categorical')
epochs = 15
history = model.fit(train_generator,
                    steps_per_epoch=train_generator.n // batch_size,
                    epochs=epochs,
                    validation_data=val_generator,
                    validation_steps=val_generator.n // batch_size,
                    verbose=1)

请注意,我们只使用了 15 个 epoch。在对另一个数据集进行重新训练时,很可能需要更多 epoch。使用苹果数据集,我们可以看到此模型很快就达到了非常高的准确度数字

image of training and validation accuracy and loss

对于您自己的数据集和模型,很可能需要更多 epoch(脚本将为验证生成上面的图)。

现在我们有了适用于苹果质量检查员的 Keras 模型。为了在 Coral Edge TPU 上运行此模型,该模型必须经过量化并转换为 TF Lite。我们将使用训练后量化来完成此操作 - 在训练后根据代表性数据集进行量化

def representative_data_gen():
  dataset_list = tf.data.Dataset.list_files('./dataset/test/*/*')
  for i in range(100):
    image = next(iter(dataset_list))
    image = tf.io.read_file(image)
    image = tf.io.decode_jpeg(image, channels=3)
    image = tf.image.resize(image, input_size)
    image = tf.cast(image / 255., tf.float32)
    image = tf.expand_dims(image, 0)
    yield [image]
model.input.set_shape((1,) + model.input.shape[1:])
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_data_gen
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.target_spec.supported_types = [tf.int8]
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
tflite_model = converter.convert()

然后,该脚本将编译模型并评估 Keras 模型和 TF Lite 模型 - 但我们需要超出脚本的步骤:我们必须使用 Edge TPU 编译器将分类模型与我们的检测模型进行联合编译。

联合编译模型

现在我们有两个经过量化的 TF Lite 模型:classifier.tflite 和从 Coral 模型页面获取的 MobileDet 的默认 CPU 模型。我们可以 将它们一起编译 以确保它们共享相同的缓存令牌 - 当请求任一模型时,参数数据将已经缓存。这只需要将两个模型都传递给编译器即可

edgetpu_compiler ssdlite_mobiledet_coco_qat_postprocess.tflite classifier.tflite 
Edge TPU Compiler version 15.0.340273435

Models compiled successfully in 1770 ms.

Input model: ssdlite_mobiledet_coco_qat_postprocess.tflite
Input size: 4.08MiB
Output model: ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite
Output size: 5.12MiB
On-chip memory used for caching model parameters: 4.89MiB
On-chip memory remaining for caching model parameters: 2.74MiB
Off-chip memory used for streaming uncached model parameters: 0.00B
Number of Edge TPU subgraphs: 1
Total number of operations: 125
Operation log: ssdlite_mobiledet_coco_qat_postprocess_edgetpu.log

Model successfully compiled but not all operations are supported by the Edge TPU. A percentage of the model will instead run on the CPU, which is slower. If possible, consider updating your model to use only operations supported by the Edge TPU. For details, visit g.co/coral/model-reqs.
Number of operations that will run on Edge TPU: 124
Number of operations that will run on CPU: 1
See the operation log file for individual operation details.

Input model: classifier.tflite
Input size: 3.07MiB
Output model: classifier_edgetpu.tflite
Output size: 3.13MiB
On-chip memory used for caching model parameters: 2.74MiB
On-chip memory remaining for caching model parameters: 0.00B
Off-chip memory used for streaming uncached model parameters: 584.06KiB
Number of Edge TPU subgraphs: 1
Total number of operations: 72
Operation log: classifier_edgetpu.log
See the operation log file for individual operation details.

此日志中有两点需要注意。首先,我们看到检测模型在 CPU 上运行了一个操作 - 这是预期的。TF Lite SSD 后处理将始终在 CPU 上运行。其次,我们无法将所有内容都容纳在片上内存中,分类器需要 584 kB 的片外内存。这没问题 - 我们已大幅减少了所需的 IO 时间。这两个模型现在将在同一个文件夹中,但因为我们联合编译了它们,所以它们互相识别,并且缓存将保留两个模型的参数。

针对您的应用程序进行定制

该演示经过优化,并已准备好进行定制和部署。它可以针对其他架构进行交叉编译(目前它只适用于 x86 或 ARM64),并且静态链接了 libedgetpu,以允许将此二进制文件部署到许多具有 Edge TPU 的不同 Linux 系统。

可以做很多事情来定制模型以适应您的应用程序

  • 最快的更改是输入,可以通过 --visual_inspection_input--worker_safety_input 标志进行调整。演示接受 mp4 文件和 V4L2 摄像头设备。
  • 工人安全演示可以通过更复杂的禁入区域算法(包括考虑与摄像头的角度/距离)以及对头顶数据的重新训练来进一步改进。目前,演示只检查边界框的底部,但 --safety_check_whole_box 标志可用于与整个框进行比较(适用于头顶摄像头等情况)。
  • 苹果检查展示了简单的质量分级/检查 - 这种级联模型方法(使用检测来确定边界框,并将这些框馈送到另一个模型)可以应用于许多不同的用途。通过重新训练检测和分类模型,可以针对您的应用程序进行定制。

结论

Coral 制造业演示展示了 Coral 如何在生产环境中用于解决多种 ML 需求。Coral 加速器提供了一种低成本、低功耗的方式,可以在不给主机带来过大负担的情况下添加足够的 ML 计算能力,从而并行运行这两个任务。我们希望您可以使用 Coral 制造业演示作为起点,将 Coral 智能引入您自己的制造环境中。

要了解有关边缘 ML 如何用于改善各个行业日常运营的更多信息,请访问我们的 行业页面。有关 Coral 产品集成 Coral 的合作伙伴产品 的更多信息,请访问 Coral.ai

下一篇文章
Real-World ML with Coral: Manufacturing

作者:Michael Brooks,Coral 3 年多来,Coral 一直致力于通过低功耗、高性能的 产品 来实现保护隐私的边缘机器学习。 我们已经发布了许多 示例项目,旨在帮助您快速加速针对特定需求的机器学习。 在探索 Coral 模型 和项目后,我们收到的最常见问题之一是:如何进行生产部署? 考虑到这一点……