CMSIS_NN:卷积神经网络

本文介绍了物联网边缘设备如何利用ARMCortex-M系列处理器进行本地的机器学习,重点是CMSIS-NN库及其在卷积神经网络中的应用。CMSIS-NN包含卷积、激活和池化等函数,以实现低延迟和高效的数据处理。卷积神经网络的核心是降维,通过卷积、激活函数(如ReLU)和池化来提取特征。全连接层则用于分类识别。CMSIS-NN提供的函数支持这些操作,适合资源受限的嵌入式环境。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introduction


物联网已经深入到我们生活的方方面面,例如穿戴式医疗设备、智能家居。大部分的物联网设备会将采集到的数据上传至云端,由后台进行数据处理和分析,再将结果返回给微处理器。然而这种云端处理数据的方式不适用于一些对实时性要求高的物联网边缘设备,通过ARM Cortex-M系列处理器内核进行Machine Learning成为了技术发展的需要,CMSIS-NN就是解决方法之一。机器学习运用到嵌入式系统中有以下的优点[1]:

  • 实时性决策
  • 增加数据的安全性和可靠性
  • 无需依赖互联网
  • 减少带宽

CMSIS-NN库分为了两个部分,NNFuctions和NNSupportFunctions,图片摘自CMSIS-NN Block Diagram

在这里插入图片描述

NNFuctions运用了卷积神经网络Convolutional Neural Network(CNN),包括了:

  • Convolution Function 卷积函数
  • Activations Function 激活函数
  • Pooling Function 池化函数
  • Fully-connected Function 全连接函数

要掌握CMSIS-NN,首先得理解CNN,所以先说一说卷积神经网络。

Convolutional Neural Network


Convolution

首先贴上卷积的公式,一个是连续性的,一个是离散型的:
( f ∗ g ) ( n ) = ∫ − ∞ ∞ f ( τ ) g ( n − τ ) d τ (f * g)(n) = \int_{-{\infty}}^{\infty}f(\tau)g(n-\tau)d\tau (fg)(n)=f(τ)g(nτ)dτ

( f ∗ g ) ( n ) = ∑ τ = − ∞ ∞ f ( τ ) g ( n − τ ) (f * g)(n) = \sum_{\tau = -\infty}^{\infty}f(\tau)g(n - \tau) (fg)(n)=τ=f(τ)g(nτ)

卷积是怎么卷的?

卷积的核心在于降维。我们令 x = τ , y = n − τ x = \tau, y = n - \tau x=τ,y=nτ,那么 x + y = n x + y = n x+y=n,也就是二维平面上一条可移动的直线(图1)。当我们遍历这条直线,也就是做积分或者是求和,像是把二维平面从45°斜线卷起来,就形成了一个一维的直线函数,每个点的函数值等于卷起来后重合的点的函数值之和。这样就从一个二维函数降到了一维函数。此处参考于 荆哲:卷积为什么叫「卷」积?,非常形象地解释了“卷”的含义。

​ 图1 二维平面 x + y = n

​ 图2 一维函数

对于灰色图像的卷积,我们只需要将图像看成 m × n m × n m×n的矩形,而彩色RGB图像的卷积,我们可以将其分为Red、Green、Blue三个map,也就是深度为3,是个 m × n × 3 m × n × 3 m×n×3的长方体。我们首先讨论 m × n m × n m×n的2-D卷积:kernel卷积核 p × q p × q p×q在x,y方向上滑动。

kernel一般选取 3 × 3 3 × 3 3×3 5 × 5 5 × 5 5×5的大小, A i j A_{ij} Aij表示权重 w w w,原图像的 B i j B_{ij} Bij表示图像亮度值 v v v

g = [ A 11 A 12 A 13 A 21 A 22 A 23 A 31 A 32 A 33 ] g = \left[ \begin{matrix} A_{11}& A_{12} & A_{13} \\ A_{21} & A_{22} & A_{23} \\ A_{31} & A_{32} & A_{33} \end{matrix} \right] g=A11A21A31A12A22A32A13A23A33
卷积的过程可以表示为:
c o n v x , y = ∑ i p ∗ q w i v i conv_{x,y} = \sum_{i}^{p*q}w_iv_i convx,y=ipqwivi
如果所示,Image Matrix和Kernel Matrix进行矩阵相乘,即0 × (-1) + 0 × (-2) + 75 × (-1) + 0 × 0 + 75 ×0 + 80 × 0 + 0 × 1 + 75 × 2 + 80 × 1 = 155 ,将该值写入Output Matrix对应的位上,这样计算出了第一个值。以下图片均来自Convolutional Neural Networks - Basics

kernel

随后将kernel沿着 ( x , y ) (x,y) (x,y)方向平移扫描,即可得出整个Output matrix的值。

img

一个 m × n m × n m×n,在不考虑边界零填充(zero padding)的情况下,输出是一个 ( m − 2 ) × ( n − 2 ) (m-2) × (n-2) (m2)×(n2)的矩阵。当考虑zero padding,即在 m × n m × n m×n的图像四周添加2行2列的0,输出可以得到一个和原图像大小相同的 m × n m × n m×n的矩阵。例如下图。

考虑zero padding的原因:一是对图像边缘只扫描一次的话可能会忽略边缘的信息;二是保持图像大小,不然卷积次数多了之后图像会越来越小。

kernel的个数、大小、平移步长都可以根据实际情况进行调整。

