如何基于iMX8M Plus开发机器学习应用

Posted toradexsh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何基于iMX8M Plus开发机器学习应用相关的知识,希望对你有一定的参考价值。

By Toradex 胡珊逢

NXP iMX8M Plus 作为其第一款支持神经网络运算硬件加速的处理器,提供对多种框架的支持,例如 ArmNN、TensorFlowLite、ONNX,eIQ Poral 工具可以使用户能够轻松地训练自己地模型,或者将现成的模型转换为适合在 iMX8M Plus 进行加速的模型。本文将介绍如何在 Toradex 的  Verdin iMX8M Plus 计算机模块上使用现成训练好的 TensorFlow Lite 模型开发深度学习应用,以及自行训练模型并借助 eIQ Poral 对模型进行转换使其适合在计算机模块上使用。

深度学习应用开发流程中,一个重要的环节就是训练模型。这不仅需要合理地调整参数,还需要大量的样本数据以及充足算力的计算机。因此使用训练好的模型通常是一个不错的选择,尤其是在项目初期缺少样本数据的阶段。TensorFlow Hub 提供了丰富的资源。这里我们将使用 ssd_mobilenet_v1 模型,以及一个使用 Python 开发的物体识别例程介绍如何使用这些现成的模型。

Toradex 部分的默认 BSP 中没有集成深度学习所需的软件,但可以通过 Yocto Project 非常容易将 NXP 深度学习软件集成到 Verdin iMX8M Plus BSP 中,具体方法可以参考该文章

然后下载包含 metadata 的模型文件,使用压缩工具直接解压下载的 tflite 文件(例如 lite-model_ssd_mobilenet_v1_1_metadata_2.tflite)即可获得标签文件 labelmap.txt,该文件中存放了能够识别物体的名字。在应用中我们将会使用该文件来显示所识别物体。模型下载页面介绍了输入和输出数据的结构。例如需要输入 RGB 色彩格式数据。输出数据部分包含被识别物体在图片中的位置,所属分类,对应分类的可信度等。

下面代码为初始化 ssd_mobilenet 模型,并获取关于该模型的基本信息,例如输入图片的大小,后面将摄像头采集到的图片调整对应尺寸。

-------------------------------------

# Load the Tensorflow Lite model.

interpreter = tflite.Interpreter(model_path=PATH_TO_CKPT)

interpreter.allocate_tensors()

# Get model details

input_details = interpreter.get_input_details()

output_details = interpreter.get_output_details()

height = input_details[0]['shape'][1]

width = input_details[0]['shape'][2]

-------------------------------------

将采集到的数据放入模块进行推演运算。

-------------------------------------

# Perform the actual detection by running the model with the image as input

interpreter.set_tensor(input_details[0]['index'],input_data)

interpreter.invoke()

-------------------------------------

最后获取被识别物体的位置,名称和相应的可信度。

-------------------------------------

boxes = interpreter.get_tensor(output_details[0]['index'])[0]

classes = interpreter.get_tensor(output_details[1]['index'])[0]

scores = interpreter.get_tensor(output_details[2]['index'])[0]

-------------------------------------

使用OpenCV 默认的配置读取摄像头时性能不是很理想,因此结合 Verdin iMX8M Plus 本身硬件特点,使用适当的 gstreamer pipeline 进行读取。

-------------------------------------

cv2.VideoCapture(" v4l2src device=/dev/video0 ! image/jpeg,width=1280,height=720,framerate=30/1 ! jpegdec ! videoconvert ! appsink", cv2.CAP_GSTREAMER)

-------------------------------------

最后通过下面命令启动应用程序。

-------------------------------------

root@verdin-imx8mp:~# export XDG_RUNTIME_DIR=/run/user/0

root@verdin-imx8mp:~# python3 tf-lite-detection-webcam.py --modeldir /home/root/PyOpenCV --graph lite-model_ssd_mobilenet_v1_1_metadata_2.tflite --labels labelmap.txt --resolution 1280x720

-------------------------------------

Verdin iMX8M Plus 可以通过 NPU 对应 TF Lite 进行硬件加速,能够实现以40 fps 左右的速度进行物体识别。

在更多的时候,我们可能需要自行采集原始数据并对其进行标记,然后训练模型。下面我们将使用 TensorFlow 分类识别 ECG 心电信号。这过程中会介绍如何在 PC 上使用 MIT-BIH心律失常数据库训练一个 TensorFlow 模型,然后使用 eIQ 将其转换为适合 iMX8M Plus 的 TensorFlow Lite 模型。

首先现从上面链接下载 Python 代码和心律数据。删除已经训练好的模块 ecg_model.h5,然后在  PC 上执行下面命令重新训练模型。根据 PC 性能,这过程会持续一段时间,最后重新生成 ecg_model.h5 文件。

-------------------------------------

$ python3 ecg.py

-------------------------------------

打开 eIQ 工具,使用默认配置将其转化为 TensorFlow Lite 模型 ecg_model.tflite。

在模型转换后输入和输出的数据格式也会发生相应额变化,例如输入固定为 1*300*1。

因此在代码中使用 reshape 函数对数据重新排列。

获得模型对每个心律信号可信度最高的预测。

结合数据库中实际诊断的结果生成一张对比矩阵图。

代码运行期间也记录以一些数据,如总共处理的 27657 个心电信号,首次运行时需要对 iMX8M Plus 的 NPU 进行 warmup,因此耗时为 177ms。其后则能够以 7.5ms 处理每个心电信号。

-------------------------------------

Total 27657signlas

First 10 inferences' time: 177.1 ms

First 10 inferences' time: 7.5 ms

First 10 inferences' time: 7.5 ms

First 10 inferences' time: 7.5 ms

-------------------------------------

总结

Verdin iMX8M Plus 得益于 NPU 能高效地处理神经网络计算。上面是一些简单的演示介绍,为了更好地发挥 NPU 性能,还需要对神经网络模块进行优化。通常现成的模型都是针对算力充足的 PC 所训练,甚至是 GPU 加速。而作为嵌入式系统处理器 iMX8M Plus,还需要兼顾功耗,NPU 算力也无法和桌面级 GPU 相提并论。对模型的优化就显得尤为重要,常见的方法如 quantization,牺牲少量的精度换取更快速的计算。

以上是关于如何基于iMX8M Plus开发机器学习应用的主要内容,如果未能解决你的问题,请参考以下文章

高性能的机器学习让边缘计算更给力-iMX8M Plus为边缘计算赋能

NXP(恩智浦)iMX8M Plus 处理器介绍

NXP(恩智浦)iMX8M Plus 处理器介绍

如何让IMX8M mini丰富的多媒体+AI设计?

机器学习之分类问题实战(基于UCI Bank Marketing Dataset)

NXP iMX8M Plus M7核心FreeRTOS开发