AI-ANNE: 将神经网络迁移到微控制器的深度探索
本文介绍了AI-ANNE框架,它将深度学习模型迁移到资源受限的微控制器上。研究使用MicroPython在Raspberry Pi Pico上实现了神经网络核心组件,包括神经元、层和激活函数。通过IRIS数据集的实验验证,较小规模的网络(6-8个神经元)在二分类任务中能达到90%的准确率。该框架为嵌入式系统提供了本地化AI解决方案,具有数据隐私保护、低延迟和低能耗等优势,特别适合物联网和边缘计算应
AI-ANNE: 将神经网络迁移到微控制器的深度探索
Klinkhammer D. AI-ANNE:(A)(N) eural (N) et for (E) xploration: Transferring Deep Learning Models onto Microcontrollers and Embedded Systems[J]. arXiv preprint arXiv:2501.03256, 2025.
引言:嵌入式系统中的人工智能革命
机器学习和深度学习正在推动各个领域的创新发展,从计算机视觉到自然语言处理,从医疗诊断到工业自动化。近年来,这种创新浪潮正逐渐扩展到嵌入式系统领域,将智能计算能力直接带到数据源头。这种被称为TinyML的趋势,特别在微控制器和物联网(IoT)设备中展现出巨大潜力。
TinyML相比传统的基于云的人工智能解决方案,具有诸多独特优势。首先,数据隐私得到更好保护,因为敏感数据无需传输到云端即可在本地处理。其次,处理延迟大幅降低,从云端往返的网络延迟被消除,实现真正的实时响应。第三,能源效率显著提升,避免了数据传输的能耗开销。最后,系统对网络连接的依赖性降低,即使在网络不稳定或完全离线的环境中也能正常工作。
本研究提出的AI-ANNE(A Neural Net for Exploration)框架,旨在解决将预训练神经网络模型迁移到资源受限微控制器的挑战。通过在MicroPython中重新实现神经网络的核心组件,包括神经元、层、密度和激活函数,使得在TensorFlow和Keras等高性能框架上训练的模型能够在Raspberry Pi Pico等微控制器上运行,同时保持相同的推理能力。
硬件平台与开发环境
Raspberry Pi Pico系列微控制器
Raspberry Pi Pico采用RP2040微控制器,配备双核ARM Cortex-M0+处理器,运行频率133 MHz,具有264 KB片上SRAM和2 MB板载闪存。这款微控制器提供了丰富的连接选项:USB接口用于供电和数据传输,最多两个I2C、SPI和UART接口用于通信,16个PWM通道用于精确控制外部设备。板载还包括三个12位ADC通道用于模拟输入,支持实时时钟(RTC)、定时器和通过嵌套向量中断控制器(NVIC)进行中断处理等外设。
2024年推出的升级版Raspberry Pi Pico 2搭载RP2350微控制器,配备双核ARM Cortex-M33处理器,运行频率提升至150 MHz,片上SRAM增加到520 KB,板载闪存扩展到4 MB。性能的提升使Pico 2能够处理更大的数据集和更复杂的神经网络。对于实际应用,建议使用Raspberry Pi Pico 2;而对于教育目的,原版Raspberry Pi Pico已经足够。
MicroPython编程语言
MicroPython是Python编程语言的精简高效实现,专门设计用于在资源受限的微控制器和嵌入式系统上运行。与完整的Python环境不同,MicroPython经过优化,能够在小型设备典型的内存和处理限制内运行,提供精简的解释器和Python标准库的子集。
MicroPython保留了Python的大部分高级语法和易用性,使熟悉Python的开发者能够快速上手。在神经网络应用的背景下,MicroPython特别适合边缘计算场景,其中深度学习模型需要直接部署到基于微控制器的系统上进行实时、本地化推理。虽然MicroPython不原生支持完整Python中的大量数值库(如TensorFlow和Keras),但通过AI-ANNE框架,可以从零开始在MicroPython中重现神经网络的基本架构。
神经网络架构的数学基础
神经元:计算的基本单元
神经网络中的神经元是一个计算单元,其数学模型可以描述为接收多个输入信号,对每个输入应用特定权重,将加权输入求和,加上偏置项,最后通过激活函数产生输出。这个过程的数学表达式为:
y=f(∑i=1nwixi+b)y = f\left(\sum_{i=1}^{n} w_i x_i + b\right)y=f(i=1∑nwixi+b)
其中,yyy是神经元的输出,fff是激活函数,xix_ixi是第iii个输入,wiw_iwi是对应的权重,bbb是偏置项,nnn是输入的数量。
在MicroPython实现中,这个计算过程分解为几个步骤。首先初始化一个零向量来存储累加结果,然后遍历所有输入,计算每个输入与其权重的乘积并累加。最后,加上偏置项并应用激活函数。这种实现方式虽然在大规模网络中可能不如矩阵运算高效,但在微控制器的资源限制下是可行的。
层的组织结构
神经网络通过层的方式组织神经元,形成信息处理的层次结构。每一层包含多个神经元,这些神经元并行处理来自前一层的输入。网络的深度(层数)和每层的宽度(神经元数)共同决定了网络的表达能力。
输入层是网络的第一层,直接接收原始数据。在AI-ANNE的实现中,输入层的每个神经元对应输入数据的一个特征。例如,在处理传感器数据时,每个传感器读数对应输入层的一个神经元。
隐藏层位于输入层和输出层之间,负责提取和学习数据的抽象特征。隐藏层的数量和每层神经元的数量是网络架构设计的关键参数。深度网络(多个隐藏层)能够学习更复杂的特征层次,但也需要更多的计算资源。
输出层产生最终的预测结果。对于二分类问题,输出层通常只有一个神经元,输出一个介于0和1之间的概率值。对于多分类问题,输出层的神经元数量等于类别数,每个神经元输出对应类别的概率。
全连接层的密度概念
在全连接(密集)层中,当前层的每个神经元都与前一层的所有神经元相连接。这种连接模式的数学表示可以用矩阵乘法来高效实现:
y=f(Wx+b)\mathbf{y} = f(\mathbf{W} \mathbf{x} + \mathbf{b})y=f(Wx+b)
其中,x\mathbf{x}x是输入向量,W\mathbf{W}W是权重矩阵,b\mathbf{b}b是偏置向量,fff是逐元素应用的激活函数,y\mathbf{y}y是输出向量。
权重矩阵W\mathbf{W}W的维度为m×nm \times nm×n,其中nnn是输入层的神经元数量,mmm是当前层的神经元数量。这意味着一个密集层需要存储m×nm \times nm×n个权重参数加上mmm个偏置参数。
激活函数的深入分析
激活函数是神经网络中引入非线性的关键组件,使网络能够学习和表示复杂的非线性关系。不同的激活函数具有不同的数学特性和应用场景。
Sigmoid函数
Sigmoid函数将任意实数映射到(0,1)(0, 1)(0,1)区间:
σ(x)=11+e−x\sigma(x) = \frac{1}{1 + e^{-x}}σ(x)=1+e−x1
Sigmoid函数的导数具有优美的形式:
σ′(x)=σ(x)(1−σ(x))\sigma'(x) = \sigma(x)(1 - \sigma(x))σ′(x)=σ(x)(1−σ(x))
这个特性在反向传播算法中非常有用。然而,Sigmoid函数存在梯度消失问题:当输入值很大或很小时,梯度接近于零,导致深层网络训练困难。
ReLU函数族
标准ReLU(Rectified Linear Unit):
ReLU(x)=max(0,x)={xif x>00if x≤0\text{ReLU}(x) = \max(0, x) = \begin{cases} x & \text{if } x > 0 \\ 0 & \text{if } x \leq 0 \end{cases}ReLU(x)=max(0,x)={x0if x>0if x≤0
ReLU的导数:
ReLU′(x)={1if x>00if x≤0\text{ReLU}'(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{if } x \leq 0 \end{cases}ReLU′(x)={10if x>0if x≤0
Leaky ReLU解决了ReLU的"死亡神经元"问题:
LeakyReLU(x)={xif x>0αxif x≤0\text{LeakyReLU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha x & \text{if } x \leq 0 \end{cases}LeakyReLU(x)={xαxif x>0if x≤0
其中α\alphaα是一个小的正数(通常为0.01或0.1)。Leaky ReLU的导数:
LeakyReLU′(x)={1if x>0αif x≤0\text{LeakyReLU}'(x) = \begin{cases} 1 & \text{if } x > 0 \\ \alpha & \text{if } x \leq 0 \end{cases}LeakyReLU′(x)={1αif x>0if x≤0
Tanh函数
双曲正切函数输出范围为(−1,1)(-1, 1)(−1,1):
tanh(x)=ex−e−xex+e−x=e2x−1e2x+1\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} = \frac{e^{2x} - 1}{e^{2x} + 1}tanh(x)=ex+e−xex−e−x=e2x+1e2x−1
Tanh函数的导数:
tanh′(x)=1−tanh2(x)\tanh'(x) = 1 - \tanh^2(x)tanh′(x)=1−tanh2(x)
Softmax函数
Softmax函数用于多分类问题的输出层,将实数向量转换为概率分布:
Softmax(xi)=exi∑j=1Kexj\text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j=1}^{K} e^{x_j}}Softmax(xi)=∑j=1Kexjexi
为了数值稳定性,实际实现中通常使用:
Softmax(xi)=exi−max(x)∑j=1Kexj−max(x)\text{Softmax}(x_i) = \frac{e^{x_i - \max(\mathbf{x})}}{\sum_{j=1}^{K} e^{x_j - \max(\mathbf{x})}}Softmax(xi)=∑j=1Kexj−max(x)exi−max(x)
IRIS数据集上的实验验证
数据集描述与问题定义
IRIS数据集包含150个鸢尾花样本,每个样本具有四个连续型特征:萼片长度(sepal length)、萼片宽度(sepal width)、花瓣长度(petal length)和花瓣宽度(petal width),所有测量单位为厘米。数据集包含三个类别,每类50个样本:Iris-setosa、Iris-versicolor和Iris-virginica。
在本研究中,我们专注于区分Versicolor和Virginica两个类别的二分类问题。这两个类别在特征空间中有部分重叠,使得分类任务具有一定挑战性,适合用于验证神经网络的性能。
实验一:8神经元网络架构
第一个实验网络包含8个神经元,分布在4层中:
- 输入层:2个神经元
- 第一隐藏层:3个神经元
- 第二隐藏层:2个神经元
- 输出层:1个神经元
网络的前向传播过程可以表示为:
h1=ReLU(W1x+b1)\mathbf{h}_1 = \text{ReLU}(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)h1=ReLU(W1x+b1)
h2=tanh(W2h1+b2)\mathbf{h}_2 = \tanh(\mathbf{W}_2 \mathbf{h}_1 + \mathbf{b}_2)h2=tanh(W2h1+b2)
h3=Softmax(W3h2+b3)\mathbf{h}_3 = \text{Softmax}(\mathbf{W}_3 \mathbf{h}_2 + \mathbf{b}_3)h3=Softmax(W3h2+b3)
y=σ(W4h3+b4)y = \sigma(\mathbf{W}_4 \mathbf{h}_3 + b_4)y=σ(W4h3+b4)
其中,W1∈R2×4\mathbf{W}_1 \in \mathbb{R}^{2 \times 4}W1∈R2×4,W2∈R3×2\mathbf{W}_2 \in \mathbb{R}^{3 \times 2}W2∈R3×2,W3∈R2×3\mathbf{W}_3 \in \mathbb{R}^{2 \times 3}W3∈R2×3,W4∈R1×2\mathbf{W}_4 \in \mathbb{R}^{1 \times 2}W4∈R1×2。
这个网络达到了90%的准确率,混淆矩阵显示模型在某些边界案例上存在分类困难。
实验二:6神经元网络架构
第二个实验采用更简单的网络结构,包含6个神经元,分布在3层中:
- 输入层:3个神经元
- 隐藏层:2个神经元
- 输出层:1个神经元
前向传播过程:
h1=ReLU(W1x+b1)\mathbf{h}_1 = \text{ReLU}(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)h1=ReLU(W1x+b1)
h2=σ(W2h1+b2)\mathbf{h}_2 = \sigma(\mathbf{W}_2 \mathbf{h}_1 + \mathbf{b}_2)h2=σ(W2h1+b2)
y=σ(W3h2+b3)y = \sigma(\mathbf{W}_3 \mathbf{h}_2 + b_3)y=σ(W3h2+b3)
令人意外的是,这个更简单的网络达到了95%的准确率。混淆矩阵显示:
- 真阳性(TP):9个样本
- 真阴性(TN):10个样本
- 假阳性(FP):0个样本
- 假阴性(FN):1个样本
这表明对于这个特定问题,简单的网络架构可能更适合,避免了过拟合。
性能评估指标
混淆矩阵分析
混淆矩阵提供了分类性能的详细视图。对于二分类问题,混淆矩阵是一个2×22 \times 22×2的表格:
[TPFNFPTN]\begin{bmatrix} \text{TP} & \text{FN} \\ \text{FP} & \text{TN} \end{bmatrix}[TPFPFNTN]
基于混淆矩阵,可以计算多个性能指标:
准确率(Accuracy):
Accuracy=TP+TNTP+TN+FP+FN\text{Accuracy} = \frac{\text{TP} + \text{TN}}{\text{TP} + \text{TN} + \text{FP} + \text{FN}}Accuracy=TP+TN+FP+FNTP+TN
精确率(Precision):
Precision=TPTP+FP\text{Precision} = \frac{\text{TP}}{\text{TP} + \text{FP}}Precision=TP+FPTP
召回率(Recall):
Recall=TPTP+FN\text{Recall} = \frac{\text{TP}}{\text{TP} + \text{FN}}Recall=TP+FNTP
F1分数:
F1=2⋅Precision⋅RecallPrecision+Recall\text{F1} = 2 \cdot \frac{\text{Precision} \cdot \text{Recall}}{\text{Precision} + \text{Recall}}F1=2⋅Precision+RecallPrecision⋅Recall
MicroPython实现细节
矩阵运算的底层实现
由于MicroPython没有NumPy等科学计算库,需要从零实现基本的矩阵运算。矩阵转置函数的实现展示了这种方法:
def transpose(M):
if not isinstance(M[0], list):
M = [M]
rows = len(M)
cols = len(M[0])
MT = zeros(cols, rows)
for i in range(rows):
for j in range(cols):
MT[j][i] = M[i][j]
return MT
这种逐元素的操作虽然不如优化的BLAS库高效,但在微控制器的小规模网络中是可行的。
神经元的完整实现
单个神经元的计算涉及多个步骤:加权求和、添加偏置和应用激活函数。MicroPython实现必须处理不同的激活函数类型:
def neuron(x, w, b, activation):
tmp = zero_dim(x[0])
for i in range(len(x)):
tmp = add_dim(tmp, [(float(w[i]) * float(x[i][j]))
for j in range(len(x[0]))])
if activation == "sigmoid":
yp = sigmoid([tmp[i] + b for i in range(len(tmp))])
elif activation == "relu":
yp = relu([tmp[i] + b for i in range(len(tmp))])
# ... 其他激活函数
return yp
与现有方法的比较
AIfES框架
Fraunhofer开发的AIfES(Artificial Intelligence for Embedded Systems)是一个灵活的软件框架,专门设计用于在微控制器等小型低功耗设备上运行深度学习模型。AIfES可以直接在设备上构建、训练和运行模型,无需强大的外部系统。用户可以通过选择不同的模型组件(如层类型或数据处理方式)来定制框架。
AI-ANNE的独特优势
相比AIfES,AI-ANNE具有以下特点:
- 教育透明性:完全开放的MicroPython源代码,便于理解神经网络的内部工作原理
- 灵活性:可以轻松修改激活函数、调整网络架构,甚至在微控制器上进行微调
- 轻量级:最小化的依赖和内存占用,适合资源极度受限的环境
- 可扩展性:用户可以根据需要添加新的激活函数或网络组件
实际应用场景
状态监测与预测性维护
在工业环境中,AI-ANNE可以部署在传感器节点上,实时监测设备状态。通过分析振动、温度、压力等传感器数据,神经网络可以检测异常模式,预测潜在故障,实现预测性维护。
医疗诊断辅助
在医疗设备中,特别是便携式诊断设备,AI-ANNE可以实现实时的信号处理和模式识别。例如,在心电图(ECG)监测中,神经网络可以识别异常心律模式。
智能农业
在精准农业应用中,部署在田间的微控制器可以分析土壤湿度、温度、光照等数据,通过神经网络模型预测作物生长状态和灌溉需求。
未来发展方向
AI-ANNE框架的未来发展可以从多个方向展开:
- 模型压缩技术:研究量化、剪枝等技术,进一步减少模型大小和计算需求
- 在线学习能力:开发增量学习算法,使模型能够在部署后继续适应新数据
- 硬件加速:利用微控制器的特殊硬件功能,如DSP指令,加速神经网络计算
- 自动化工具:开发自动将TensorFlow/Keras模型转换为AI-ANNE格式的工具
结论
本研究成功展示了如何将神经网络迁移到资源受限的微控制器上。通过AI-ANNE框架,我们证明了即使在Raspberry Pi Pico这样的低成本微控制器上,也能运行有效的神经网络模型。实验结果表明,经过精心设计的小型网络可以达到与大型网络相当的性能,同时显著降低资源消耗。
附录:数学推导
附录A:反向传播算法
虽然AI-ANNE主要用于推理而非训练,理解反向传播算法对于理解预训练权重的来源至关重要。
损失函数
对于二分类问题,使用二元交叉熵损失函数:
L=−1N∑i=1N[yilog(y^i)+(1−yi)log(1−y^i)]L = -\frac{1}{N}\sum_{i=1}^{N}[y_i \log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i)]L=−N1i=1∑N[yilog(y^i)+(1−yi)log(1−y^i)]
其中NNN是样本数量,yiy_iyi是真实标签,y^i\hat{y}_iy^i是预测概率。
梯度计算
对于输出层权重wjk(L)w_{jk}^{(L)}wjk(L)的梯度:
∂L∂wjk(L)=∂L∂aj(L)⋅∂aj(L)∂zj(L)⋅∂zj(L)∂wjk(L)\frac{\partial L}{\partial w_{jk}^{(L)}} = \frac{\partial L}{\partial a_j^{(L)}} \cdot \frac{\partial a_j^{(L)}}{\partial z_j^{(L)}} \cdot \frac{\partial z_j^{(L)}}{\partial w_{jk}^{(L)}}∂wjk(L)∂L=∂aj(L)∂L⋅∂zj(L)∂aj(L)⋅∂wjk(L)∂zj(L)
定义误差项δj(L)=∂L∂zj(L)\delta_j^{(L)} = \frac{\partial L}{\partial z_j^{(L)}}δj(L)=∂zj(L)∂L,则:
δj(L)=∂L∂aj(L)⋅f′(zj(L))\delta_j^{(L)} = \frac{\partial L}{\partial a_j^{(L)}} \cdot f'(z_j^{(L)})δj(L)=∂aj(L)∂L⋅f′(zj(L))
对于隐藏层的误差项,使用链式法则:
δj(l)=(∑kwkj(l+1)δk(l+1))⋅f′(zj(l))\delta_j^{(l)} = \left(\sum_{k} w_{kj}^{(l+1)} \delta_k^{(l+1)}\right) \cdot f'(z_j^{(l)})δj(l)=(k∑wkj(l+1)δk(l+1))⋅f′(zj(l))
权重更新规则
使用梯度下降法更新权重:
wjk(l)←wjk(l)−η∂L∂wjk(l)w_{jk}^{(l)} \leftarrow w_{jk}^{(l)} - \eta \frac{\partial L}{\partial w_{jk}^{(l)}}wjk(l)←wjk(l)−η∂wjk(l)∂L
其中η\etaη是学习率。
附录B:激活函数的数值稳定性分析
Sigmoid函数的数值问题
当∣x∣|x|∣x∣很大时,e−xe^{-x}e−x可能导致数值溢出或下溢。改进的实现:
σ(x)={11+e−xif x≥0ex1+exif x<0\sigma(x) = \begin{cases} \frac{1}{1 + e^{-x}} & \text{if } x \geq 0 \\ \frac{e^x}{1 + e^x} & \text{if } x < 0 \end{cases}σ(x)={1+e−x11+exexif x≥0if x<0
Softmax的数值稳定实现
标准Softmax在输入值很大时会溢出。稳定版本:
Softmax(xi)=exi−C∑jexj−C\text{Softmax}(x_i) = \frac{e^{x_i - C}}{\sum_{j} e^{x_j - C}}Softmax(xi)=∑jexj−Cexi−C
其中C=max(x)C = \max(\mathbf{x})C=max(x)。证明这与原始定义等价:
exi−C∑jexj−C=exi⋅e−C∑jexj⋅e−C=exi∑jexj\frac{e^{x_i - C}}{\sum_{j} e^{x_j - C}} = \frac{e^{x_i} \cdot e^{-C}}{\sum_{j} e^{x_j} \cdot e^{-C}} = \frac{e^{x_i}}{\sum_{j} e^{x_j}}∑jexj−Cexi−C=∑jexj⋅e−Cexi⋅e−C=∑jexjexi
附录C:矩阵运算的计算复杂度分析
前向传播的复杂度
对于一个全连接层,输入维度为nnn,输出维度为mmm:
- 矩阵乘法:O(mn)O(mn)O(mn)次乘法和O(mn)O(mn)O(mn)次加法
- 偏置加法:O(m)O(m)O(m)次加法
- 激活函数:O(m)O(m)O(m)次函数调用
总复杂度:O(mn)O(mn)O(mn)
内存需求分析
对于LLL层网络,第lll层有nln_lnl个神经元:
- 权重存储:∑l=1L−1nl×nl+1\sum_{l=1}^{L-1} n_l \times n_{l+1}∑l=1L−1nl×nl+1个浮点数
- 偏置存储:∑l=1L−1nl+1\sum_{l=1}^{L-1} n_{l+1}∑l=1L−1nl+1个浮点数
- 激活值缓存:maxlnl\max_l n_lmaxlnl个浮点数(可以重用)
对于8神经元网络:
- 权重:4×2+2×3+3×2+2×1=224 \times 2 + 2 \times 3 + 3 \times 2 + 2 \times 1 = 224×2+2×3+3×2+2×1=22个参数
- 偏置:2+3+2+1=82 + 3 + 2 + 1 = 82+3+2+1=8个参数
- 总计:30个参数
附录D:梯度消失和梯度爆炸问题
Sigmoid函数的梯度消失
Sigmoid函数的导数最大值为0.25(当x=0x=0x=0时):
σ′(0)=σ(0)(1−σ(0))=0.5×0.5=0.25\sigma'(0) = \sigma(0)(1-\sigma(0)) = 0.5 \times 0.5 = 0.25σ′(0)=σ(0)(1−σ(0))=0.5×0.5=0.25
在深层网络中,梯度通过多层反向传播时会连续相乘:
∏l=1Lσ′(z(l))≤0.25L\prod_{l=1}^{L} \sigma'(z^{(l)}) \leq 0.25^Ll=1∏Lσ′(z(l))≤0.25L
当LLL很大时,梯度趋近于零。
ReLU的优势
ReLU的导数在正区间恒为1:
ReLU′(x)={1if x>00if x≤0\text{ReLU}'(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{if } x \leq 0 \end{cases}ReLU′(x)={10if x>0if x≤0
这避免了梯度消失问题,但可能导致"死亡ReLU"现象。
附录E:信息论视角下的激活函数
熵与信息增益
Sigmoid函数输出的熵:
H(p)=−plog(p)−(1−p)log(1−p)H(p) = -p\log(p) - (1-p)\log(1-p)H(p)=−plog(p)−(1−p)log(1−p)
其中p=σ(x)p = \sigma(x)p=σ(x)。熵最大值出现在p=0.5p=0.5p=0.5(即x=0x=0x=0)时。
Softmax与最大熵原理
Softmax函数是在约束条件∑ipi=1\sum_i p_i = 1∑ipi=1和pi≥0p_i \geq 0pi≥0下,最大化熵H=−∑ipilogpiH = -\sum_i p_i \log p_iH=−∑ipilogpi的解。
使用拉格朗日乘数法:
L=−∑ipilogpi+λ(∑ipi−1)\mathcal{L} = -\sum_i p_i \log p_i + \lambda(\sum_i p_i - 1)L=−i∑pilogpi+λ(i∑pi−1)
求导并令其为零:
∂L∂pi=−logpi−1+λ=0\frac{\partial \mathcal{L}}{\partial p_i} = -\log p_i - 1 + \lambda = 0∂pi∂L=−logpi−1+λ=0
解得pi=eλ−1p_i = e^{\lambda - 1}pi=eλ−1,归一化后即得Softmax形式。
附录F:微控制器上的定点数实现
虽然本文使用浮点数,但在某些微控制器上,定点数运算可能更高效。
定点数表示
使用Q格式,例如Q15.16表示16位整数部分和16位小数部分:
xfixed=xfloat×216x_{fixed} = x_{float} \times 2^{16}xfixed=xfloat×216
定点数乘法
两个Q15.16数相乘:
z=xfixed×yfixed216z = \frac{x_{fixed} \times y_{fixed}}{2^{16}}z=216xfixed×yfixed
定点数激活函数
Sigmoid函数的查找表实现:
- 预计算[−8,8][-8, 8][−8,8]区间内的Sigmoid值
- 量化到256个值
- 使用线性插值提高精度
这种方法可以将Sigmoid计算时间从几百个时钟周期减少到几十个。
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐
所有评论(0)