若将RGB图像分为3层进行卷积,就需要一个立体的深度为3的kernel,在x,y,z三个方向上进行扫描,此处不再论述。

Activation

激活函数的作用是给函数加入偏置:
Z ( x , y ) = h ( ∑ i p ∗ q w i v i + b ) Z(x,y) = h(\sum_{i}^{p*q}w_iv_i+b) Z(x,y)=h(ipqwivi+b)
常用的激活函数有 S i g m o i d Sigmoid Sigmoid t a n h tanh tanh以及 R e L u ReLu ReLu S i g m o i d Sigmoid Sigmoid t a n h tanh tanh函数常用于全连接层, R e L u ReLu ReLu函数常用语卷积层。

在CMSIS-NN中用到的激活函数是 R e L u ReLu ReLu Function(Rectified Linear Units Function),作用是输出非负数,可表示为:
R e L u = m a x ( 0 , T ) ReLu = max(0,T) ReLu=max(0,T)

Pooling

池化函数的主要作用是通过特征降维对图像进行压缩,降低feature maps的分辨率,以此减少计算量,同时提高容错率。

池化一般选取 2 × 2 2 × 2 2×2的滑动窗口作为池化区域,通过相应的池化函数将4个像素转换为1个像素。常用的池化函数有 M a x Max Max $ Pooling 和 和 Average$ $ Pooling$。

下图中采用了 M a x Max Max P o o l i n g Pooling Pooling F u n c t i o n Function Function,在四个像素中选取了最大的数值 m a x ( 0.11 , 0.33 , − 0.11 , 0.33 ) = 0.33 max(0.11,0.33,-0.11,0.33) = 0.33 max(0.11,0.33,0.11,0.33)=0.33作为结果。例如下图。以下两张图摘自[大话卷积神经网络(CNN)][pooling and fully]。

polling

不过并不是所有情况下,进行池化后的效果会更好,因为池化的过程中可能丢失了信息。

Fully-connected

全连接层首先将多个map经过Convolution、Activation、Pooling后的结果合并到一起,即将每个 n × n n × n n×n的矩阵都拆开转成 ( n 2 ) × 1 (n^2) × 1 (n2)×1的列矩阵,再将 N N N个列矩阵合并成 ( n 2 × N ) × 1 (n^2 × N) × 1 (n2×N)×1的列矩阵。例如下图。

connected

其次,根据已训练好的监督学习模型得到全连接层每一个特征值的权重,将列矩阵与权重加权求和,通过Softmax函数对数值进行分类匹配,最贴近的就是识别结果。

Conclusion

CNN算法可以分为两个部分:

  • 特征提取:Convolution、Activation、Pooling
  • 分类识别:Fully-connected

在这里插入图片描述

CMSIS-NN采用的是框架如下图。

在这里插入图片描述

使用了以下函数:

  • arm_convolve_HWC_q7_RGB()
  • arm_convolve_HWC_q7_fast()
  • arm_relu_q7()
  • arm_maxpool_q7_HWC()
  • arm_avepool_q7_HWC()
  • arm_fully_connected_q7_opt()
  • arm_fully_connected_q7()

References


[1] ARM Developer, Image recognition on ARM Cortex-M with CMSIS-NN, https://developer.arm.com/solutions/machine-learning-on-arm/developer-material/how-to-guides/image-recognition-on-arm-cortex-m-with-cmsis-nn/single-page. 01 April 2019, Accessed 2020-08-19

### CMSIS-NN简介 CMSIS-NN 是 ARM 提供的一组优化函数库,旨在帮助开发者在基于 Cortex-M 的微控制器上高效运行神经网络推理任务[^1]。这些函数针对定点运算进行了高度优化,使得可以在资源受限的环境中实现高效的机器学习应用。 对于希望深入了解或使用 CMSIS-NN 的开发者来说,可以从以下几个方面入手: #### 官方文档与教程 ARM 官网提供了详细的 CMSIS-NN 用户指南和技术参考手册,其中包含了安装说明、配置选项以及如何集成到现有项目中的指导[^2]。此外,《CMSIS-RTOS教程》虽然主要关注于实时操作系统的相关内容,但对于理解如何在一个完整的嵌入式系统框架下部署和管理神经网络模型也有一定的借鉴意义[^3]。 #### 示例代码 为了便于理解和实践,ARM 还提供了一系列示例工程来演示不同类型的神经网络结构及其训练后的权重加载方法。通过研究这些例子可以快速掌握基本概念并应用于实际产品开发之中。GitHub 上有许多开源项目也利用了 CMSIS-NN 库实现了各种功能的应用程序,比如图像识别、语音命令分类等[^4]。 ```c // 加载预训练好的模型参数至指定地址空间 void load_model_parameters(const char* filename, uint8_t *dst){ FILE *fp; fp = fopen(filename,"rb"); fread(dst,sizeof(uint8_t),MODEL_SIZE,fp); fclose(fp); } ``` #### 社区支持与其他资源链接 除了官方资料外,在线社区如 Stack Overflow 和 Reddit 论坛也是获取技术支持的好地方;同时还可以访问 Nordic Semiconductor GitHub 仓库查找更多有关宏定义和其他实用技巧的信息[^5]。另外,“超棒的嵌入式学习资源汇总”一文中列举了许多有价值的参考资料,涵盖了从基础入门到高级主题的内容,非常适合那些想要全面提高自己在这方面能力的人士阅读[^6]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值