← 全部极客知识库

大模型通识 / AI 理论基础

7. 神经网络与深度学习:多层计算怎样形成能力

原文备份 · 第 8 / 14 篇 · 查看极客时间原知识库 ↗

本篇目录 · 8 节

来源:AI 理论基础

你把复习笔记分别保存在两份清单里,想找出“只出现在其中一份”的笔记,以便检查两份清单是否同步。

对每篇笔记,只记录两个数字:x₁ 表示它是否在清单 A 中,x₂ 表示它是否在清单 B 中;在记作 1,不在记作 0。希望输出的结果如下:

x₁:在 A 中 x₂:在 B 中 是否需要检查
0 0 0
1 0 1
0 1 1
1 1 0

这个规则写成普通程序很简单:两个值不一样就标记。我们借它提出一个不同的问题:模型能否通过分层计算,表示“两个条件怎样组合才算成立”?

本篇会搭出一个可以手算的神经网络,解释权重、偏置、激活函数和隐藏层。例子中的参数由我们直接指定,用来展示机制,本篇没有进行训练实验;实际开发清单同步功能,也没有必要为这种明确规则训练网络。

读完以后,你应该能看懂一个小网络怎样产生输出,并分清“网络能表示什么”“训练能否找到合适参数”“真实项目是否可靠”这三个问题。

从一个计算单元开始:加权相加,再做变换

前面几篇已经出现过按特征计算分数的模型。一个常见的神经网络计算单元,也可以先从这一步理解:

中间分数 z = w₁ × x₁ + w₂ × x₂ + b
单元输出 h = 激活函数(z)

x₁、x₂ 是输入;w₁、w₂ 是权重,weight,决定输入怎样参与相加;b 是偏置,bias,是在加权结果上再加的一个数。权重和偏置通常属于训练要调整的参数。

例如,暂时取 w₁=2、w₂=-1、b=-0.5。输入 [1,0] 时,中间分数是 2×1-1×0-0.5=1.5。权重为负,并不是出现了“负概率”;我们此时算的是一个中间分数。偏置也不是“数据偏见”的意思,而是这个公式里的平移项。

如果输入全为 0,没有偏置时分数只能是 0;有偏置时,它可以是 b。这让模型不必把所有输入关系都限制在经过零点的形式中。

这里的“神经元”可以先理解为计算单元,不需要把它想象成一颗会思考的小脑细胞。把多个单元放在一起,一次得到一组输出,就是构建一层的基本方式。Google:神经网络的节点与隐藏层

为什么还需要激活函数

激活函数,activation function,是对中间分数进行的变换。先认识一种最容易手算的选择:ReLU。

ReLU(z) = max(0, z)

z 小于 0:输出 0
z 大于或等于 0:保留 z

因此 ReLU(-2)=0,ReLU(0)=0,ReLU(1.5)=1.5。它不是“负数变成 0、正数变成 1”,也不会把所有输出限制在 0 到 1 之间。Keras:ReLU 的定义

这一步引入了非线性。这里不必先学抽象定义,可以看输入增加 1 时会怎样:从 -2 变成 -1,输出仍为 0;从 1 变成 2,输出则增加 1。同样的输入增量,在不同区域产生不同效果。

这种变化让后续层能够有条件地利用前面算出的信号。ReLU 只是一个易懂的例子,神经网络还有其他激活函数;本篇不要求背名字,也不意味着所有大模型都使用同一种激活函数。

单纯多算几层,为什么还不够

假设没有这种非线性变换,第一层只算:

h = 2x + 1

第二层再算:

y = 3h - 4

把第一层的结果代进去,就得到:

y = 3(2x + 1) - 4 = 6x - 1

看上去经历了两层,结果却能合并成一次同类计算。在只由“乘权重、相加、加偏置”组成的串联网络里,这种合并同样适用于向量输入。因此,多堆这样的层,并不会自动获得非线性关系的表达能力。严格说,带偏置的这类变换叫作“仿射变换”;入门资料里也常把它归在“线性层”这一说法中。《动手学深度学习》:从线性到非线性

这解释了激活函数的位置为什么重要:它插在计算之间,让整个映射不再总能被压回一层加权相加。

不过,加入非线性也不是自动成功的保证。如果参数设置让所有单元始终只在 ReLU 的同一段上工作,网络在那些输入范围里仍可能表现得很简单。结构提供了可能性,参数和数据决定实际用上了什么。

