第二章:神经网络基础回顾——感知机与多层感知机、激活函数、前向与反向传播
各位同学,欢迎来到第二章。说实话,每次讲这一章我都特别感慨。为什么?因为我在做AI芯片之前,一直觉得神经网络是搞算法的人的事,跟我们硬件工程师八竿子打不着。直到有一次,我接手了一个嵌入式视觉项目,客户要求在0.5W功耗下跑人脸检测——嗯,从那以后我再也不敢说「算法跟我无关」了。
这一章,我们就把神经网络最核心的几个概念掰开揉碎。你不需要有数学恐惧症,我会用做硬件设计的思路来讲。
2.1 感知机:最简单的「神经元」
感知机(Perceptron)是1957年提出的。说白了,它就是模仿人脑神经元的一个简化模型。
一个感知机接收多个输入,每个输入有一个权重,然后求和,再经过一个阶跃函数输出0或1。数学表达很简单:
y = 1 if (w1*x1 + w2*x2 + ... + wn*xn + b) > 0
y = 0 otherwise
我在项目中遇到过一件事:有次调试一个简单的二分类电路,死活不收敛。查了半天,发现是偏置b忘了加。你想想看,没有偏置,决策边界就必须过原点,很多问题根本解不了。所以,偏置不是可选项,是必需品。
2.2 多层感知机:打破线性限制
既然一个感知机不够,那就堆多个。多层感知机(MLP)就是在输入和输出之间加了「隐藏层」。每一层的输出作为下一层的输入。
我习惯把MLP看作一个「函数逼近器」。理论上,只要隐藏层神经元够多,它可以拟合任意复杂的函数。这个结论叫「万能逼近定理」,做硬件加速器的时候,我们就是靠这个定理吃饭的。
举个例子,一个两层的MLP(一个隐藏层)可以解决XOR问题:
隐藏层神经元1:实现 AND
隐藏层神经元2:实现 OR
输出层:组合它们得到 XOR
嗯,这里要注意:隐藏层的层数和神经元数量不是越多越好。我见过有人为了追求精度,堆了20层,结果在嵌入式芯片上推理延迟直接爆炸。做硬件的人,一定要有「成本意识」。
2.3 激活函数:给网络注入「非线性」
如果没有激活函数,多层感知机就退化成单层线性变换。那跟没有隐藏层一样。激活函数的作用,就是引入非线性。
常用的激活函数有几种,我列个表对比一下:
| 激活函数 | 公式 | 优点 | 缺点 |
|---|---|---|---|
| Sigmoid | σ(x) = 1/(1+e-x) | 输出范围(0,1),适合概率输出 | 梯度饱和,容易梯度消失 |
| ReLU | f(x) = max(0, x) | 计算简单,缓解梯度消失 | 神经元「死亡」问题 |
| Tanh | tanh(x) = (ex-e-x)/(ex+e-x) | 输出范围(-1,1),零中心 | 同样有梯度饱和 |
我个人强烈推荐ReLU。为什么?因为它在硬件上实现太友好了。你想想看,Sigmoid需要指数运算,在嵌入式芯片上要消耗大量逻辑门。而ReLU就是一个比较器加一个选择器,几乎不占资源。
不过ReLU有个坑——「神经元死亡」。如果输入一直为负,梯度就是0,这个神经元就再也学不动了。我曾经在一个项目中踩过这个坑,后来用Leaky ReLU解决了:
Leaky ReLU: f(x) = x if x > 0, else α*x (α很小,比如0.01)
2.4 前向传播:数据从输入到输出
前向传播很简单,就是数据从输入层流到输出层的过程。每一层做两件事:线性变换 + 激活。
数学上,第l层的输出a[l]可以写成:
z[l] = W[l] · a[l-1] + b[l]
a[l] = g(z[l]) // g是激活函数
做硬件加速的时候,前向传播就是我们的「推理」过程。我习惯把权重W看作「固定的参数」,把输入a看作「流动的数据」。在芯片上,这就是一个乘累加(MAC)阵列不断重复的过程。
你可能会问:为什么叫「前向」?因为信息只往前走,不回头。这在硬件上意味着——流水线设计非常自然。每一层可以做成一个独立的流水级,数据一拍一拍往下传。
2.5 反向传播:让网络学会「纠错」
反向传播(Backpropagation)是训练神经网络的核心算法。说白了,就是计算每个参数对最终误差的「贡献度」,然后沿着梯度下降的方向更新参数。
我刚开始学的时候,觉得反向传播特别玄乎。后来用链式法则一拆,其实就三件事:
- 计算输出层的误差:预测值 - 真实值
- 误差反向传递:用链式法则,把误差从输出层传到输入层
- 更新参数:每个参数减去它的梯度乘以学习率
公式长这样(以均方误差损失为例):
输出层误差: δ[L] = (a[L] - y) * g'(z[L])
隐藏层误差: δ[l] = (W[l+1])T · δ[l+1] * g'(z[l])
梯度更新: W[l] = W[l] - η * δ[l] · (a[l-1])T
嗯,这里要注意:反向传播在硬件上实现比前向传播难得多。为什么?因为前向传播只需要乘累加,而反向传播需要矩阵转置、激活函数求导、还要保存中间结果。这就是为什么训练通常在GPU上做,推理才放到嵌入式芯片上。
2.6 从算法到硬件的桥梁
讲到这里,我想强调一个观点:理解神经网络的计算模式,是设计加速器的第一步。
前向传播的本质是什么?是大量的矩阵乘法(或者卷积)。反向传播的本质是什么?是矩阵乘法 + 转置 + 逐元素操作。这些操作在硬件上都可以映射到乘累加阵列(Systolic Array)上。
我建议你记住这张对应关系表:
| 算法操作 | 硬件实现 | 关键参数 |
|---|---|---|
| 线性变换 (Wx+b) | MAC阵列 + 加法树 | 数据位宽、并行度 |
| 激活函数 (ReLU/Sigmoid) | 查找表或分段线性逼近 | 精度、延迟 |
| 反向传播梯度计算 | 共享MAC阵列(时分复用) | 存储带宽、控制逻辑 |
| 权重更新 | 加法器 + 乘法器 | 学习率量化 |
说白了,你只要把前向传播和反向传播的数学吃透了,后面设计加速器架构就是「如何用硬件高效实现这些计算」的问题。
好,这一章就到这里。下一章我们会深入卷积神经网络(CNN),看看它是怎么处理图像数据的。到时候你会发现,很多思路跟MLP是一脉相承的。