02

神经元与层——一个函数怎么变成一张网

阅读约 9 分钟第 2/60 课

上一章节的模型只有一个旋钮:价格 = w × 面积。它能学会一条直线的斜率,但也仅此而已。

现实中的关系远比一条直线复杂。房价不只取决于面积——还跟楼层、朝向、到地铁的距离、周边学校有关。更重要的是,这些因素之间有交互:顶层的大房子可能因为漏水而贬值,但低楼层的大房子不会。单独看每个因素不够,要看它们的组合。

一个旋钮学不了这种复杂关系。我们需要更多旋钮,更需要一种把旋钮组织起来的方式。这种方式叫做神经网络。

一个神经元做三件事

神经网络的基本单元叫做神经元。这个名字来自生物学——大脑的神经细胞接收信号、处理信号、输出信号。人工神经元做的事情类似,但简单得多。

一个人工神经元的计算可以分成三步。我们用一个具体的数字例子来走一遍。

假设神经元接收三个输入:房子面积 80 平方米、楼层 15、到地铁 500 米。每个输入有自己的权重——可以理解为这个神经元对每个因素的重视程度:

输入 1:面积 = 80     权重 1 = 0.5
输入 2:楼层 = 15     权重 2 = 0.3
输入 3:距离 = 500    权重 3 = −0.02
偏置 = 1.0

第一步:加权求和。 每个输入乘以对应的权重,然后全部加起来,再加上一个偏置(偏置是一个额外的旋钮,相当于调整基准线):

80 × 0.5 + 15 × 0.3 + 500 × (−0.02) + 1.0
= 40 + 4.5 + (−10) + 1.0
= 35.5

注意距离的权重是负的——距离越远,对房价的贡献越负面。这很合理。

第二步:激活函数。 把上一步的结果通过一个函数。最常用的激活函数叫 ReLU,它的规则极其简单:

  • 如果输入是正数,原样输出。
  • 如果输入是负数或零,输出零。

35.5 是正数,所以输出 35.5。如果上一步的结果是 −3,那输出就是 0。

第三步:输出。 就是第二步的结果。这个神经元对这套房子给出的评分是 35.5。

用 Python 写出来:

def neuron(inputs, weights, bias):
    # 第一步:加权求和
    total = 0
    for i in range(len(inputs)):       # 遍历每一个输入
        total = total + inputs[i] * weights[i]
    total = total + bias               # 加上偏置

    # 第二步:激活函数(ReLU)
    if total > 0:
        return total
    else:
        return 0

# 试一下
result = neuron(
    inputs=[80, 15, 500],              # 面积、楼层、到地铁的距离
    weights=[0.5, 0.3, -0.02],         # 三个权重
    bias=1.0                           # 偏置
)
print(result)  # 输出 35.5

一个神经元的全部计算就是这些。它不复杂——加权求和加一个 if-else。但当成千上万个这样的单元组合在一起时,整体的能力远远超过了每个单元本身。

激活函数为什么不可或缺

ReLU 看起来简单到多余——正数通过,负数变零,这有什么用?

它的作用在于引入「非线性」。如果没有激活函数,每个神经元都只是在做加权求和。两个加权求和叠在一起还是一个加权求和,三个也是,一百个也是。

打一个比方:加权求和是直尺。用一把直尺只能画直线。两把直尺叠起来还是一把直尺——你画不出曲线。但如果每把直尺之后都加一个「折叠」的动作(ReLU 就是一种折叠:把负数的部分折到零),直线就变成了折线。折线叠得足够多,就能逼近任何形状——曲线、拐角、阶梯。

激活函数就是这个折叠。没有它,无论堆多少层,网络能做的事情都等价于一层。有了它,每多一层都真正增加了网络的表达能力。

ReLU 不是唯一的激活函数。Sophia 用的前馈网络里用了 SiLU(一种更平滑的变体),注意力部分用了 softmax(后面的章节会讲)。但核心思路是一样的:在线性计算之间插入一个非线性操作,让网络能够表示复杂的关系。

一层:很多神经元并排

一个神经元只给出一个数字。如果我们想从同一组输入里得到多角度的信息,就需要很多神经元一起工作。

想象三个神经元,接收同样的输入(面积、楼层、距离),但各自有不同的权重:

神经元 1:特别看重面积(面积的权重大),不太在意距离
    → 给出评分 35.5

神经元 2:特别看重到地铁的距离(距离的权重绝对值大)
    → 给出评分 12.0

神经元 3:楼层的权重特别大,面积的权重较小
    → 给出评分 8.7

三个神经元的输出合在一起就是 [35.5, 12.0, 8.7]——这是这一层对这套房子的「理解」,从三个不同的角度。

这就是一层。同一组输入,不同的权重,得到不同的侧面。

在实际的神经网络中,一层通常有几百甚至几千个神经元。Sophia 的每一层有 1,536 个维度——你可以理解为 1,536 个神经元从 1,536 个角度同时观察输入。

一层的计算可以用矩阵乘法一次完成(矩阵是数字排成的方阵,第 11 章节会详细讲)。现在只需要知道:一层的核心操作 = 矩阵乘法 + 激活函数,无论这一层有多少个神经元。

深度:把层叠起来

一层能做的事有限——它只能从原始输入中提取一步的特征。但如果我们把两层叠起来呢?

第一层看到的是原始数据(面积、楼层、距离),从中提取出简单的特征(比如「面积大」「离地铁近」「高楼层」这样的信号)。

第二层看到的不是原始数据,而是第一层的输出。它在简单特征的基础上组合出更复杂的模式:「面积大且离地铁近」、「高楼层但面积小」。

如果还有第三层,它能在第二层的组合基础上发现更抽象的规律:「学区房的高楼层大户型」。

每多一层,网络能理解的概念就更高级、更抽象。两层网络能学到的东西,一层网络学不到;三层能学到的,两层学不到。这就是「深度学习」名字的由来——学习的能力来自深度。

Sophia 的 28 层

Sophia 有 28 层。为什么是 28,不是 10 或 100?

这不是拍脑袋决定的。Meta 的研究团队在一篇叫做 MobileLLM 的论文中发现:在十亿参数左右的规模上,深而窄的结构稳定优于浅而宽的结构。

什么意思呢?假设你有十亿个参数的预算。你可以把它们分成 14 层、每层很宽(每层的神经元多),也可以分成 28 层、每层窄一些。研究表明后者更好——更多的层带来更多的抽象层次,比单层更宽更有价值。

于是 Sophia 的形状被确定为 28 层 × 每层 1,536 维。

十亿个参数是怎么算出来的

你可能好奇:十亿是怎么来的?

一层如果有 1,536 个输入和 1,536 个输出,它的权重矩阵就有 1,536 × 1,536 = 2,359,296 个参数。加上偏置,大约 236 万个。

但 Sophia 的每一层不只有一组权重。每一层包含注意力机制和前馈网络(这两个概念分别在第四单元和第五单元讲解),各自有自己的权重矩阵。一层加起来有三四千万个参数。28 层叠加,再加上最底下的嵌入层(把文字映射成数字的那张表,第 12 章节会讲),总共是 1,012,630,480 个参数。

这就是 Sophia 的十亿个旋钮。训练就是把这十亿个旋钮从随机调到有意义。

下一章节进入 Sophia 真正在做的事情:处理语言。什么是语言模型,它是怎么一个词一个词地生成文本的。