用两个隐藏单元,完成开头的判断

现在返回两份复习清单。我们设置两个单元:

h₁ = ReLU(x₁ - x₂)
h₂ = ReLU(x₂ - x₁)

最终输出 y = h₁ + h₂

第一单元的两个权重为 [1,-1],第二单元为 [-1,1],偏置都取 0。输出层的权重为 [1,1],偏置取 0,直接相加。

先手算“只在 A 中”的情况,也就是输入 [1,0]:

h₁ = ReLU(1 - 0) = 1
h₂ = ReLU(0 - 1) = 0
y  = 1 + 0 = 1

再看两份清单里都有,即 [1,1]:两个差值都是 0,输出也是 0。

四种情况全部展开如下:

输入 [x₁,x₂] h₁ h₂ 输出 y 与目标是否一致
[0,0] 0 0 0 一致
[1,0] 1 0 1 一致
[0,1] 0 1 1 一致
[1,1] 0 0 0 一致

在这个二值输入范围内,h₁ 检出“只在 A 中”,h₂ 检出“只在 B 中”,输出层把两种需要检查的情况合并起来。这就是一个完整的计算过程:

输入层                  隐藏层                     输出层
[x₁, x₂] ────────→ [ReLU(x₁-x₂), ReLU(x₂-x₁)] ────────→ 相加
 清单记录                两个方向的差异                  是否检查

这里的“隐藏”,是说这些值处在输入与最终输出之间。它们不是我们直接提供的原始记录,也不是最终要求的目标;有模型内部访问权限时,完全可以把它们读出来。“隐藏”不等于系统不允许查看。

这套逻辑也叫异或,XOR。它揭示了组合关系的重要性:当 B 中没有记录时,把 A 从 0 改成 1,会让目标从 0 变成 1;当 B 中已有记录时,同样修改 A,却让目标从 1 变成 0。一个对 A 始终采用固定正向或负向影响的加权打分器,再配固定阈值,不能同时完成这四项判断。

可以再做一个反例:把网络里的两个 ReLU 去掉,输出就变成 (x₁-x₂)+(x₂-x₁)=0,无论输入是哪一种都得 0。非线性在这里确实做了工作。

注意,我们只证明了这组指定参数能完成四种输入的规则。输出恰好是 0 或 1,并不意味着这是经过校准的概率模型;输入如果改成任意实数,这个公式也不保证输出落在 0 到 1 之间。

层、宽度与参数量,分别在数什么

上面这个网络包含两个输入值、一个有两个单元的隐藏层,以及一个输出单元。从输入依次算到输出,叫作一次前向传播,forward propagation。

为了避免数层数时混乱,本篇把“带参数的隐藏层和输出层”计入层数,输入层不算计算层。因此它是一个有两个参数层、一个隐藏层的小网络。不同资料可能采用不同计数口径,读结构图比只看“几层”更可靠。

对于这里这种全连接层,下一层的每个单元都接收上一层的全部输入,各连接有自己的权重。多个单元的权重可以排成矩阵,偏置排成向量;软件就能批量完成这些运算。第 05 篇的矩阵在这里有了具体用途。Keras:Dense 全连接层的计算形式

假设保留所有权重和偏置作为可调整参数,即使当前数值为 0 也计算在内,那么参数数量是:

位置 权重数量 偏置数量 合计
两个输入到两个隐藏单元 2×2=4 2 6
两个隐藏单元到一个输出单元 2×1=2 1 3
总计 6 3 9

两个输入值不是参数,某一次算出的 h₁、h₂ 也不是参数。换一篇笔记,中间值会改变,权重却可以保持不变。参数决定怎样算,中间值是这一次算出的结果。

层的宽度通常关注它有多少单元或表示维度;网络的深度关注串联了多少层计算。增加宽度与增加深度不是一回事,参数多也不一定代表层数更多。

多层表示怎样帮上忙

第 05 篇提到,表示决定哪些信息容易被后续模型使用。这个小网络给出了一个看得见的例子:输入描述“各清单是否存在记录”,隐藏层把它改写成“哪个方向存在差异”。在新表示上,最后一步只要相加。

