我建议为您的 MIPI 相机创建一个支架,以便轻松定位以识别物体。我的是用 OpenBeam 做的,但你可以用木头、冰棒棍和电工胶带,或者你周围的任何东西。
包含的模型是 i.MX SDK eIQ 示例中包含的 Mobilenet v.1 的默认版本。虽然快速且轻巧,但它不是很准确。您会看到它通常无法识别图像中的任何内容:
Inference time: 172 ms
Detected: No label detected (0%)
这里列出了一个有用的 Tensorflow Lite 图像分类模型列表,以及它们的准确性、速度(以四核 CPU 为基准)和大小。我们使用的默认模型与列表中的第一个模型最相似。它的 top-1 准确率为 39.5%,这意味着模型的最高预测只有大约 39.5% 的时间是正确的标签。
在这里,我们的任务是图像分类,所以我们只考虑图像分类模型。I.MX RT 板有几种不同的模型类型示例:
根据您的图像分类需求,您可能需要具有一定准确性或速度的模型。确定特定模型是否可以在特定设备上运行基于:
尽管 MaaXBoard RT 有一个浮点单元并且能够运行浮点模型,但最好对模型进行量化以考虑大小和速度。
大小:MaaXBoard 配备 256 Mb 超闪存。Tensorflow Lite 标签图像项目为 35.4Mb,其中 5.5 个是模型本身。
我可以从 Tensorflow Lite 模型列表中看到,量化 MobileNet v2 比 V1 准确得多,同时仍然相当小且速度快:
您可以按原样使用该模型,或者如果您希望在自定义数据集上对其进行训练,您可以使用迁移学习来重新训练您的模型。
迁移学习的完整说明在此处的恩智浦迁移学习实验室中,您可以在此处找到与迁移学习实验室相关的更多信息,了解如何收集或选择数据集。您需要一个带标签的图像数据集进行训练(最好使用 MaaXBoard RT 相机收集的数据进行训练),并且您还需要在您的 PC 上安装正确版本的 Python 和 Tensorflow。
在这一步中,我们将把我们的模型转换为 C 头文件,这些头文件可以添加到 MCUXpresso 中的项目中,然后加载到 MaaXBoard RT 上。这其实很简单。它只需要 Vim,如果你在 Mac 或 Linux 上应该已经可用。
如果在 Windows 上,请安装Vim 8.1 :在该软件包内有一个名为 xxd.exe 的二进制转换程序,需要名为 xxd。xxd 是一个 hexdump 实用程序,可用于在文件的十六进制转储和二进制形式之间来回转换。在这种情况下,该实用程序用于将 tflite 二进制文件转换为可添加到 eIQ 项目的 C/C++ 头文件。
如果使用 Windows 命令提示符:
xxd -i mobilenet_v2_1.0_224_quant.tflite > model_data.h
如果使用 Windows Powershell:
xxd -i mobilenet_v2_1.0_224_quant.tflite | out-file -encoding ASCII mobilenet_v2_1.0_224_quant.h
#include
#define MODEL_NAME "mobilenet_v1_0.25_128_quant_int8"
#define MODEL_INPUT_MEAN 127.5f
#define MODEL_INPUT_STD 127.5f
const char model_data[] __ALIGNED(16) = {
更改后应如下所示:
如果您使用的是现有模型,它应该带有一个labels.txt文件(在 mobilenet 的情况下,它被称为 mobilenet_labels.txt)。附加的 python 脚本,replace_label_text.py,应该将一个正常的行分隔的labels.txt文件转换为与 C++ 一起工作的文件。将您的文件命名为“ labels.h ”
转换后,它应该如下所示:
最后一步是采用TensorFlow Lite Label Image示例并对其进行修改以使用新重新训练的模型。
我们需要将上一节中生成的模型文件model_data.h和标签文件labels.h都导入到这个项目中。
双击项目视图中“source\model”文件夹下的model.cpp文件将其打开。
第 15 和 16 行应该引入模型和您的新模型 model_data.h:
在第 26 行左右,更改 API 调用以加载默认模型,并将其替换为新头文件中的新模型名称 (model_data) 和模型长度 (model_data_len)。它可能与下面列出的名称略有不同。它应该与 model_data.h 中的数组名称和长度相匹配( const char model_data[] __ALIGNED(16) = {):
为了减小项目的大小,Label Image示例仅支持默认 Mobilenet 模型所需的特定操作数。我们重新训练的模型使用了一些新的操作数。这些特定的操作数可以通过使用名为netron的应用程序分析模型来确定,然后手动添加操作数,如 eIQ TensorFlow Lite 库用户指南第 7.1 节所述。或者,可以使用 BuiltinOpResolver 方法在项目中支持所有 TFLite 操作数。对于本实验,我们将使用后一种方法,以提供与其他模型的最大兼容性。在model.cpp的第 33 或 34 行附近,注释掉原来的解析器行。然后添加一个新行
tflite::AllOpsResolver micro_op_resolver;
这就是您需要进行的所有修改!该应用程序现在可以运行了。
在 MCUXpresso 中,确保超闪存驱动程序MaaXBoard_S26KS256.cfx位于Project Explorer下的 xip 文件夹中。然后,单击“编辑项目设置”,导航到 MCU 设置,并确保在两个位置都选择了超闪存驱动程序作为闪存驱动程序。
我选择了Debug ,因为这一步即可构建和调试项目。几乎立即(哇,有 HyperFlash!)我能够在 LCD 上看到相机的输出。
我收集了label.h 中命名的东西的列表,例如橙子和一杯葡萄酒(下一次我将训练一个识别鸡尾酒类型的模型,因为这将使测试步骤更加愉快)。
当控制台以 115200 波特打开时,我可以看到它打印每个对象的标签,因为我将它举到相机上,并且模型识别了它:
Inference time: 2537 ms
Detected: orange (61%)
----------------------------------------
Inference time: 2536 ms
Detected: red wine (54%)
----------------------------------------
虽然它比示例项目中提供的 MobileNet 模型慢了一点,但它的准确度要高得多,而且速度仍然足够快,可以派上用场。在这个令人难以置信的微控制器上准备和运行模型的简单程度给我留下了深刻的印象。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !