神经网络到底是什么:一个 13,002 参数的函数
以手写数字识别为例:给一张 28×28 的灰度图,让网络判断它写的是 0 到 9 里的哪个数字。
神经元就是一个装数字的容器
装的是一个 0.0 到 1.0 之间的数,这个数叫激活值(activation)。越接近 1 越「活跃」,接近 0 则「不活跃」。
更准确地说,神经元是一个函数:接收前一层所有神经元的输出,算完吐出一个 0~1 的数。
层结构:784 → 16 → 16 → 10
输入层 784 个:图片是 28×28 = 784 个像素,每个像素的灰度值(0.0 黑 ~ 1.0 白)直接作为对应神经元的激活值。
隐藏层 2 层、每层 16 个:介于输入和输出之间。叫「隐藏」是因为不直接看到它们的输入输出。2 层 × 16 个是人为定的,为了演示方便。
输出层 10 个:分别代表 0~9。哪个神经元激活值最高,网络就认为图片是那个数字。
为什么要有中间这两层
期望网络能逐层抽象:
- 第 1 层隐藏层识别小边缘(短线段、小弧线)
- 第 2 层把边缘组合成笔画组件(圆圈、竖线、弯钩)
- 输出层把组件组合成数字(圆圈 + 竖线 = 9)
「把复杂问题分解成小问题再组合」是层结构的核心动机。
需要说明的是:这只是期望。 网络实际学到的东西是什么样,训练完之后可以把权重可视化出来看 —— 结果和这个期望差得挺远。那是后面的话题。
权重与偏置
前一层的每个神经元都与下一层的每个神经元相连,每条连接带一个权重。
加权和 = w₁·a₁ + w₂·a₂ + … + wₙ·aₙ权重为正 → 对应输入神经元活跃时会「鼓励」下一层神经元活跃;为负则「抑制」。绝对值表示连接强度。
加权和算完再加一个偏置 b:
加权和 + b偏置控制的是门槛 —— 神经元多容易被激活。偏置为负意味着加权和必须足够大才能激活;为正则更容易激活。
激活函数
加权和加偏置的结果可能是任何数(3.7、−2.1),但需要压缩到 0~1 之间。
sigmoid 把任意数压扁到 0~1:很大的正数 → 接近 1;很小的负数 → 接近 0;0 → 0.5。
a = σ(加权和 + 偏置) = σ(w₁a₁ + w₂a₂ + … + wₙaₙ + b)σ(z) = 1 / (1 + e⁻ᶻ)现代网络更常用 ReLU(Rectified Linear Unit):输入为负输出 0,为正原样输出。更简单,训练效果也更好。
13,002 个参数
把这个网络的可调参数数一遍:
| 权重 | 偏置 | |
|---|---|---|
| 输入层 → 隐藏层 1 | 784 × 16 = 12,544 | 16 |
| 隐藏层 1 → 隐藏层 2 | 16 × 16 = 256 | 16 |
| 隐藏层 2 → 输出层 | 16 × 10 = 160 | 10 |
| 合计 | 12,960 | 42 |
共 13,002 个。所谓「学习」,就是找到这 13,002 个数的最佳取值。
整个网络就是一个函数
上面的计算用矩阵乘法可以写得很简洁:
a⁽¹⁾ = σ( W · a⁽⁰⁾ + b )W 是权重矩阵(k×n),a⁽⁰⁾ 是前一层激活值向量(n×1),b 是偏置向量(k×1)。
所以整个网络本质上是一个巨大的函数:吃进 784 个数字(像素值),经过多层矩阵乘法和压缩,吐出 10 个数字(每个数字的置信度)。虽然涉及 13,002 个参数,但它仍然只是一个函数。
与传统编程的区别
传统编程:人明确写出规则(if-else)。
神经网络:人只设计结构,然后用数据训练让网络自己「学」出规则。不是写一个识别数字的算法,而是写一个能学会识别数字的算法。
结构讲完了,但那 13,002 个参数现在还是随机的 —— 网络什么也不会。
怎么把它们调到正确的取值上,是下一篇的内容。