更复杂的任务也可以利用这种分层组合。以识别手写数字为直觉例子,局部像素变化可以组合成笔画,再组合成更大的形状模式。深层网络允许后续计算反复使用前面形成的表示,而不是每一步都重新从原始像素开始。对某些函数,这样的组合能比非常宽的浅层网络表达得更紧凑。《动手学深度学习》:隐藏表示与多层结构

但不能把这个直觉写成固定分工表,认为“第一层一定认识笔画、第二层一定理解文字、第三层一定掌握逻辑”。实际中间表示由结构、数据和训练目标共同影响,并不保证每个单元都有一个人类能命名的含义。一个概念也可能由多个数值共同表达。

本篇恰好能给 h₁、h₂ 命名,是因为我们亲手设计了它们。通常训练神经网络时,不必逐个告诉中间单元应该识别什么,而是给最终任务设定目标,让参数更新逐步改变这些中间计算。具体怎样更新,将在下一篇讲。

“深度学习”关注的正是利用多层计算学习表示与映射。这里的一层隐藏层小例子帮助理解组成方式,不应被当作现代大模型的规模或完整结构。

从小网络到大模型,需要跨过哪些距离

大语言模型中的计算规模更大,连接方式也更复杂。Transformer 使用注意力机制以及前馈网络等组件组织信息,不能把本篇的两输入网络简单放大,就当作它的完整架构。第二部分会分别解释这些组件。Transformer 原始论文:Attention Is All You Need

但我们已经获得了几个继续学习的支点:输入要变成数值表示;参数参与计算;中间表示层层变化;最终输出还要根据任务解释成分数、概率或其他结果。

多层结构也会带来训练难题。更深不等于自然更好训;残差网络的研究就专门针对深层网络的优化困难,提出让层学习相对于输入的变化,以帮助训练更深的模型。这里无需掌握具体结构,只需知道网络设计还要考虑“怎样学得动”。原始论文:Deep Residual Learning for Image Recognition

把这些区别放回个人项目中,会更容易判断问题发生在哪一层:

你看到的现象 需要进一步检查什么
某种网络在数学上能表达所需映射 训练是否真的找到了合适参数
模型在训练样本上表现很好 对新的笔记是否仍然有效
模型能生成一张看起来不错的卡片 内容是否忠实、文件是否真的保存
新模型参数更多、结构更深 在自己的任务上,质量、速度和成本是否合适

因此,架构提供表达方式,训练决定学到的参数,评估检验实际表现,应用程序还要完成文件、界面和流程。它们彼此相关,却不能相互代替。

理解检查:自己算一遍这个小网络

  1. 计算单元先算 z=2x₁-x₂-0.5,再经过 ReLU。输入 [0,1] 时,z 和单元输出各是多少?
  2. 清单网络输入 [0,1] 时,两个隐藏值和最终输出分别是多少?
  3. 若把清单网络中的两个 ReLU 去掉,再增加几个只做加权相加与偏置的串联层,是否就能获得非线性表达能力?
  4. 一个全连接网络有 2 个输入、3 个隐藏单元、1 个输出单元;隐藏层与输出层都使用偏置。共有多少参数?
  5. 某层输出一个 100 维向量,是否意味着它有 100 个参数,或者其中每一维都代表一个固定概念?

第 1 题: z=2×0-1-0.5=-1.5;ReLU 输出 0。中间负分数是合法的,它不是负概率。

第 2 题: h₁=ReLU(-1)=0,h₂=ReLU(1)=1,因此 y=1,表示两份清单的记录不一致。

第 3 题: 不能。这样的串联仍能合并成一个仿射变换。增加层数本身不能替代非线性操作。

第 4 题: 隐藏层有 2×3+3=9 个参数,输出层有 3×1+1=4 个,共 13 个。输入值和当前隐藏值不另算参数。

第 5 题: 都不意味着。100 是该输出的维度;产生它需要多少参数取决于层的结构与输入大小。每个坐标的意义也不能仅凭维度推断。

现在你已经能把“输入 → 模型 → 输出”中的模型拆开了。不过,本篇的权重是我们手选的,真实训练往往有太多参数,不能靠人逐个试。下一篇就把这里的前向计算与第 06 篇的损失接起来:梯度下降、反向传播和参数更新,分别负责什么?


上一篇:06|概率、预测与损失:模型怎样知道自己需要改进

下一篇:08|训练究竟在做什么:梯度下降、反向传播与参数更新

返回:第一部分大纲