/ 消息 / 由 Cortex-M7 处理器支持的 OpenMV Cam 上的低功耗深度学习

由 Cortex-M7 处理器支持的 OpenMV Cam 上的低功耗深度学习

边缘计算通过在数据源执行信号处理来帮助减少延迟和功耗。最近,ARM 发布了CMSIS-NN库,这是一个针对基于 Cortex-M 的微控制器进行优化的高效神经网络库。 CMSIS-NN 库(发音为 Sim-Sis)为低功耗微控制器(例如基于 Cortex-M7 的 OpenMV 相机)带来了深度学习。在这篇博文中,我们将在 PC 上使用 Caffe 训练自定义神经网络,并将该网络部署在 OpenMV Cam 上。

CMSIS-NN:

CMSIS-NN 库由许多使用 SIMD 和 DSP 指令、可分离卷积等优化的神经网络函数组成……最重要的是,它支持 8 位定点表示。使用定点可以避免昂贵的浮点运算,减少内存占用,并在运行推理时使用更少的电量。然而,这意味着在将模型与 CMSIS-NN 一起使用之前必须先对其进行量化。

简而言之,量化是将一系列数字映射到更紧凑的数字范围,或者在本例中将 32 位浮点数映射到 8 位定点数。量化模型最困难的部分是找到层输入/输出的最小和最大范围,以便在 8 位表示中均匀分布浮点值。幸运的是,ARM 还提供了一个脚本来量化 Caffe 模型权重和激活。如果您对有关 CMSIS-NN 库和量化过程的更多详细信息感兴趣,请参阅 ARM 研究人员发表的这篇论文

默认 CMSIS-NN 库附带在 CIFAR-10 数据集上训练的 CNN 示例。但是,此示例是硬编码的,这意味着它必须与主应用程序进行编译和链接。因此,我们扩展了 CMSIS-NN 库和支持脚本。我们的代码允许用户将 Caffe 模型转换为量化的二进制格式,该格式可以在运行时从文件系统(SD 卡或内部闪存)加载。此外,我们的代码负责预处理输入图像、减去平均值,并根据需要缩放数据。

在本博文的下一部分中,我将演示如何将 CMSIS-NN 库与 OpenMV 相机结合使用,在微笑检测数据集上训练简单的 CNN 模型。该模型的准确度约为 93%,并且相机在运行网络时消耗约 150mA @ 3.3V 的电流。

使用 Caffe 训练网络:

首先,如果您刚刚开始使用神经网络和 Caffe,我强烈推荐本教程。请注意,您应该记住 CMSIS-NN 库和转换脚本对支持层的数量和类型有限制 - 因此您的模型应该很简单。

数据集:

我们使用的微笑数据集可以在这里找到。该数据集由约 3000 张正图像和约 9000 张负图像组成。我们需要正负图像的数量接近,否则网络将偏向于某个类别(类别不平衡)。为了解决这个问题,我们可以在正图像上使用此增强脚本来增强数据集,将正示例的数量增加 4 倍。图像增强脚本可以这样使用:

 python2 Augment_images.py --输入图像/train/ --输出图像/train_aug/ --count 4

训练网络:

您可以使用任何深度学习库来训练网络。但是,如果您不使用 Caffe,则需要将网络输出转换为 Caffe 格式才能使用 ARM 脚本。未来ARM将提供更多转换脚本来接受来自TensorFlow等的模型。

量化模型:

训练网络后的第一步是使用 ARM 提供的量化脚本将 Caffe 模型权重和激活从浮点格式转换为定点格式。如前所述,执行量化是为了减小网络的大小并避免浮点计算。

nn_quantizer 脚本的工作原理是测试网络并找出动态定点表示的最佳格式。该脚本的输出是一个序列化的 Python (.pkl) 文件,其中包括网络的模型、量化权重和激活以及每层的量化格式。运行此命令会生成量化模型:

 python2 nn_quantizer.py --model models/smile/smile_train_test.prototxt --weights models/smile/smile_iter_*.caffemodel --save models/smile/smile.pkl

将模型转换为二进制:

下一步是使用我们的NN 转换器脚本 将模型转换为可由 OpenMV Cam 运行的二进制格式。转换器脚本输出每个层类型的代码,后跟层的尺寸和权重(如果有)。

在 OpenMV Cam 上,我们的固件读取二进制文件并使用类似链表的结构在内存中构建网络。

运行此命令会生成二进制模型:

 python2 nn_convert.py --model models/smile/smile.pkl --mean /path/to/mean.binaryproto --output smile.network

在 OpenMV 相机上部署:

虽然可以在整个图像上滑动检测窗口,但这样做会非常慢。相反,我们使用内置的 Haar 级联人脸检测器从图像中提取人脸,然后将感兴趣区域 (ROI) 传递给 CNN 来检测微笑。微笑检测代码的第一部分将网络加载到内存中并加载内置的人脸检测Haar Cascade。

 # 加载微笑检测网络
net = nn.load('/smile.network')

# 加载人脸检测 Haar Cascade
face_cascade = image.HaarCascade("frontalface", stage=25)
打印(face_cascade)

下一步是捕捉快照并找到所有面孔。

 # 捕获快照
img = 传感器.snapshot()
# 寻找面孔。
对象= img.find_features(face_cascade,阈值= 0.75,scale_factor = 1.25)

最后,对于每个检测到的人脸,感兴趣的区域会被稍微裁剪并传递到神经网络。请注意,微笑检测网络是在紧密裁剪的脸部上进行训练的,因此我们必须减小 ROI 的大小。

 # 检测微笑
对于对象中的 r:
# 调整检测区域的大小并居中
r = [r[0]+10, r[1]+25, int(r[2]*0.70), int(r[2]*0.70)]
out = net.forward(img, roi=r, softmax=True)
img.draw_string(r[0], r[1], ':)' if (out[0] > 0.8) else ':(', color=0, scale=2)

微笑检测

前进:

OpenMV Cam 使用 Cortex-M7 处理器,无需连接任何外部 DRAM,仅使用内部 SRAM。在任何时间点,处理器都可以进入低功耗模式,消耗约 50 uA 的电流,同时保持所有状态,然后在中断时再次唤醒,拍照并运行神经网络,然后再次关闭。

例如,在即将推出的 OpenMV Cam H7 上,我们能够以 50 FPS 的速度运行在 MNIST 数据集上训练的 Lenet-6 CNN,同时每次推理仅使用 3mA @ 3.3V。使用 1Ah 3.7V 锂电池,您可以在现场部署 CNN,每分钟运行一次,可持续一年多

特别是,Cortex-M7 处理器上的 CNN 支持与部署基于智能热视觉的相机特别吻合,这些相机能够从低分辨率热视觉图像中准确检测人员。由 CMSIS-NN 和 Cortex-M7 处理器提供支持的智能传感器即将推出!

如需 MNIST 演示,请观看以下视频:

固件发布:

您可以我们的 GitHub 获取最新固件 (v3.0.0)。示例脚本在这里。模型就在这里。用于打包所有内容的 OpenMV IDE 版本即将发布。