跳到正文
AI 知识地图 0.18 · 2026-07-30
关于与纠错文字目录 / Search
理解原理

神经网络

从「为什么需要」到「如何通过反向传播学会」

Neural Network · 人工神经网络 · ANN

建议 45–60 分钟 · 基础 → 中级 · 需要:代数、函数、导数

核心命题 神经网络的本质不是「很多节点」,而是可微分的非线性函数复合。前向传播算出答案,损失函数度量错误,反向传播用链式法则把错误分配给每个参数,优化器再据此微调——四步合成一个能从数据里学习的闭环。
读完这一页,你应该能自己回答:
  • 必要性——为什么线性模型处理不了图像、语言这类问题,而神经网络可以。
  • 结构——输入层、隐藏层、输出层、节点、权重、偏置、激活函数各自负责什么。
  • 推理——一条输入怎样经过加权求和与非线性变换,最终变成预测。
  • 学习——损失、梯度、链式法则、反向传播、梯度下降如何合成一个闭环。
  • 数学——读懂 z = Wx + ba = φ(z)θ ← θ − η∇L(θ),并能手算一次更新。
  • 边界——什么时候该用它、什么时候不该,怎样识别过拟合与训练失败。
贯穿全页的最小例子 从头到尾我们只用一个网络当例子:2 个输入 → 2 个 ReLU 隐藏节点 → 1 个 Sigmoid 输出。前面用它讲结构和道理,第 9 节用它做一次完整的数字手算。你不必一次记住所有符号,遇到时回看这里即可。

1为什么需要神经网络直觉

这一节真正想建立的核心认识是:神经网络出现,不是因为线性模型没有用,而是因为现实世界中很多重要关系无法用一条“平直边界”表达;神经网络通过学习非线性中间特征,让模型能够描述这些复杂关系。

先看线性模型在做什么。公式

y' = w_1x_1+w_2x_2+…+w_nx_n+b

表示模型把所有输入特征乘上各自的权重,再相加,最后加上偏置,得到一个预测分数。例如,要根据面积、房龄和距离市中心的远近预测房价,可以把三个特征分别乘以对应权重再相加。权重表示某个特征对结果的作用方向和强弱:正权重通常表示特征越大,预测分数越高;负权重则表示特征越大,预测分数越低。偏置 b 不依赖任何输入,它负责调整整个预测结果的基准位置。

在线性回归中,这个分数可以直接作为预测值;在二分类中,可以根据分数是否超过某个阈值来决定类别。假设使用零作为阈值,那么分类边界就是:

一条直线:分不开 一条曲线:分得开
图 1 左:蓝色点集中在内部,红色点分布在外围,一条直线无法将两类完全分开。右:图中的闭合曲线将蓝色点包围在内、红色点留在外。神经网络能够学习这样的非线性分类边界。
w_1x_1+w_2x_2+…+w_nx_n+b=0

当输入只有两个特征时,这条边界是一条直线;有三个特征时,它是一个平面;维度更高时,称为超平面。虽然名称不同,但本质相同:它只能进行一次“平的切分”。

这就暴露出线性模型的基本限制。假设平面上有两类点:一类集中在中心,另一类围绕中心形成一个圆环。无论怎样移动或旋转一条直线,都无法把内圈和外圈完全分开,因为正确边界需要围绕中心弯曲并闭合。这里的困难不是模型还没有找到“正确的直线”,而是正确答案根本就不属于直线这一类边界。继续训练线性模型只能在许多不完美的直线中寻找相对较好的一个,不能从根本上解决问题。

不过,“原始数据不是线性可分的”并不等于线性模型永远无法处理。可以先人为构造新特征。例如,如果内圈和外圈的区别取决于点到圆心的距离,那么可以计算

r^2=x_1^2+x_2^2

再让线性模型根据 r^2 是否超过某个阈值分类。在原始的 x_1,x_2 坐标中,边界是一条圆形曲线;但在新特征 r^2 上,它只是一个简单阈值。这说明一个非常重要的事实:很多所谓的非线性问题,可以通过合适的特征变换,转化为容易处理的问题。

传统特征工程就是由人寻找这种变换。对于结构清楚、特征数量少的问题,这种方法可能非常有效。例如,预测物体运动时可以构造速度和加速度;分析金融数据时可以构造收益率、移动平均值和波动率。问题在于,当输入是一张图片、一段声音或一篇文章时,原始维度可能达到几千甚至几百万,而且真正有用的组合往往无法提前列举。

以图像识别为例,单个像素本身通常没有多少意义。判断图片里是否有一只猫,可能需要先组合相邻像素形成边缘,再组合边缘形成纹理和局部形状,再组合局部形状形成耳朵、眼睛和轮廓,最后综合这些结构作出判断。如果完全依靠人手工规定哪些像素应该怎样组合,不仅组合数量巨大,而且很难覆盖光照、角度、姿态和背景的变化。

因此,神经网络最重要的价值并不是表面上的“层数很多”,而是它能在训练过程中自动学习一系列有用的特征变换。原始输入经过隐藏层后,被逐步表示为新的中间特征。以图像为例,浅层可能对边缘和颜色变化敏感,中间层可能组合出纹理或局部结构,更深层则可能形成与完整物体有关的表示。具体网络未必严格按照这种人类可命名的层级工作,但核心思想是:模型不再要求人把所有关键特征提前设计好,而是根据训练目标,从数据中找到有助于降低误差的内部表示。

接下来需要理解一个容易产生误会的地方:既然一层线性变换能力有限,是否只要叠加很多线性层就能解决问题?答案是否定的。假设第一层为

h=W_1x+b_1

第二层为

y=W_2h+b_2

其中 x 是原始输入,h 是第一层产生的中间结果,y 是最终输出。把第一层代入第二层,可以得到:

y =W_2(W_1x+b_1)+b_2; =(W_2W_1)x+(W_2b_1+b_2)

如果令

W=W_2W_1, b=W_2b_1+b_2

那么整个两层网络就变成:

y=Wx+b

它仍然只是一次仿射变换。这里更严谨地说,带偏置的 Wx+b 属于仿射变换;日常讲解中经常把它笼统称为线性层。无论名称如何,关键结论不变:多个不带非线性激活的线性或仿射层,可以被合并成一个等价的层。

这意味着,即使这样的网络有一百层,它能够表达的函数类型也没有发生本质变化。中间虽然产生了很多变量,最终仍然只能形成平直的分类边界。深度只增加了参数表示和计算过程,没有增加解决复杂非线性问题所需的表达能力。

真正改变局面的,是在线性变换之间加入非线性函数。结构从

W_2(W_1x+b_1)+b_2

变成类似

W_2 σ(W_1x+b_1)+b_2

其中 σ 是非线性激活函数。由于 σ 不能像矩阵乘法和加法那样被简单合并掉,前后两层不再等价于单个线性层。网络可以反复进行“线性组合—非线性变换—再次组合”,逐步构造弯曲而复杂的函数和决策边界。由此可见,神经网络的能力来自两个因素的配合:线性层负责组合信息,非线性激活负责打破只能进行平直变换的限制。

还需要避免把“神经网络能表达复杂关系”误解成“任何问题都应该使用神经网络”。模型是否合适,取决于数据和任务。神经网络通常适合图像、文本、语音等高维数据,也适合存在复杂非线性规律且拥有足够训练数据的问题。但如果数据量很小、主要是结构化表格、业务规律能用几条明确规则表达,或者任务要求每一步都具有严格可解释性,那么线性模型、树模型或规则系统可能成本更低、训练更快、结果更稳定,也更容易检查。

因此,本节可以浓缩为一条完整的逻辑链:

线性模型只能形成平直边界 → 人工特征变换可以解决部分非线性问题 → 高维复杂数据中的有用特征难以由人穷举 → 神经网络让模型自行学习中间特征 → 但单纯堆叠线性层仍等价于一层 → 必须加入非线性,深度才真正获得新的表达能力。

2网络的结构:它由什么组成直觉数学

上一节已经说明,神经网络不能只靠堆叠线性变换获得新的表达能力,它必须在线性变换之间加入非线性。这一节进一步回答:这些变换在网络里以什么结构组织起来,以及输入层、节点、隐藏层和输出层分别承担什么工作。

可以先把一个最小神经网络看成一条信息加工流水线:

输入特征→隐藏层→输出层→预测结果
w x₁ x₂ h₁ h₂ ŷ 输入层 隐藏层(ReLU) 输出层(Sigmoid) 特征进来 预测出去
图 2 贯穿全页的最小网络。每条连线是一个可学习的权重 w(高亮那条只是示意其中一条);每个非输入圆圈是一个节点,先加权求和、再过激活函数。

例如,一个网络有两个输入 x_1,x_2,一个包含两个节点 h_1,h_2 的隐藏层,以及一个输出节点 y-hat。输入首先同时传给隐藏层的两个节点;隐藏层各自产生一个响应;这两个响应再传给输出节点,最终得到预测。图中的每条连线都带有一个可以通过训练调整的权重,而每个非输入节点通常还拥有自己的偏置。

输入层是网络接收数据的位置。它通常不进行真正的学习计算,而是承载已经转换成数字的特征向量 x。在表格任务中,输入可能是年龄、收入和消费次数;在图像任务中,输入可能是像素值;在文本模型中,原始词语会先被转换成数字向量,再进入后续网络。输入层的作用不是理解这些数字,而是为网络明确“一份样本由哪些数值组成”。

需要注意,输入数字的含义和组织方式非常重要。神经网络不能直接接触现实对象本身,它看到的始终是数字表示。如果输入表示丢失了关键信息,后面的网络再复杂也无法凭空恢复。例如,只给模型一张图片的平均亮度,却要求它辨认图片中的物体,输入本身就没有保留足够的形状信息。

输入进入一个普通节点后,首先计算:

z=w· x+b=Σ_i w_ix_i+b

然后再计算:

a=φ(z)

这两步对应节点内部的两个阶段。

第一步是加权求和。每个输入 x_i 都乘以一个权重 w_i,所有结果相加后再加偏置 b,得到 z。这个 z 被称为预激活值,因为它是进入激活函数之前的结果。

第二步是激活。激活函数 φz 进行变换,得到节点真正传给下一层的输出 a。如果激活函数是 ReLU,那么

a=max(0,z)

负的预激活值会变成零,正值则保留下来。如果输出层使用 Sigmoid,那么

a=((1) / (1+e^(-z)))

任意大小的 z 都会被压缩到 0 和 1 之间,因此常被用来表示二分类中的概率式输出。

可以把一个节点理解成一个“可学习的模式探测器”,但这个说法需要拆开理解。权重向量 w 描述节点关心的模式方向,点积 w· x 衡量当前输入与这个方向的匹配程度,偏置 b 调整触发门槛,激活函数则决定匹配结果如何转化为响应。

假设输入有两个特征,一个节点的权重是

w=[2,-1]

偏置为 -0.5,那么它计算:

z=2x_1-x_2-0.5

这意味着该节点倾向于在 x_1 较大、x_2 相对较小时产生较高响应。若使用 ReLU,只有当

2x_1-x_2>0.5

时,它才输出正数。偏置 -0.5 在这里改变了触发条件:没有偏置时,边界必须经过原点;加入偏置后,边界可以整体移动。由此可见,权重负责决定探测方向,偏置负责决定探测门槛。

“一个节点检测一种模式”是一种帮助理解的近似说法,并不表示每个节点一定对应一个能够被人清楚命名的概念。某些节点可能对边缘、颜色或词语关系产生明显响应,但也有很多节点学习到的是分散而抽象的数学特征,很难直接命名。真正重要的是,不同节点能够学到不同的权重和偏置,从而对输入的不同方向或组合产生不同响应。

真实任务通常不可能依靠一个模式完成。因此,一个隐藏层会放置多个节点,让它们并行处理同一份输入。假设这一层有 m 个节点,每个节点都会计算自己的预激活值和激活结果:

z_1 =w_1· x+b_1, a_1 =φ(z_1); z_2 =w_2· x+b_2, a_2 =φ(z_2); ⋮ ⋮; z_m =w_m· x+b_m, a_m =φ(z_m)

把它们的输出排列起来,就得到一个新向量:

a= [a_1; a_2; ⋮; a_m]

所以,一层的输出通常不是一个最终答案,而是由许多节点响应组成的新表示。每个输出分量都概括了输入的某个方面,下一层会把这个新向量当作自己的输入。

这正是隐藏层的核心意义:隐藏层不直接给出任务答案,而是把原始输入转换成更适合后续判断的表示。例如,在一种理想化的图像识别解释中,第一层可能响应横向边缘、纵向边缘或颜色变化,下一层再组合这些响应形成角点或纹理,更深的层继续组合出局部形状。实际网络学到的表示通常比这个例子更复杂,但逐层转换表示的逻辑是一致的。

“隐藏”并不是说这些层无法被查看,而是说训练数据通常只直接规定输入和目标输出,并没有逐个告诉模型每个中间节点应该表示什么。隐藏层的表示是在优化最终任务的过程中自行形成的。比如训练数据只标注图片是猫还是狗,却不会额外规定某个节点必须检测耳朵;如果耳朵相关特征有助于降低分类误差,网络可能在训练中形成相应响应。

当一层包含许多节点时,逐个书写相同结构的公式会很繁琐。矩阵记号只是把这些计算合并表达。把每个节点的权重向量作为矩阵的一行,就得到权重矩阵 W;把每个节点的偏置组成向量 b,于是整层计算可以写成:

组成它是什么它解决什么
输入层承载特征向量 x,通常不做学习计算把现实对象(像素、词、数值)变成一串数字
权重 w每条连线上的可学习系数决定信息被放大、抑制还是反向
偏置 b每个非输入节点的可学习常数平移触发门槛,使节点不必过原点
节点 / 神经元先加权求和,再过激活函数检测某一种模式并输出响应强度
隐藏层输入与输出之间的中间层逐层形成对任务更有用的新表示
激活函数 φ作用在加权和上的非线性函数打破「多层仍等于一层」的线性坍缩
输出层把最终表示映射为任务输出产生数值、概率或类别分布
z=Wx+b
a=φ(z)

假设输入 xn_(in) 个分量,而这一层有 n_(out) 个节点,那么各对象的形状是:

x∈R^(n_(in))
W∈R^(n_(out)× n_(in))
b,z,a∈R^(n_(out))

矩阵 W 的第 j 行就是第 j 个节点的权重。矩阵乘法 Wx 一次完成所有节点各自的点积。因此,矩阵没有引入新的神经网络原理,它只是高效组织并行计算的方式。

输出层负责把最后一个隐藏层形成的表示转换成任务需要的结果。它的具体形式取决于任务:

  • 回归任务可能只输出一个不受限制的数值,例如预测温度或价格;
  • 二分类任务通常输出一个数值,再通过 Sigmoid 转换成 0 到 1 之间的结果;
  • 多分类任务通常为每个类别输出一个分数,再通过 Softmax 转换成类别分布;
  • 更复杂的任务可能输出一串词、多个边界框,或者与输入同样大小的像素结果。

因此,输出层不是固定结构,它必须与目标的含义相匹配。即使前面的隐藏层完全相同,更换输出层也可以让网络服务于不同类型的任务。

接着看参数量。对于一个全连接层,每个输入都连接到每个输出节点。若有 n_(in) 个输入和 n_(out) 个节点,权重数量为:

n_(in)× n_(out)

每个输出节点还有一个偏置,因此偏置数量为:

n_(out)

总参数量是:

n_(in)× n_(out)+n_(out)

对于“2 个输入 → 2 个隐藏节点 → 1 个输出节点”的网络,第一层参数量为:

2×2+2=6

其中有 4 个权重和 2 个偏置。第二层参数量为:

2×1+1=3

其中有 2 个权重和 1 个偏置。整个网络共有:

6+3=9

个可学习参数。

这里的“可学习”表示这些参数不是由设计者逐个写死,而是在训练过程中根据误差不断调整。网络结构决定有多少层、每层多少节点以及节点如何连接;训练则在这个预先规定的结构内寻找合适的权重和偏置。结构是容器,参数是容器中需要学习的具体数值。

参数更多通常意味着网络拥有更大的表示容量,因为它可以调整的自由度更多。但容量更大不等于效果一定更好。参数增加会带来至少三种成本:需要更多计算,训练和推理会更慢;需要更多存储空间和显存;也更容易记住训练样本中的偶然细节,产生过拟合。另一方面,网络太小又可能没有足够能力表达任务规律,形成欠拟合。

因此,设计网络时真正要平衡的是:让模型容量足以表示任务中的规律,同时又与数据规模、计算资源和泛化要求相匹配。网络并不是节点越多、层数越深就必然越好。

这一节的结构关系可以总结为:

输入层承载数字化特征;权重选择和组合信息;偏置移动节点的触发门槛;激活函数提供非线性;多个节点并行形成一层的新表示;隐藏层逐步把表示变得更适合任务;输出层把最终表示转换为所需答案;所有权重和偏置共同构成训练要学习的参数。

3前向传播:网络怎样给出答案数学

前两节已经确定了两件事:神经网络由一层层节点组成,每个节点执行“加权求和,再经过激活函数”;非线性激活使多层网络不再坍缩成一个线性模型。前向传播要回答的是:当输入和参数都已经给定时,数据如何经过这些层,最终变成一个预测结果?

“前向”描述的是计算方向。从输入层开始,信息依次流过各个隐藏层,最后到达输出层,中间不向回走。假设网络有两层可学习变换,它的完整计算可以写成:

z^((1))=W^((1))x+b^((1))
a^((1))=φ(z^((1)))
z^((2))=W^((2))a^((1))+b^((2))
y-hat=g(z^((2)))

这里,上标 (1)(2) 表示不同层,并不是平方。x 是送入网络的输入,W^((1)),b^((1)),W^((2)),b^((2)) 是当前参数,φ 是隐藏层激活函数,g 是输出层根据任务选择的变换,y-hat 是网络给出的预测。帽子符号用来区分“模型预测的结果”与真实目标 y

前向传播的第一步其实发生在网络计算之前:把现实数据转换成适合网络处理的数字。不同类型的数据需要不同预处理。例如,连续数值可能需要标准化,类别可能需要编码,图片像素可能需要缩放,文本则需要先转换成词元和向量。预处理不是无关紧要的包装,因为输入数值的尺度和表示方式会直接影响网络后续看到的信息。

以数值标准化为例,如果一个特征的范围是 0 到 1,而另一个特征的范围是 0 到 100 万,后者在加权求和中可能天然产生更大的数值。网络虽然理论上可以通过调整权重补偿,但训练往往会更困难。把特征调整到较为合理的尺度,通常能让计算和学习更加稳定。需要注意的是,训练和实际使用时必须采用一致的预处理规则,否则即使网络参数没有变化,它接收到的输入含义也会改变。

得到输入向量 x 后,第一隐藏层计算:

z^((1))=W^((1))x+b^((1))

这是整层所有节点的加权求和。矩阵 W^((1)) 的每一行对应一个节点的权重,偏置向量 b^((1)) 为每个节点提供独立的偏置。计算得到的 z^((1)) 是这一层所有节点的预激活值。

随后,激活函数逐个作用在这些预激活值上:

a^((1))=φ(z^((1)))

如果隐藏层采用 ReLU,那么每个分量都按照 max(0,z) 处理。正值被保留,负值变成零。这样得到的 a^((1)) 不再只是原始输入的一次线性组合,而是第一隐藏层根据当前参数提取出的新表示。

这个新表示会成为下一层的输入。也就是说,第二层不再直接处理原始特征 x,而是处理第一层产生的 a^((1))。若还有更多隐藏层,就继续重复:

z^((l))=W^((l))a^((l-1))+b^((l))
a^((l))=φ^((l))(z^((l)))

其中 l 表示当前层,a^((l-1)) 是上一层的输出。第一层通常把 a^((0)) 视为原始输入 x。因此,无论网络有多少层,前向传播都可以理解为不断重复“线性变换产生预激活值,再用非线性函数产生新表示”。

可以用上一节的“2 输入 → 2 隐藏节点 → 1 输出节点”网络做一次具体计算。假设输入为:

x=[2; -1]

隐藏层参数为:

W^((1))= [1, 1; 2, -1], b^((1))= [0; -1]

首先计算预激活值:

z^((1))= [1, 1; 2, -1] [2; -1] + [0; -1] = [1; 4]

若隐藏层使用 ReLU,那么:

a^((1))= [max(0,1); max(0,4)] = [1; 4]

再假设输出层权重和偏置为:

W^((2))=[1, -0.5], b^((2))=0

输出层的预激活值就是:

z^((2))=1×1+(-0.5)×4=-1

如果这是二分类任务,输出层采用 Sigmoid,则预测为:

y-hat=((1) / (1+e^(-(-1))))≈0.269

如果把 y-hat 解释为属于正类的预测概率,那么网络当前认为正类的可能性约为 26.9%。若分类阈值设为 0.5,它会预测为负类。这个例子展示了前向传播的全部过程:每一步都由当前输入、权重、偏置和激活函数确定,没有随机猜测,也没有在计算途中修改参数。

输出层应采用什么变换,取决于任务要求。回归任务可能直接输出 z,因为目标可能是任意实数;二分类任务常使用 Sigmoid,把一个分数压缩到 0 和 1 之间;互斥的多分类任务常使用 Softmax,把多个类别分数转换成总和为 1 的分布。输出变换必须与损失函数和目标含义相互配合,不能因为某种激活函数常见,就不分任务地使用。

前向传播本身只是一次计算过程,并不意味着网络正在学习。网络在实际推理时,通常执行以下操作:接收新输入,采用与训练时一致的预处理,使用已经确定的参数完成前向传播,然后输出预测。整个过程中,权重和偏置保持不变。相同参数面对相同输入,在没有额外随机机制时,会得到相同结果。

训练则包含前向传播,但不止于前向传播。训练时首先通过前向传播得到 y-hat,然后把预测与真实目标 y 比较,计算损失。接下来还要判断每个参数对损失负有多大责任,并按能够减小损失的方向更新参数。因此,训练的逻辑链是:

输入→前向传播→预测→计算损失→计算梯度→更新参数

而单纯推理通常只包含前半部分:

输入→前向传播→预测

区分两者很重要。前向传播回答的是“在参数保持当前数值时,这个网络会输出什么”;损失函数回答“这个输出错了多少”;反向传播回答“哪些参数造成了这些误差以及影响方向”;优化器则回答“参数下一步具体改多少”。前向传播提供了训练所需的预测和中间计算结果,但它自己并不负责纠错。

这一节可以归结为一句话:前向传播就是让输入按照网络既定的结构和当前参数,逐层经过“加权求和与非线性变换”,最终形成符合任务格式的预测;推理到这里就结束,而训练还要根据预测误差反过来调整参数。

4激活函数:非线性从哪里来直觉数学

前面留下了一个关键问题:多个线性或仿射层即使叠得很深,整体仍能合并成一个仿射变换,那么神经网络为什么能表示弯曲而复杂的关系?答案就是在线性层之间加入激活函数。线性层负责重新组合信息,激活函数负责打破线性,使这些组合能够产生转折、门控和复杂边界。

一个节点通常先计算预激活值:

ReLU 0 2 4 z −44 max(0, z) Sigmoid 0 0.5 1 z −44 0 < f(z) < 1 tanh -1 0 1 z −44 −1 < f(z) < 1
图 3 三种常见激活函数的形状。它们的共同点是都不是直线——正是这个「拐弯」给了网络表达非线性的能力。

横轴均为输入 z;各图纵轴刻度单独标明。圆点标出 z=0:ReLU 为 0,Sigmoid 为 0.5,tanh 为 0。图中只展示 −4 到 4 的输入区间。

z=w· x+b

再通过激活函数得到输出:

a=φ(z)

如果 φ(z)=z,激活函数只是原样放行,网络仍然是线性的。只有当 φ 是非线性函数时,前后两层才不能简单合并。例如:

y=W_2φ(W_1x+b_1)+b_2

由于 φ 位于两次线性变换之间,通常无法把整个式子重新整理成单个 Wx+b。这个看起来很小的变化,正是深层网络获得额外表达能力的关键。

最常见的隐藏层激活之一是 ReLU:

ReLU(z)=max(0,z)

z<0 时,它输出 0;当 z>0 时,它输出 z。ReLU 的图像由两段直线组成,但整体不是一条直线,因为它在 z=0 处改变了斜率。这个折点就是非线性的来源。

单个 ReLU 节点会根据 w· x+b 的正负,把输入空间分成两个区域。在一个区域内节点关闭,输出为零;在另一个区域内节点激活,输出随输入线性变化。多个 ReLU 节点使用不同的权重和偏置,就会在不同位置形成许多分界。它们的输出再被后续层组合,会把输入空间划分成更多区域。

因此,ReLU 网络形成的复杂函数可以理解为“分段线性”:每个小区域内部仍是一种线性关系,但跨过不同节点的激活边界后,函数斜率会发生变化。就像用许多短直线段可以逼近一条圆弧,大量节点和多层组合也能用许多局部平直的片段拼出整体弯曲的决策边界。这里并不是某一个节点独自画出完整曲线,而是许多节点共同提供转折,再由后续层把这些转折组合起来。

ReLU 形式简单、计算便宜。在正半轴上,它的导数为 1,不会因正输入增大而像 Sigmoid 那样进入梯度接近零的饱和区;但在负半轴上,它的输出和导数都为 0。不过,ReLU 也有明显风险:当 z<0 时,输出恒为零,对 z 的梯度也是零。如果某个节点在训练数据上长期落在负半轴,它可能无法再获得有效更新,持续输出零,这被称为“死亡 ReLU”。

Leaky ReLU 是一种直接的缓解方法:

LeakyReLU(z)=max(alpha z,z)

其中 alpha 是一个较小的正数。这样,负半轴不再完全水平,而是保留一条很缓的斜线;节点在负区间仍可能接收到梯度。不过,alpha 需要人为设定或通过某种方式确定,而且它只能缓解部分问题,并不保证所有训练困难都会消失。

Sigmoid 的公式是:

σ(z)=((1) / (1+e^(-z)))

它把任意实数压缩到 0 和 1 之间。z 很大时,输出接近 1;z 很小时,输出接近 0;z=0 时,输出为 0.5。这个范围使它特别适合二分类输出,或者用于网络内部需要“开多少、关多少”的门控结构。

函数公式 / 范围典型用途主要代价
ReLUmax(0, z)多数隐藏层的稳健起点z<0 时梯度为 0,可能「死亡」
Leaky ReLUmax(αz, z)缓解死亡 ReLU负半轴还要选个 α
Sigmoid1/(1+e⁻ᶻ),0~1二分类输出概率、门控两端饱和,隐藏层易梯度消失
tanh−1~1需要零中心输出时仍会饱和
GELU平滑门控现代 Transformer 隐藏层常见计算略复杂
Softmaxeᶻⁱ / Σⱼeᶻʲ互斥多分类的输出层类别多时计算与校准需注意

Sigmoid 的问题是饱和。当输入位于很大的正值或负值区域时,曲线几乎变平,导数接近零。反向传播经过这种区域时,梯度可能被显著缩小;若网络有很多层,这种缩小逐层累积,就容易产生梯度消失。因此,Sigmoid 虽然在二分类输出层很常见,却通常不是现代深层网络隐藏层的默认选择。

tanh 可以写成:

tanh(z)=((e^z-e^(-z)) / (e^z+e^(-z)))

它把输入压缩到 -1 和 1 之间。与 Sigmoid 相比,tanh 的输出以零为中心:负输入产生负响应,正输入产生正响应。这在某些模型中更方便。但 tanh 的两端同样会变平,所以仍然存在饱和和梯度消失的问题。

GELU 是现代 Transformer 隐藏层中的常见选择。它不像 ReLU 那样在零点进行硬切断,而是根据输入大小进行平滑门控:较大的正值大多保留,较大的负值大多抑制,零附近则平滑过渡。它保持了非线性,同时比 ReLU 更平滑,但计算表达式也更复杂。选择 GELU 并不意味着它在所有任务上都必然优于 ReLU;它更应被理解为某些现代架构经过实践验证的常用设计。

Softmax 处理的不是单个数,而是一组类别分数。对第 i 个类别,它计算:

Softmax(z)_i=((e^(z_i)) / (Σ_j e^(z_j)))

每个输出都在 0 和 1 之间,而且所有输出之和为 1。某个类别分数相对于其他类别越大,它得到的输出就越高。因此,Softmax 常用于类别彼此互斥的多分类任务,例如一张图片只能在“猫、狗、鸟”中选择一个类别。

Softmax 输出经常被称为类别概率,但需要谨慎理解。它首先是把相对分数规范化为一个分布形式;这些数值是否真的与现实中的正确概率吻合,还取决于训练数据、损失函数以及模型是否经过良好校准。一个模型输出 0.99,并不自动保证它在所有输出 0.99 的样本中都有 99% 的准确率。

容易混淆的一点是:ReLU、Sigmoid、tanh、GELU 和 Softmax 都可能被统称为激活函数,但它们在网络中的职责并不完全相同。

隐藏层面对的问题是:“怎样把当前表示变成下一层可以继续组合的新表示?”这里使用 ReLU、GELU 或 tanh,主要目的在于引入非线性。如果所有隐藏层都没有非线性,隐藏层到输出变换之前的多层仿射计算就能合并成一个仿射变换。若输出层也不含非线性,整个网络才仍是仿射函数;若输出使用 Sigmoid 或 Softmax,最终概率映射不是仿射函数,但隐藏层仍未获得新的非线性表示能力。

输出层面对的问题则是:“最终答案应该具有怎样的范围和含义?”回归任务可能采用线性输出,让结果可以取任意实数;二分类可能用 Sigmoid 产生一个 0 到 1 之间的值;互斥多分类可能用 Softmax 产生类别分布。输出层可以采用线性映射,也可以采用 Sigmoid、Softmax 等非线性变换。选择哪一种,首先取决于任务所需的输出范围和含义。

位置它要回答的问题常见选择
隐藏层怎样产生复杂、可组合的内部表示?ReLU、GELU、tanh
输出层最终答案应该是什么范围和含义?线性、Sigmoid、Softmax

这一区分还能解释为什么不能孤立选择输出函数。输出层、目标编码和损失函数必须彼此兼容。例如,二分类常把一个输出分数、Sigmoid 与二元交叉熵配合;互斥多分类常把多个类别分数、Softmax 与多类交叉熵配合;实数回归则可能使用线性输出和均方误差。如果组合不匹配,模型输出的含义、损失的计算方式和训练方向就可能彼此冲突。

激活函数也不是越复杂越好。它的选择会影响表示能力、梯度传播、计算成本和训练稳定性。对于普通全连接网络或卷积网络,ReLU 往往是隐藏层的稳健起点;担心负区间完全失去梯度时,可以考虑 Leaky ReLU;Transformer 中常见 GELU;Sigmoid 和 Softmax 则更多根据输出任务或门控需要使用。最终选择仍应结合架构、数据和实际验证。

这一节的逻辑可以总结为:线性层只能对信息进行线性重组,激活函数在这些重组之间制造转折;许多节点的转折经过多层组合,可以拼成复杂的非线性函数。隐藏层激活的主要任务是创造可组合的内部表示,输出层变换的主要任务是把最终数值转换成符合任务含义的答案。

5根本原理:可微分的函数复合直觉

前四节分别介绍了神经网络为什么需要非线性、网络由哪些部件构成、预测如何向前计算,以及激活函数怎样产生非线性。现在可以把这些内容统一成一个核心模型:神经网络把一个复杂映射拆成许多简单函数的复合,并尽量让这些函数对参数可微,从而既能表达复杂关系,又能通过梯度进行训练。

假设一个网络有三层,每层都可以看成一个函数:

f_1(x)=φ_1(W_1x+b_1)
f_2(h_1)=φ_2(W_2h_1+b_2)
f_3(h_2)=g(W_3h_2+b_3)

整个网络就是:

F(x)=f_3(f_2(f_1(x)))

这种“把一个函数的输出交给下一个函数”的关系叫作函数复合。输入 x 先被 f_1 转换成 h_1h_1 再被 f_2 转换成 h_2,最后由 f_3 变成预测。网络的深度,本质上就是这种转换连续发生了多少级。

函数复合为什么有价值?因为复杂规律往往可以拆成若干层次较清楚的简单处理。识别一张图片时,直接从数百万个像素一步跳到“这是一只猫”非常困难;如果先形成局部变化的表示,再组合成纹理和形状证据,最后综合成类别判断,问题就被分成了多级转换。神经网络并不一定真的按照人类语言中的“边缘—部件—对象”严格分工,但函数复合允许它建立这种层级式计算。

这里的每一层都在重新编码信息。重新编码不是简单复制,也不意味着信息一定变得更丰富,而是把上一层的数值转换到一个对后续任务更方便的坐标系统中。例如,同一张图片最初以像素坐标表示;经过若干层以后,网络内部可能形成一些对形状、纹理或类别判断更敏感的方向。原本在像素空间里难以用简单边界区分的样本,在新的表示空间中可能更容易分开。

可以把这种变化类比为重新选择描述问题的语言。假设任务是区分圆环内外的点,在原始坐标 (x_1,x_2) 中需要一条弯曲边界;如果把输入重新表示成“到圆心的距离”,分类可能只需要比较一个阈值。神经网络的隐藏层所做的事情,与自动寻找这种有用的新表示有相似之处,但它通常不是由人提前指定具体公式,而是通过训练寻找能降低最终任务误差的变换。

这就是表示学习。传统特征工程由人决定应该提取哪些特征;表示学习则让模型根据数据和目标,自动调整中间层参数,形成对任务有帮助的内部特征。这里必须强调“对任务有帮助”:网络学到的表示不一定是对所有用途都好,也不一定对应人类容易理解的概念。一个为猫狗分类训练的网络,可能保留区分类别所需的信息,却忽略与分类无关的背景细节。

函数复合提供的是表达能力,但网络还必须能够训练。训练需要回答:如果最终预测有误,每一层、每一个参数应该向哪个方向调整?这就是“可微分”发挥作用的地方。

如果损失记为 L,网络参数记为 θ,训练希望知道:

((∂ L) / (∂ θ))

这个导数描述参数发生很小变化时,损失大致会怎样变化。如果导数为正,沿正方向增大参数会使损失局部上升;如果导数为负,增大参数会使损失局部下降。优化算法利用这些梯度,为大量参数寻找能够减小损失的更新方向。

函数复合之所以特别适合这种训练,是因为链式法则可以把最终误差沿着复合关系逐层传回去。对于:

维度增大它通常意味着常见风险
宽度(每层节点数)同一抽象层级上并行检测更多模式参数、显存、过拟合上升
深度(隐藏层数)用更多级复合表达层级结构梯度传播与优化更难
F(x)=f_3(f_2(f_1(x)))

某个早期参数对最终损失的影响,可以拆成它对本层输出的影响、本层输出对下一层的影响,直到最终输出对损失的影响。这正是反向传播的数学基础。前向传播沿复合函数从输入计算到输出;反向传播则利用链式法则,从损失开始反向计算各参数的梯度。

严格来说,实践中的网络不要求每一点都拥有普通意义下光滑且连续的导数。ReLU 在 z=0 处就不可微,但它在其他位置可微,并且可以在折点选定一个约定的次梯度,所以梯度方法仍然能够工作。因此,这里的“可微分”应理解为:网络的大部分计算能够提供适合反向传播的局部变化信息,而不是要求每个函数在数学上处处光滑。

网络的宽度和深度会以不同方式影响函数复合。宽度是每层的节点数。更宽的一层可以并行形成更多响应,相当于在同一阶段提供更多可调整的特征方向。但节点增加通常意味着参数更多、计算和显存需求更高,同时也可能提高过拟合风险。

深度是隐藏层的数量。更深的网络可以进行更多级变换,把简单模式逐层组合成复杂模式。对于本身具有层级结构的问题,这种复合可能比单层直接表示更有效。但深度也让优化变得困难:梯度必须经过更多层传播,可能逐渐变小、变大或受到不同层尺度的干扰。残差连接、归一化和合适的初始化等技术,很大一部分作用就是让深层函数复合更容易训练。

宽度和深度都能提高模型容量,但不能简单地互相替代,也不能单凭参数数量判断模型质量。更宽可能让同一级表示包含更多模式,更深则允许更多级顺序组合。具体任务适合怎样的比例,需要结合数据结构、计算预算和训练稳定性判断。

“万能逼近”是理解神经网络时最容易被夸大的概念之一。相关理论大意是,在一定条件下,具有足够容量的网络可以把许多连续函数逼近到任意精度。它说明神经网络的函数族具有很强的表达能力,但没有保证训练算法一定能找到所需参数,也没有说明需要多少数据和计算,更没有保证模型面对新样本时仍然正确。

因此,至少要把四个问题分开:

第一,表达能力:网络结构是否存在一组参数,能够表示目标关系?

第二,可优化性:现有训练方法能否在合理时间内找到足够好的参数?

第三,样本效率:为了学到这种关系,需要多少有代表性的数据?

第四,泛化能力:在训练数据之外的新样本上,模型是否仍然有效?

一个网络可能理论上足以表示答案,却因为梯度问题而训练失败;也可能把训练集拟合得非常好,却只是在记忆样本,无法泛化;还可能由于数据中从未包含关键规律,无论模型多大都学不到可靠关系。模型只能利用训练信号中存在的信息,强大的表达能力不能凭空创造事实。

这一节最终要记住的是:神经网络的“神经”外观不是它最根本的数学特征;更本质的描述是一个由许多参数化小函数组成的可微分计算系统。函数复合让它能够逐层学习表示并表达复杂映射,可微分性让最终误差能够通过链式法则传回参数。能表示、能训练、学得省、能泛化,则是四个彼此相关但不能混为一谈的问题。

6从内部数值到答案:输出层与损失数学

前面的网络经过多层变换后,最后一个隐藏层会产生一组内部数值。这些数值只是模型形成的表示,本身还不是现实任务中的答案。要让网络能够训练,必须连续完成两次翻译:输出层先把内部表示翻译成具有任务含义的预测,损失函数再把预测与真实答案的差异翻译成一个可以优化的标量。

假设最后一个隐藏层输出为 h,输出层通常先计算一组原始分数:

z = Wouth + bout

这些原始分数常被称为 logits。接下来是否对 z 进行变换,以及采用什么变换,取决于任务希望输出表达什么。输出层不是一个脱离任务的固定部件,而是模型内部数值与现实答案之间的接口。

对于回归任务,目标通常是任意实数,例如房价、温度或销量。输出层常采用线性输出,也就是直接令:

y-hat=z
任务输出层变换输出的含义为什么这样选
回归线性 / 无激活任意实数房价、温度不该被压进 0~1
二分类Sigmoid正类概率 0~1把一个实数压成概率
互斥多分类Softmax各类概率、和为 1类别互相竞争,只能选一个
多标签每类独立 Sigmoid每个标签各自的概率多个标签可同时成立

这里的“线性”或“无激活”不是说整个网络变成了线性模型,因为前面的隐藏层已经包含非线性;它只表示最后一步不再限制输出范围。如果错误地使用 Sigmoid,预测会被压缩到 0 和 1 之间,显然无法直接表示一般房价。某些回归目标确实有范围限制,此时也可以选择相应变换,但这个选择必须来自目标含义,而不是机械套用。

对于二分类任务,通常只需要一个输出分数 z,再经过 Sigmoid:

y-hat=σ(z)=((1) / (1+e^(-z)))

这样 y-hat 位于 0 和 1 之间,可以解释为模型给正类分配的概率式分数。例如,y-hat=0.8 表示模型强烈倾向于正类,负类对应的分数就是 1-0.8=0.2。若需要最终类别,还要选择阈值;0.5 是常见默认值,但在漏诊与误报代价不同的任务中,最合适的阈值可能不是 0.5。

对于互斥多分类任务,网络为每个类别产生一个 logit,记为 z_1,…,z_K,再通过 Softmax:

p_k=((e^(z_k)) / (Σ_j e^(z_j)))

所有 p_k 都在 0 和 1 之间,且总和为 1。提高一个类别的相对分数会影响其他类别所占的份额,体现类别之间的竞争。这适合“每个样本只能属于一个类别”的任务,例如一张图片在猫、狗、鸟中选择一个。

多标签分类与互斥多分类不同。一张图片可以同时包含“人物”“汽车”和“夜景”,多个标签可以一起成立,因此不能让它们通过 Softmax 争夺总和为 1 的份额。常见做法是为每个标签设置一个独立 logit,并分别使用 Sigmoid:

y-hat_k=σ(z_k)

这样每个标签都有自己的 0 到 1 输出,一个标签的概率提高并不要求其他标签降低。由此可见,Softmax 与多个 Sigmoid 的差别不只是公式不同,而是它们表达了两种不同的现实假设:类别互斥,或者标签可以共存。

确定输出含义后,还需要定义“错了多少”。模型无法直接优化“看起来不错”或“基本正确”这样的模糊评价,它需要一个数值目标。损失函数把预测 y-hat 和真实答案 y 映射成一个标量 L。通常损失越小,表示预测越符合训练目标。

设网络全部权重和偏置为 θ,网络预测写成 f(x;θ)。对包含 N 个样本的训练集,基本目标可写成:

θ^*=argmin_θ((1) / (N))Σ_(i=1)^(N)L(f(x_i;θ),y_i)

其中,x_i 是第 i 个输入,y_i 是它的真实答案,L 是单个样本的损失,求和再除以 N 得到平均训练损失。argmin 问的不是“最小损失是多少”,而是“哪一组参数能使这个目标尽可能小”。训练过程就是不断调整 θ,尝试接近这样的参数。

回归中常见的均方误差,对单个标量预测可写成:

L_(MSE)=(y-hat-y)^2

如果真实值是 10,预测是 12,误差为 2,平方损失为 4;若预测是 20,误差为 10,平方损失为 100。平方会让大误差受到更强惩罚,同时避免正负误差相互抵消。它也具有便于求导的性质。不过,MSE 对异常大的误差比较敏感;如果数据中存在严重异常值,可能需要考虑其他回归损失。

二分类中常见二元交叉熵:

L_(BCE)=-[ylny-hat+(1-y)ln(1-y-hat)]

当真实标签 y=1 时,第二项消失,损失变成:

L=-lny-hat

模型给真实正类的概率越接近 1,损失越小;如果它非常自信地给出接近 0 的概率,损失会非常大。当 y=0 时,损失变成 -ln(1-y-hat),此时模型应给正类较低概率。交叉熵不仅关心最终分类是否正确,还关心模型对正确类别分配了多少概率。

例如,两个模型都把阈值以上的样本判为正类:模型 A 输出 0.51,模型 B 输出 0.99。从准确率角度看,两者都答对一次;但若真实标签为正类,交叉熵会认为 B 的预测更符合目标。反过来,如果真实标签为负类,模型 B 的高置信错误会受到远大于 A 的惩罚。这种连续变化的惩罚为梯度训练提供了细致信号。

损失示例公式直觉
均方误差 MSE(ŷ − y)²大误差被平方放大,常用于回归
二元交叉熵 BCE−[y ln ŷ + (1−y) ln(1−ŷ)]正确类给的概率越低,罚得越重
多类交叉熵−Σₖ yₖ ln pₖ只盯真实类别被分到的概率

互斥多分类常使用多类交叉熵:

L=-Σ_k y_kln p_k

如果真实标签采用 one-hot 编码,只有真实类别对应的 y_k 为 1,其余为 0,那么公式实际化简为:

L=-ln p_(真实类别)

也就是说,它重点检查模型给真实类别分配了多少概率。真实类别概率越高,损失越小;若模型把几乎全部概率给了错误类别,损失就很大。

实践中的实现经常直接把 logits 和交叉熵结合计算,而不是先显式算出 Sigmoid 或 Softmax,再取对数。这样做通常具有更好的数值稳定性。例如,极大或极小的 logit 可能使指数运算溢出,或使概率被舍入为精确的 0,随后计算 ln 0 会产生问题。框架提供的“带 logits 的交叉熵”通常会用等价但更稳定的公式完成计算。这没有改变输出含义,只是改进了数值实现。

损失函数和评价指标不能混为一谈。损失是训练期间供优化器最小化的信号,通常需要对模型输出具有可用梯度。准确率、F1 和 AUC 等评价指标主要用于人判断模型在某种业务标准下表现如何,它们不一定适合直接求导。

以准确率为例,二分类输出从 0.49 变到 0.48 时,如果阈值是 0.5,分类结果没有改变,准确率也没有任何变化;从 0.49 变到 0.51 时,准确率却突然跳变。这样的平台与跳跃无法为每一次微小参数更新提供平滑方向。交叉熵则会随着预测概率连续变化,所以更适合作为训练信号。

但可优化的损失更低,并不自动等于实际评价一定更好。训练集平均损失下降,可能同时伴随验证集表现恶化,这就是过拟合的一种迹象;模型也可能交叉熵较低,却因阈值不合适而在 F1 上表现不佳。因此,训练时用损失指导参数更新,验证和测试时再用符合实际目标的指标评价,两者各司其职。

基本目标公式还只写了训练集上的平均损失。实际训练往往还会加入正则化、类别权重或其他约束,并且真正希望得到的是对未见数据也有效的模型,而不是单纯把训练损失压到最低。θ^* 在复杂神经网络中通常也不是能够严格求出的全局最优解,而是优化算法在有限时间内找到的一组足够好的参数。

这一节的完整逻辑是:最后一个隐藏层只产生内部表示;输出层按照任务规则把它转换成实数、二分类分数、互斥类别分布或多个独立标签;损失函数再把预测与真实答案的差异压缩成一个可求导的标量;训练通过最小化这个标量来更新参数,而准确率、F1、AUC 等指标则从人的任务目标出发评价模型。

7梯度下降:为什么要朝梯度的反方向走数学

上一节用损失函数把预测错误压缩成了一个标量,但知道“现在错了多少”还不够。神经网络可能有成千上万甚至数十亿个参数,训练必须进一步回答:每个参数应该增大还是减小,并且改变多少,才能让损失下降?梯度提供局部方向,学习率控制迈步大小,二者共同构成梯度下降的基本更新。

先从只有一个参数 θ 的情况理解。损失写成 L(θ),它对参数的导数是:

((dL) / (dθ))

这个导数描述当前位置附近参数稍微增大时,损失如何变化。如果导数为正,增大 θ 会使损失上升,因此应适当减小 θ;如果导数为负,增大 θ 反而会使损失下降,因此应适当增大 θ。两种情况可以统一写为:

θ←θ-η((dL) / (dθ))

其中 η>0 是学习率。减去导数会自动选择相反方向:导数为正时参数减小,导数为负时参数增大。

最低点(损失最小) 起点 损失 L(θ)
图 4 把损失想成一条山谷。梯度指向「上坡最陡」的方向,所以每一步朝它的反方向(下坡最陡)走一小段,就能逐步逼近谷底。

当参数很多时,把所有参数记为向量 θ=[θ_1,θ_2,…,θ_m]^T。损失对每个参数的偏导数组成梯度:

∇_θ L= [((∂ L) / (∂θ_1)); ((∂ L) / (∂θ_2)); ⋮; ((∂ L) / (∂θ_m))]

梯度与参数向量形状相同。每个分量说明对应参数发生微小变化时,损失在局部如何响应。梯度不是一个笼统的“错误大小”,而是一份针对全部参数的局部敏感度清单。

为什么梯度表示最快上升方向?假设从当前位置沿单位方向 u 走一小步 ε,损失可以用一阶近似表示为:

L(θ+ε u)≈ L(θ)+ε∇ L(θ)· u, \|u\|=1

在步长相同的情况下,损失变化主要由点积 ∇ L· u 决定。根据点积的几何性质,当 u 与梯度方向相同时,这个值最大,意味着损失增加最快;当 u 与梯度方向相反时,这个值最小,意味着损失下降最快。因此,局部最陡下降方向是:

-∇ L(θ)

这就是“梯度下降”名称背后的直接原因:梯度本身指向局部最快上升方向,取负号后得到局部最快下降方向。

这里的“最快”有两个限制。第一,它比较的是走相同长度的小步时的方向;如果不同方向允许任意步长,就无法直接比较。第二,它只依据当前位置附近的一阶近似,是局部结论,不表示梯度直接指向全局最低点。损失面可能弯曲、狭长、存在鞍点或多个谷底,梯度只告诉我们脚下哪边最陡,并没有提供整张地形图。

原文提到没有唯一的“下降最慢方向”,也可以从点积看出。如果方向 u 与梯度垂直,那么:

∇ L· u=0

一阶近似下损失几乎不变。选择一个与梯度接近垂直、但略微朝下降侧的方向,可以让下降量任意接近零。因此,与“最陡下降”这个明确方向不同,“最慢下降”没有一个具有同等唯一意义的方向。

基本梯度下降更新写成:

θ←θ-η∇_θ L(θ)

负梯度决定方向,学习率 η 决定步长尺度。即使方向正确,步长也会决定训练是否成功。因为梯度只在足够小的邻域内可靠,如果一步走得太远,真实损失面可能已经弯向别处。

学习率过小时,每一步只移动一点点,损失可能稳定下降,但训练需要大量步骤,时间和计算成本很高。在平坦区域中,更新甚至可能小到几乎看不见。学习率过大时,参数可能越过谷底,在两侧来回震荡;更严重时,每次都跳到损失更高、梯度更大的区域,最终数值发散。合适的学习率需要兼顾速度和稳定性,实际训练中也常随训练进程调整。

梯度下降不保证每一步都找到全局最优解。对于深度网络,损失面通常是高维非凸的,可能存在鞍点、平坦区域和许多不同的低损失区域。训练的现实目标通常不是证明找到唯一的全球最低点,而是在可接受的计算预算内找到训练损失较低、验证表现良好的一组参数。

完整训练从参数初始化开始。如果同层隐藏节点的入向权重与偏置相同,它们对相同输入会产生相同响应;若对应的下游连接、优化器状态及更新规则也保持节点置换对称,它们会继续得到相同梯度并保持重复。不同的下游权重就可能打破这种对称。随机初始化权重是让不同节点有机会学到不同模式的常见方法;偏置常可初始化为零,不必把每个参数都随机化。权重全部设为零会有对称或梯度受阻的风险,但具体表现取决于激活函数、连接和更新规则。随机数的尺度仍需合理,过大或过小都可能影响信号和梯度传播。

随后取一批数据进行前向传播。为什么常用一小批而不是每次只看一个样本,或者每次都看完整训练集?使用完整训练集计算的梯度更接近整体平均方向,但每次更新成本很高;单样本更新便宜,却具有较大随机波动。小批量训练在计算效率、硬件并行和梯度稳定性之间提供折中,是现代神经网络训练的常见方式。

对于当前批次,网络完成前向传播并得到预测,然后计算该批样本的平均损失。反向传播再利用链式法则,求出损失对每个权重和偏置的梯度。需要区分:反向传播负责高效计算梯度,梯度下降或其他优化器负责利用梯度更新参数。二者紧密相连,但不是同一个步骤。

最基础的随机小批量梯度下降按当前梯度更新参数;更常见的优化器还会加工梯度。例如,带动量的方法会结合过去的更新方向以减少来回震荡,Adam 会根据梯度的一阶和二阶统计量为不同参数调整有效步长。无论规则多复杂,其共同输入仍然是反向传播得到的梯度,其目的仍然是寻找更低损失的参数。

一次完整的训练步骤可以写成:

术语准确含义
参数 parameter模型内部训练学到的权重和偏置
超参数 hyperparameter训练者手动设的学习率、批大小、层数等
batch一次参数更新用到的一小批样本
epoch训练集被完整过一遍
iteration / step一次「前向 + 反向 + 更新」
取一个 batch→ 前向传播→ 计算损失→ 反向传播→ 优化器更新参数

这个过程重复许多次。一个 batch 是一次参数更新所使用的一小批样本;一次 iteration 或 step 通常表示完成一次“前向、反向、更新”;一个 epoch 表示训练集中的全部样本大致被使用了一遍。如果训练集有 10,000 个样本,batch size 为 100,那么一个 epoch 通常包含约 100 个 step。

参数和超参数也必须区分。参数是模型在训练中学习的内部数值,例如权重和偏置,它们由优化器根据梯度更新。超参数则由训练者或外部搜索过程设定,例如学习率、批大小、隐藏层数、每层宽度和正则化强度。参数是训练过程要寻找的答案;超参数定义了模型结构和寻找答案的方式。

训练期间不能只盯着训练损失。如果训练损失持续下降,而验证损失开始上升,模型可能正在过度适应训练数据。训练曲线可以帮助发现学习率过大导致的震荡、学习率过小导致的停滞、数值发散以及过拟合。梯度下降负责降低当前优化目标,是否能推广到新数据还要依靠验证、正则化、数据质量和合理的停止策略。

这一节最终要建立的认识是:梯度不是通向最低点的地图,而是当前位置的坡度信息;在相同的小步长度下,梯度指向最快上升,负梯度指向最快下降。学习率决定沿负梯度走多远,反向传播负责算出梯度,优化器负责使用梯度,而许多批次和轮次的重复更新共同构成训练。

8反向传播:链式法则如何分配责任数学

上一节说明,优化器需要损失对每个参数的梯度,才能决定参数更新方向。但神经网络的预测由大量参数共同产生,损失函数只给出一个最终数值,并没有直接指出每个权重和偏置分别造成了多少影响。反向传播解决的正是这个计算问题:它利用链式法则,从损失开始向前面的节点逐层传递敏感度,并复用已经计算过的下游影响,从而在一次反向遍历中得到全部参数的梯度。

首先必须区分反向传播和优化器。反向传播负责计算:

∇_θ L

也就是损失对全部参数的梯度。梯度下降、带动量的 SGD 或 Adam 则读取这些梯度,按照各自规则更新参数。例如,最基本的梯度下降执行:

θ←θ-η∇_θ L

因此,反向传播回答“梯度是多少”,优化器回答“得到梯度以后怎样改参数”。反向传播本身通常不会修改权重,把它称为一种优化器是不准确的。

先看一条最简单的计算链。假设某个权重 w 经过以下过程影响损失:

z=wx+b
a=φ(z)
y-hat=g(a)
L=ell(y-hat,y)

从因果关系看,w 先影响 zz 再影响 aa 影响预测 y-hat,预测最后影响损失 L。链式法则把整条影响链写成:

((∂ L) / (∂ w))= ((∂ L) / (∂y-hat))((∂y-hat) / (∂ a))((∂ a) / (∂ z))((∂ z) / (∂ w))

每一项只描述相邻两步之间的局部影响。把这些局部导数相乘,就得到参数 w 对最终损失的总影响。这就是“参数变一点,会让节点变多少;节点的变化会让下一步变多少;最终会让损失变多少”的数学表达。

可以用一个具体的标量例子手算。设:

z=wx+b, a=ReLU(z), y-hat=va,

损失采用:

L=((1) / (2))(y-hat-y)^2

x=2,w=1,b=1,v=3,y=5。前向传播得到:

z=1×2+1=3
a=ReLU(3)=3
y-hat=3×3=9
L=((1) / (2))(9-5)^2=8

接下来从损失向后计算。损失对预测的导数为:

((∂ L) / (∂y-hat))=y-hat-y=4

预测对激活值的导数为:

((∂y-hat) / (∂ a))=v=3

因为当前 z=3>0,ReLU 在这里的导数为:

((∂ a) / (∂ z))=1

预激活值对权重的导数为:

((∂ z) / (∂ w))=x=2

所以:

((∂ L) / (∂ w))=4×3×1×2=24

这个正梯度表示,在当前位置附近增大 w 会使损失上升,因此梯度下降会减小 w。同样可以计算:

((∂ L) / (∂ v))= ((∂ L) / (∂y-hat))((∂y-hat) / (∂ v))=4× a=12

以及:

做法怎样估计参数影响主要代价
逐个试参数每改一个参数,重做一次完整前向参数越多,重复计算越多
反向传播从损失出发,逐层复用已算出的下游影响一次反向即得全部梯度
((∂ L) / (∂ b))=4×3×1×1=12

这说明一个最终误差可以通过不同局部导数,被具体分配到多个参数上。这里的“责任”不是道德意义上的责任,也不是把损失拆成若干份后要求总和等于损失;它表示损失对每个参数的局部敏感度。

梯度的符号和大小需要结合当前位置解释。正梯度表示参数略微增大会使损失局部上升,负梯度表示参数略微增大会使损失局部下降。绝对值较大表示损失对该参数的局部变化较敏感,但不一定意味着这个参数在全局上“更重要”,也不意味着应该不受限制地大幅修改它。真正更新幅度还会受到学习率、优化器状态和正则化等因素影响。

如果用最朴素的方法估计梯度,可以把某个参数增加一个很小的 ε,重新进行完整前向传播,再比较损失变化:

((∂ L) / (∂θ_i))≈ ((L(θ_i+ε)-L(θ_i)) / (ε))

这叫有限差分近似。它在检查少量梯度是否实现正确时很有用,但不适合日常训练。如果网络有一百万个参数,为每个参数分别扰动并重算损失,就需要约一百万次额外前向计算;参数越多,重复计算越严重。

反向传播高效的关键不是链式法则本身的新颖,而是对共同下游计算的复用。假设许多早期参数都会先影响同一个中间值 a,再由 a 影响后面的输出和损失。朴素方法会为每个早期参数重复计算“a 之后如何影响损失”。反向传播则先计算一次:

((∂ L) / (∂ a))

然后把这份已经得到的下游敏感度,与各条进入 a 的局部导数相乘,分别得到更早变量和参数的梯度。共同的后半段只算一次,不为每个参数重新走完整条链。

网络不总是一条没有分叉的链。如果某个变量通过多条路径影响损失,那么它的总梯度是各条路径贡献之和。例如,h 同时进入两个后续分支 u(h)v(h),损失为 L(u,v),则:

((∂ L) / (∂ h))= ((∂ L) / (∂ u))((∂ u) / (∂ h))+ ((∂ L) / (∂ v))((∂ v) / (∂ h))

沿一条路径连续发生的影响用乘法连接,来自多条不同路径的影响用加法汇总。这两条规则足以解释复杂网络中梯度怎样流动:链上相乘,分支相加。

在实际实现中,前向传播除了计算预测,还会保存反向计算所需的中间结果,例如某层输入、预激活值或激活值。反向传播从损失开始,按照与前向相反的顺序处理各个运算,计算每个运算的局部导数,并把上游传来的梯度继续传向更早位置。保存中间结果会占用内存,这也是训练通常比单纯推理需要更多显存的原因之一。

“计算图”是描述这种依赖关系的工具:节点表示数值或运算,边表示一个结果如何被后续计算使用。“动态规划”则强调复用已经计算的子结果。理解这些术语有助于分析复杂实现,但反向传播的核心并不依赖先掌握它们。只要抓住“先算一次下游敏感度,再沿所有进入路径分发”这一点,就已经理解了它高效的根本原因。

反向传播还能解释前面提到的梯度消失和梯度爆炸。早期参数的梯度往往包含许多层局部导数的乘积。在标量链式乘积的简化情形中,若每个局部导数的绝对值都不超过某个小于 1 的常数,连乘的幅度会随层数增加而衰减;持续的放大也可能使梯度变得很大。实际网络涉及雅可比矩阵的连乘及多条路径,因此还取决于权重、激活状态和梯度传播方向。这不是反向传播算错了,而是链式法则忠实反映了深层函数复合中的敏感度变化。

自动微分框架会替我们完成大量求导和复用,但它没有改变基本逻辑。模型先执行前向传播并记录计算关系,损失产生起始梯度,反向过程按链式法则计算所有参数的梯度,最后优化器读取梯度并更新参数。通常还要在下一批数据前清理或重置旧梯度,以免无意累加;某些训练设计会故意累积多个批次的梯度,但那是明确选择。

这一节可以总结为:损失只给出最终错误,反向传播利用链式法则把“参数变化—中间节点变化—预测变化—损失变化”连接起来。它从输出端向前复用共同的下游影响,链上导数相乘、分支贡献相加,一次反向遍历便能得到全部参数的梯度;梯度算完以后,才轮到梯度下降或 Adam 更新参数。

9完整手算:一次前向 + 一次更新数学

这一节把前面分开讲过的结构、激活函数、输出层、损失、反向传播和梯度下降串成一次完整训练步骤。目标不是记住这些具体数字,而是看清:一个样本怎样产生预测和损失,损失怎样变成每个参数的梯度,参数更新后又为什么会让预测发生变化。

任务给出输入:

x=[1; 2]

真实标签为:

y=1

网络有两个输入、两个使用 ReLU 的隐藏节点,以及一个使用 Sigmoid 的输出节点。初始参数为:

W_1= [0.5, -0.25; 1.0, 0.5], b_1= [0; -1]
W_2=[1.2, -0.7], b_2=0.3

矩阵 W_1 的每一行对应一个隐藏节点。因此,第一行 [0.5,-0.25] 是隐藏节点 1 对两个输入的权重,第二行 [1.0,0.5] 是隐藏节点 2 的权重。

先完成前向传播。隐藏层预激活值为:

z_1=W_1x+b_1

第一个隐藏节点得到:

z_(1,1)=0.5×1+(-0.25)×2+0=0

第二个隐藏节点得到:

z_(1,2)=1.0×1+0.5×2-1=1

所以:

z_1=[0; 1]

隐藏层使用 ReLU:

a_1=ReLU(z_1) = [max(0,0); max(0,1)] = [0; 1]

这意味着在当前输入和参数下,第一个隐藏节点没有向后传递正响应,第二个节点输出 1。输出层接收的是 a_1,而不是原始输入 x。它的预激活值为:

z_2=W_2a_1+b_2
z_2=1.2×0+(-0.7)×1+0.3=-0.4

经过 Sigmoid 后:

y-hat=σ(z_2)=((1) / (1+e^(-z_2)))=((1) / (1+e^(0.4)))≈0.4013

真实标签为 1,而模型只给正类约 0.4013 的输出,因此预测偏低。二元交叉熵在 y=1 时化简为:

L=-lny-hat

代入预测:

L=-ln(0.4013)≈0.913

到这里,前向传播回答了“当前参数会预测什么”,损失回答了“这个预测错了多少”。接下来反向传播要从损失开始,求出每个参数的梯度。

Sigmoid 与二元交叉熵组合时,损失对输出层 logit 的导数可以简化为:

((∂ L) / (∂ z_2))=y-hat-y

这个结果可以从链式法则得到。二元交叉熵对 y-hat 求导,再乘上 Sigmoid 的导数 y-hat(1-y-hat),其中一些项会相互抵消,最终留下 y-hat-y。这种简洁且数值性质良好的梯度,是 Sigmoid 与二元交叉熵常被搭配使用的重要原因。

定义输出层误差信号:

δ_2=((∂ L) / (∂ z_2))=0.4013-1=-0.5987

负号表示,如果让 z_2 在当前位置略微增大,损失会下降。这符合直觉:真实标签是 1,而预测偏低,所以模型需要提高输出 logit 和正类预测。

因为:

z_2=W_2a_1+b_2

所以输出权重梯度为:

((∂ L) / (∂ W_2))=δ_2a_1^T

代入数值:

((∂ L) / (∂ W_2))=-0.5987[0, 1] =[0, -0.5987]

第一个输出权重的梯度为零,是因为与它相连的隐藏节点输出为零。当前样本通过这条连接传递的输入为零,所以轻微改变该权重不会改变当前输出。第二个隐藏节点输出为 1,因此第二个输出权重获得非零梯度。

输出层原始分数 z_2 对输出偏置 b_2 的局部导数为 1,所以:

((∂ L) / (∂ b_2))=δ_2=-0.5987

接下来把输出层的影响传回隐藏层。损失对隐藏层激活值的梯度为:

((∂ L) / (∂ a_1))=W_2^Tδ_2
((∂ L) / (∂ a_1))= [1.2; -0.7] (-0.5987) = [-0.7184; 0.4191]

这个向量还只是损失对 ReLU 输出的敏感度。要继续传到 ReLU 之前的 z_1,还要乘以 ReLU 的局部导数。这里约定 ReLU 在 z=0 处的导数取 0;在正数位置导数取 1。因此:

ReLU'(z_1)=[0; 1]

隐藏层误差信号为逐元素相乘:

δ_1 = ((∂ L) / (∂ a_1))odot ReLU'(z_1) = [-0.7184; 0.4191] odot [0; 1] = [0; 0.4191]

第一个隐藏节点的下游影响原本不是零,但在通过 ReLU 导数时被截断了。因此,这个节点对应的第一层参数在当前样本上没有梯度。第二个隐藏节点处于正半轴,梯度可以继续通过。

由于:

z_1=W_1x+b_1

第一层权重梯度是隐藏层误差信号与输入的外积:

((∂ L) / (∂ W_1))=δ_1x^T
((∂ L) / (∂ W_1))= [0; 0.4191] [1, 2] = [0, 0; 0.4191, 0.8382]
参数更新前梯度更新后
W₂ 第二项−0.7000−0.5987−0.6401
b₂0.3000−0.59870.3599
W₁ 第二行[1.0, 0.5][0.4191, 0.8382][0.9581, 0.4162]
b₁ 第二项−1.00000.4191−1.0419

第一层偏置梯度为:

((∂ L) / (∂ b_1))=δ_1 = [0; 0.4191]

至此,反向传播已经得到所有参数的梯度。现在由梯度下降进行更新,学习率为 η=0.1

θ_(new)=θ_(old)-0.1((∂ L) / (∂θ))

输出层第二个权重更新为:

-0.7-0.1(-0.5987)=-0.6401

输出偏置更新为:

0.3-0.1(-0.5987)=0.3599

第一层第二行权重更新为:

[1.0, 0.5] -0.1 [0.4191, 0.8382] = [0.9581, 0.4162]

第一层第二个偏置更新为:

-1-0.1(0.4191)=-1.0419

梯度为零的参数保持不变。因此,W_2 的第一项、W_1 的第一行和 b_1 的第一项都没有在这一次更新中变化。这不代表它们永远无法学习;换一个输入后,第一个隐藏节点可能进入正半轴,从而获得非零梯度。

可以用新参数再次前向传播,检查这一步是否确实改善了当前样本。新的第二个隐藏节点预激活值约为:

0.9581×1+0.4162×2-1.0419≈0.7486

经过 ReLU 后仍约为 0.7486。新的输出 logit 约为:

z_2^(new) =(-0.6401)×0.7486+0.3599 ≈-0.1193

所以新预测约为:

y-hat_(new)=σ(-0.1193)≈0.4702

新损失约为:

L_(new)=-ln(0.4702)≈0.755

预测从 0.4013 向真实标签 1 的方向上升到约 0.4702,损失从约 0.913 降到约 0.755。这验证了当前这一步更新对这个样本有效。不过,梯度下降只在局部和足够小的步长下提供下降依据;实际小批量训练中,某一步也不保证让每个单独样本的损失都下降,优化的是批次或总体目标。

这次更新还揭示了“学习”的真正含义。网络没有把“输入 [1,2] 的答案是 1”完整存进某个节点,也没有由某一条连接独自承担学习。输出权重、输出偏置、第二个隐藏节点的输入权重和偏置都发生了彼此关联的小变化。它们共同改变了隐藏表示和最终输出,使当前目标的损失降低。

一次更新产生的变化通常很小,而且它只利用一个样本或一个小批次提供的局部信息。训练通过成千上万个 step 重复“前向—损失—反向—更新”,让不同样本不断对参数施加影响。最终形成的参数是许多训练信号共同作用的结果,网络的内部表示也在这些协同更新中逐渐变得对任务有用。

这一节可以概括为:前向传播用当前参数算出预测和损失;反向传播从输出误差开始,通过链式法则得到每层参数的梯度;优化器再沿负梯度更新参数。学习不是把答案塞进某个节点,而是让整张网络中参与当前计算的参数发生协同微调,并通过大量重复逐渐降低总体损失。

10训练为什么会失败工程

理解前向传播、损失、反向传播和参数更新,并不意味着实际训练一定成功。数学公式描述了训练应该怎样进行,工程实践还要保证数据正确、数值稳定、梯度能够传播,而且模型没有只记住训练样本。“训练失败”不是单一问题:有时参数根本学不动,有时数值发散,有时程序切断了梯度,还有时训练集表现很好却无法推广。诊断的第一步,是先判断失败属于哪一种。

梯度消失发生在较早层收到的梯度变得极小。反向传播使用链式法则,早期参数的梯度通常包含许多层局部导数的乘积。当反向传播沿相关方向经过各层时持续受到压缩,传到早期层的梯度可能很小。用标量乘积作直观说明,就是多个幅度小于 1 的因子连续相乘;真实网络还要考虑矩阵与多条路径的共同作用。此时输出附近的层仍能更新,而靠近输入的层几乎不动,网络难以学到有效的底层表示。

Sigmoid 和 tanh 在饱和区域的导数很小,因此深层网络若大量使用这些激活,更容易出现梯度消失。ReLU 或 GELU 在合适工作区间通常能改善梯度传播,但它们也不是单独的万能解。合理初始化、归一化和残差连接会从不同角度控制信号尺度或缩短梯度传播路径,从而让深层网络更容易训练。

梯度爆炸是相反现象:链式乘积中的因子或权重尺度过大,使梯度在向前层传播时迅速增长。参数更新可能突然变得非常大,损失剧烈震荡,甚至出现无穷大或 NaN。降低学习率可以减小每次更新幅度;梯度裁剪可以在梯度范数超过阈值时限制其大小;合理初始化与归一化则尽量从源头避免激活和梯度尺度逐层放大。

现象根因常见应对
梯度消失深层链式传播沿相关方向持续缩小梯度幅度(标量直观例子:多个绝对值小于 1 的因子连乘)ReLU/GELU、残差连接、合适初始化与归一化
梯度爆炸连乘与权重尺度过大降学习率、梯度裁剪、归一化、合理初始化
死亡 ReLU节点长期落在负半轴,输出和梯度都为 0降学习率、Leaky ReLU、检查初始化
训练损失不降数据/标签错、学习率不当、梯度断裂先用极小数据集故意过拟合,逐层查数值与梯度
训练好、验证差记住了训练细节,没学到可泛化规律更多数据、正则化、早停、减小模型(见第 11 节)

需要注意,梯度裁剪更像安全护栏。它可以阻止极端梯度直接破坏训练,却不一定消除导致爆炸的根因。如果训练反复触发裁剪,仍应检查学习率、初始化、数据异常、损失实现以及网络结构,而不是只把裁剪阈值不断调小。

死亡 ReLU 指某个 ReLU 节点长期处于负半轴。因为:

ReLU(z)=0 (z<0)

并且该区域的导数为零,所以这个节点既不向后输出信号,也无法通过当前样本获得传向其输入参数的梯度。如果一次过大的更新把许多节点推入长期负区间,或初始化让它们一开始就很难激活,网络的有效容量会下降。

降低学习率可以减少参数被一次更新推得过远的风险;合理初始化能让初始预激活值分布在较可用的范围;Leaky ReLU 在负半轴保留小梯度,使节点仍有机会恢复。但某个节点偶尔输出零并不等于死亡 ReLU。ReLU 本来就设计成允许部分输入关闭节点,只有节点对几乎所有相关数据长期不激活时,才构成值得处理的问题。

另一类常见现象是训练损失从一开始就不下降。原因可能非常基础:输入与标签错位、标签编码错误、预处理不一致、损失函数与输出层不匹配、参数没有交给优化器、忘记执行更新、在错误位置关闭了梯度,或参数实际上被冻结。也可能是学习率太小导致变化难以观察,或太大导致每一步都越过有效区域。

排查这种问题时,一个非常有效的方法是让模型故意过拟合一个极小数据集,例如只取几个样本并训练很多步。一个容量足够的网络通常应该能够把这几个样本的训练损失压得很低。如果连极小数据集都无法拟合,问题更可能出在实现、数据管线、损失配置或优化过程,而不是“泛化不够”。

极小数据集测试失败后,可以沿训练链逐段检查:输入数值和标签是否正确;前向输出的范围与形状是否符合预期;损失是否为有限数且会随预测变化;每个参数是否需要梯度;反向传播后梯度是否存在、是否全零或异常巨大;优化器更新后参数是否真的变化。把复杂训练拆成这些可观察环节,比盲目更换模型或优化器更有效。

还有一种情况是训练损失正常下降、训练指标很好,但验证表现明显较差。这通常不是“网络不会学习”,而是网络学得过于贴合训练集,包括其中的偶然噪声和细节,形成过拟合。此时继续降低训练损失可能让验证表现进一步恶化。

缓解过拟合可以从信息和容量两侧入手。更多且更有代表性的数据能帮助模型区分稳定规律与偶然细节;数据增强可在合理假设下产生更多变化;权重衰减、Dropout 等正则化方法限制模型过度依赖特定参数或路径;早停在验证表现不再改善时停止训练;减小模型则直接降低可用容量。应对方法取决于任务,不能把“训练集与验证集有差距”一律归咎于模型太大,还要检查训练和验证的数据分布、预处理及评价流程是否一致。

初始化是训练稳定性的起点。同层隐藏节点的入向权重和偏置相同,只能保证它们面对相同输入时具有相同的前向响应。若对应的下游连接、优化器状态及更新规则也保持节点置换对称,即交换这些节点不改变相关计算与更新,那么它们会得到相同梯度,并在后续更新中保持重复,难以分工学习不同模式。仅有相同的入向参数并不足够:例如输入为 1,两个 ReLU 节点的入向权重都为 1、偏置都为 0,但线性输出连接权重分别为 1 和 2,输出就是 3。目标为 0、损失为输出平方的一半时,两节点入向权重的梯度分别为 3 和 6,普通梯度下降会让它们分开。随机初始化权重是打破对称的常见方法;在权重已适当初始化时,偏置通常可以设为零。全部权重设为零则可能保持对称或阻断梯度,不能把它当成通用初始化方案。

但随机并不表示随便选择任意尺度。如果初始权重过小,信号和梯度可能逐层缩小;如果过大,激活可能饱和或数值逐层放大。Xavier 或 Glorot 初始化根据输入和输出宽度控制权重方差,常与 tanh 等激活配合;He 初始化主要根据输入宽度调整尺度,常与 ReLU 类激活配合。它们的共同目标是让前向激活和反向梯度在跨层传播时不过快放大或缩小。

归一化方法也在控制中间数值,但具体方式不同。批归一化利用一个批次内的统计量对中间激活进行标准化,再通过可学习参数恢复合适尺度;它常见于卷积网络,但行为会受到批大小和训练、推理模式切换的影响。层归一化在单个样本的特征维度上进行归一化,不依赖同一批次的其他样本,因此在 Transformer 中非常常见。

归一化不只是把数字变得“好看”。它能让不同层面对更稳定的数值范围,使优化对参数尺度和学习率不那么敏感,并帮助深层模型训练。但归一化位置、维度和训练模式必须实现正确。例如,批归一化在训练时使用批次统计量,在推理时通常使用累积统计量;如果模式切换错误,验证结果可能异常。

残差连接把某个变换写成:

y=x+F(x)

而不是要求这一组层直接从头学出完整映射 y=F(x)。这样,变换分支可以学习“在输入基础上需要增加什么修正”。如果最佳操作接近保持原样,令残差分支接近零就比较容易。更重要的是,加法提供了一条较直接的信号和梯度路径,使梯度不必完全依赖深层变换中所有局部导数的连乘。

残差连接不会消除所有优化问题,也不能保证任意深度都有效,但它显著改变了深层网络的可训练性。归一化、残差连接、合适初始化、激活函数选择和梯度裁剪都不是“神经网络必须拥有才算神经网络”的定义性部件;一个简单网络没有它们也能计算和学习。它们属于工程结构:面对更深、更大、更难优化的模型时,帮助理论上的可训练性变成现实中的稳定训练。

诊断时还要区分症状和根因。损失出现 NaN 可能来自梯度爆炸,也可能来自对零取对数、除以零、无效数据或精度溢出;梯度为零可能来自饱和激活,也可能因为参数被冻结或计算图被意外切断;验证差可能是过拟合,也可能是验证数据处理与训练不一致。不能只根据一个表面现象立刻套用固定答案,而应通过数值、梯度、参数变化和数据样本逐层验证。

一套实用排查顺序是:先人工检查少量输入和标签;再确认简单基线与评价逻辑;让模型过拟合极小数据集;观察各层激活、损失和梯度是否有限且尺度合理;确认更新前后参数确实变化;最后才系统调整学习率、初始化、归一化、正则化和模型容量。先排除正确性问题,再处理稳定性和泛化问题,可以避免在错误代码上反复调参。

这一节的核心认识是:训练成功不仅要求网络具有表达能力和可计算的梯度,还要求梯度在深层结构中保持可用、参数打破对称、数值尺度稳定、数据与实现正确,并且模型学到可推广的规律。初始化、归一化和残差连接是让深层网络更容易优化的工程工具,而训练集与验证集的差异则提醒我们:能够拟合和能够泛化是两件事。

11泛化:训练集好还不够直觉工程

模型在训练集上表现很好,只能说明它成功适应了已经见过的数据;真正部署以后,面对的却通常是训练时没有见过的新样本。泛化就是模型把训练数据中学到的规律正确应用到新数据上的能力。这不是训练完成后的附加要求,而是监督学习真正想实现的目标。

神经网络通常拥有大量参数,因此既可能学习稳定规律,也可能记住训练集中的偶然细节。假设训练图片里的猫大多出现在沙发上,而狗大多出现在草地上,网络可能利用背景颜色进行分类,而不是学习动物本身的特征。它在训练集上仍可能取得很高准确率,但遇到草地上的猫时就容易失败。这种情况说明低训练误差并不能自动证明模型学到了我们希望的规律。

过拟合就是模型过度适应训练数据,包括噪声、偶然相关性和样本特有细节,以至于在新数据上表现变差。欠拟合则是模型连训练数据中的主要规律都没有掌握,训练和验证表现都较差。两者的处理方向往往不同:过拟合通常需要更多有效数据、更强约束或更小容量;欠拟合则可能需要更合适的特征、更大模型、更长训练或更有效的优化。

为了观察泛化,数据通常分成训练集、验证集和测试集。训练集直接参与梯度更新,模型参数通过它学习。验证集不用于更新权重,而用于比较架构、学习率、正则化强度、训练轮数和决策阈值等选择。测试集应尽量留到所有设计选择完成后,只用于估计最终方案对未见数据的表现。

早停点 训练损失 验证损失 训练时间 →
图 5 训练损失一路降,不代表模型一路变好。当验证损失开始回升,模型已经在「背」而非「学」——那一刻正是该早停的地方。

三者的分工可以概括为:训练集用来学习参数,验证集用来选择方案,测试集用来进行最终评价。虽然验证集不直接参与反向传播,但反复根据验证结果修改模型,实际上已经让设计过程逐渐适应验证集。因此,不能在看过测试结果后继续不断调参,再把同一个测试结果声称为完全独立的泛化估计。

数据划分必须符合真实部署方式。若同一个人的多条记录随机散落在训练集和测试集,模型可能通过个体特征间接认出测试样本;时间序列若随机打乱划分,训练数据可能包含测试时点之后的信息;同一原始图片的不同裁剪版本若进入不同集合,也会造成近重复泄漏。这些情况会让测试指标看起来很好,却高估实际泛化能力。

训练过程中经常出现这样的曲线:训练损失持续下降,验证损失先下降后上升。早期阶段,模型学习训练集与验证集共有的规律,所以二者都改善;继续训练后,模型越来越贴合训练集的细节,训练损失仍下降,但验证损失开始恶化。验证损失最低附近通常是一个合适的早停位置。

早停不是看到一次验证波动就立即终止。验证指标本身可能有噪声,实践中常设置一定耐心值:只有连续若干次评估都没有改善才停止。同时应保存验证表现最佳时的模型检查点,而不是直接使用最后一步参数。否则即使正确检测到后期过拟合,最终保留的仍可能是已经退化的模型。

L2 正则化通过在原始训练损失之外加入权重平方惩罚来约束模型:

L_(total)=L_(data)+lambdaΣ_j w_j^2

其中 L_(data) 衡量预测错误,第二项惩罚较大的权重,lambda 控制约束强度。它倾向于让模型使用较分散、较小的权重,而不是极度依赖少数连接。直觉上,这常使函数对输入变化不那么敏感,从而减少对训练样本细节的过度贴合。

权重衰减在许多优化器中以直接缩小权重的形式实现,与 L2 正则化关系密切。在普通梯度下降中二者可以对应,但在 Adam 等自适应优化器中,解耦权重衰减与把 L2 项直接加入损失并不总是完全等价。对初学者最重要的认识是:它们都试图限制权重无约束增长,但具体实现应遵循所用优化器和框架的定义。

正则化强度也需要平衡。lambda 太小可能无法抑制过拟合;太大则会把有用权重也压得过小,使模型连训练规律都表达不了,形成欠拟合。因此,正则化强度属于需要根据验证集选择的超参数。

Dropout 在训练时随机把一部分节点输出置零,使网络每一步都不能完全依赖同一组内部路径。某些节点可能在这一批被屏蔽,下一批又恢复,迫使其他节点也承担信息表达,减少多个特征之间脆弱的固定共适应。它可以近似理解为训练许多共享参数的子网络,并在推理时汇总成一个完整网络。

Dropout 在训练和推理阶段行为不同。训练时随机屏蔽,推理时应关闭随机屏蔽,使用全部节点,并按所采用的实现处理尺度。现代框架通常使用“反向 Dropout”:训练时对保留的输出自动放大,使其期望尺度与推理阶段一致;推理时直接关闭 Dropout 即可。如果忘记切换到推理模式,预测会继续随机变化,结果通常不可靠。

数据增强不是直接限制参数,而是通过生成符合任务不变性的合理变化扩大有效训练分布。例如,图像分类中可能使用轻微裁剪、翻转或颜色扰动,让模型不能只记住固定像素位置。语音可加入符合场景的噪声,文本任务则可能采用经过谨慎设计的改写。

数据增强是否正确,取决于变化后标签是否仍然成立。水平翻转普通物体图片可能合理,但翻转交通标志、文字或具有左右语义的医学图像可能改变含义;任意旋转数字 6 可能接近数字 9。错误增强会向模型提供相互矛盾的训练信号。因此,增强策略必须来自真实任务的不变性,不能只因为某种方法常见就直接套用。

方法作用机制注意
L2 / 权重衰减惩罚过大的权重,偏向更平滑的解太强会欠拟合
Dropout训练时随机屏蔽部分节点,减少共适应推理时关闭并处理缩放
早停验证损失开始变差就停要保存最佳验证检查点
数据增强制造保持标签不变的合理变化增强要符合真实任务不变性
减小模型直接降低容量可能牺牲表达能力

减小模型是最直接的容量控制。减少层数或节点数,通常可以减少参数和计算量;在适合任务的结构中共享参数,也可以减少独立参数数量和存储需求。这些调整会改变模型的表达能力,但并不保证泛化更好。但容量过小会导致欠拟合。更大的模型也并非必然泛化更差;在数据、优化和正则化合适时,大模型可能找到良好解。模型规模应与任务难度、数据数量和部署预算共同决定。

这些方法针对过拟合的角度不同:L2 或权重衰减约束参数规模;Dropout 扰动内部路径,减少共适应;早停限制模型适应训练集的时间;数据增强扩大合理变化范围;减小模型直接降低容量。它们可以组合使用,但更多方法不等于自动更好。约束叠加过强可能让模型无法充分学习。

泛化问题也不能只看训练损失和验证损失的差距。如果训练集与验证集来自不同分布,验证差可能反映分布偏移,而非普通过拟合;如果标签质量差,模型可能受到错误监督;如果类别严重不平衡,只看总体准确率可能掩盖少数类失败。因此,评价泛化需要选择符合任务代价的指标,并检查不同数据切片上的表现。

“在测试集上表现好”也只是在测试集能够代表未来数据的前提下,提供泛化证据。部署环境会随时间变化,输入设备、用户行为、语言表达或业务规则都可能发生改变。真实系统还需要监控数据漂移、性能变化和错误类型,而不能把一次离线测试看成永久保证。

这一节的核心逻辑是:训练的目标不是把训练集记到极致,而是从有限样本中提取能用于新数据的稳定规律。训练集负责学习参数,验证集负责选择方案,测试集负责最终评估;早停、权重衰减、Dropout、数据增强和容量控制从不同方向抑制过拟合,但可靠泛化还依赖无泄漏的数据划分、合适的评价指标以及测试数据对真实环境的代表性。

12把整条因果链连起来综合

前面各节分别解释了神经网络的部件与训练机制,但真正理解它,需要看清这些概念并不是彼此独立的术语。每一个环节都在解决上一环节留下的问题,并为下一环节提供条件。整条链从现实对象的数字表示开始,经过表达、预测、误差度量和参数优化,最终必须在未见数据上接受检验。

第一步是把现实对象表示为数字输入 x。图片可以表示为像素数组,声音可以表示为采样值或频谱,文本可以转换成词元及向量,表格对象则由多个数值和类别特征组成。网络不能直接处理“猫”“一句话”或“信用风险”这些抽象对象,它只能对数字执行运算。因此,输入表示决定了模型能够接触到哪些信息,也限定了它可能学到什么。

如果输入表示遗漏关键信息,后面的网络无法凭空恢复。例如,只保留图片平均亮度却要求识别形状,任务所需信息已经丢失。反过来,如果训练输入包含部署时不存在的信息,模型可能得到虚假的高分。这说明数据表示和数据管线不是网络外部的杂务,而是整条学习链的起点。

有了输入以后,最简单的方法是做一次加权求和:

y'=w· x+b

它能根据不同特征的重要性形成预测,但只能表达线性或仿射关系。在分类问题中,这意味着决策边界是直线、平面或高维超平面。面对圆环式边界、图像结构、语言关系等复杂规律,一个线性模型通常不够,因此需要自动构造更有用的中间特征。

神经网络用许多节点并行完成这种构造。每个节点计算加权和与激活:

z=w· x+b, a=φ(z)

权重决定节点关心输入中的哪些方向,偏置调整触发条件,激活函数决定响应怎样传递。一个节点只能提供一种有限响应,许多节点则能同时形成多个特征方向;它们的输出拼成新向量,成为下一层的输入。

只有节点和层还不够。如果每层都只进行仿射变换,多层仍可合并成一层,深度不会增加函数类型。层间激活函数打破这种线性坍缩。以 ReLU 为例,不同节点在不同区域激活,使网络形成许多斜率不同的局部片段;经过多层组合,这些片段可以构造复杂的非线性映射。

因此,隐藏层的工作可以概括为表示学习。每一层都把上一层信息重新编码到一个对最终任务更有用的坐标系统中。早期层未必真的对应人类可命名的概念,但只要这些表示能帮助后续层降低任务误差,它们就具有训练价值。深度提供多级函数复合,宽度允许同一级并行检测更多模式。

在参数确定的情况下,前向传播沿网络结构从输入计算到输出:

x → z^((1)) → a^((1)) → … → z^((L)) → y-hat

隐藏层逐步形成内部表示,输出层再把最后的内部数值翻译成任务需要的答案。回归可能直接输出实数,二分类可能通过 Sigmoid 输出一个 0 到 1 的值,互斥多分类可能通过 Softmax 形成类别分布,多标签任务则可能为每个标签使用独立 Sigmoid。

到这里,网络只能给出答案,还不会判断答案是否正确。损失函数把预测 y-hat 与真实目标 y 的差异转换为一个标量 L。回归可使用均方误差,分类常使用交叉熵。这个标量既让不同参数状态可以比较,也为求导提供明确目标。没有损失函数,“变得更好”就没有可供优化器执行的数学定义。

但损失只有一个数,网络参数却可能有很多。反向传播使用链式法则,从损失开始向前面的层传递敏感度,求出:

∇_θ L

梯度的每个分量说明对应参数略微变化时,损失在当前位置附近如何变化。反向传播复用共同的下游影响,一次反向遍历便能高效得到全部参数的梯度。它负责计算梯度,不负责真正修改参数。

优化器读取梯度并更新参数。最基本的梯度下降为:

θ←θ-η∇_θ L

梯度指向局部最快上升方向,负梯度给出局部最快下降方向,学习率 η 控制步长。Adam 等优化器会进一步利用历史梯度和尺度信息,但它们仍然依赖反向传播提供的梯度。

一次训练 step 因而形成一个内部循环:

取一批数据→ 前向传播→ 计算损失→ 反向传播→ 更新参数

更新后的参数会改变下一次前向传播;新的预测产生新的损失;新的损失产生新的梯度。成千上万个小批次反复经过这个循环,隐藏层表示和输出行为共同变化,训练损失通常逐步下降。这就是网络“学习”的直接机制。

训练循环还依赖工程条件。随机初始化打破节点对称;合适的权重尺度、激活函数和归一化帮助信号稳定传播;残差连接为深层网络提供更直接的路径;梯度裁剪可限制极端更新。如果数据错误、梯度断裂、学习率不当或数值溢出,即使理论链条正确,实际训练仍可能失败。

然而,训练损失下降只证明优化器找到了更适合训练数据的参数。由于网络容量很大,它可能同时学到稳定规律、偶然相关性、标签噪声,甚至直接记住样本。仅凭训练集无法判断这些成分中哪些能够用于未来数据。

因此,验证集必须位于闭环的末端。训练集提供参数更新信号,验证集不参与梯度更新,而是检查当前模型在未用于训练的数据上是否也改善。如果训练损失下降且验证损失也下降,说明当前学习至少具有一定迁移价值;如果训练继续改善而验证恶化,则可能正在过拟合,应考虑早停、正则化、数据增强、容量调整或重新检查数据分布。

测试集则在架构、超参数和训练策略确定以后,对最终方案进行更独立的评估。验证集用于开发选择,测试集用于最终估计。若反复查看测试结果并据此修改模型,测试集也会逐渐参与选择,失去原本的独立性。

整条因果链可以写成:

  1. 现实对象
  2. 数字输入
  3. 多层非线性表示
  4. 任务输出
  5. 损失
  6. 梯度
  7. 参数更新
  8. 未见数据检验

这条链也提供了一套排错顺序。如果模型失败,可以沿相反方向追问:评价数据是否代表真实任务?训练与验证是否分布一致且没有泄漏?损失是否与输出含义匹配?梯度是否存在且尺度合理?参数是否实际更新?激活和输入是否保留有效信息?问题可能发生在任何一环,不能一看到结果差就直接归咎于网络结构。

不同成功层次也应分开判断。网络结构能够表示目标关系,说明表达能力可能足够;训练损失能下降,说明优化链至少在工作;验证表现良好,才提供泛化证据;部署后持续有效,还要求真实环境与离线数据足够一致,并进行持续监控。这些层次逐级增加,前一层成功不能替代后一层检验。

所以,到“训练损失变小”为止,闭环仍不完整。真正目标从来不是让模型在已知题目上得高分,而是让它从已知样本中形成对未知样本有用的映射。神经网络的完整逻辑是:用多层非线性函数获得表达能力,用损失和反向传播获得可训练性,用优化器从数据中形成参数,最后用未见数据判断学到的是可泛化规律,还是对训练样本的记忆。

13概念依赖与延伸学习路线

神经网络涉及的术语很多,如果按照流行程度随意跳着学习,很容易知道许多名字,却无法解释它们之间的因果关系。更稳固的路线是把知识分成依赖层级:先掌握网络所使用的数学与机器学习语言,再理解核心计算闭环,然后深入训练工程,扩展到具体架构,最后处理可信与部署问题。

第一层是先修知识。特征与标签决定监督学习问题怎样表述:特征 x 是模型能够看到的输入信息,标签 y 是训练阶段希望模型预测的目标。理解这一区分,才能看懂网络为什么从 x 计算 y-hat,又为什么需要用 y 计算损失。

线性回归是理解加权和与连续值预测的起点:

y-hat=w· x+b

逻辑回归则进一步展示如何把线性分数经过 Sigmoid 转换成二分类输出,以及如何与交叉熵建立训练目标。神经网络可以看成在这种简单模型之前加入多层可学习的非线性表示,因此,如果线性模型和逻辑回归尚不清楚,隐藏层的意义也容易变成纯粹记忆。

学习层级涉及概念
先修特征、标签、线性回归、逻辑回归、向量与矩阵、导数
本页核心节点、权重、偏置、隐藏层、激活函数、损失、前向传播、反向传播、梯度下降
训练深化初始化、mini-batch、Adam、学习率调度、归一化、正则化、过拟合
架构延伸卷积神经网络、循环神经网络、注意力、Transformer、残差网络
可信与部署可解释性、校准、分布偏移、鲁棒性、推理延迟、模型压缩

向量和矩阵是描述整层并行计算的语言。无需一开始掌握所有线性代数理论,但至少应理解向量表示一组特征,矩阵的每一行可以表示一个节点的权重,矩阵乘法 Wx 同时完成许多节点的加权和,并能检查输入、权重与输出的形状是否匹配。

导数和偏导数是理解训练的基础。导数描述一个量轻微变化时另一个量如何变化;偏导数把这种思想用于多参数函数;梯度则把所有参数的偏导数组成向量。还需要理解链式法则,因为早期权重并不直接影响损失,它要通过预激活、激活、后续层和预测逐步产生影响。

第二层是本页的核心闭环。节点使用权重和偏置形成预激活值:

z=Wx+b

激活函数把它转换成非线性表示:

a=φ(z)

许多节点组成隐藏层,多个隐藏层形成函数复合。前向传播沿这些函数从输入计算到输出,输出层根据任务把内部数值转换成预测,损失函数把预测错误转换成标量。反向传播再利用链式法则计算全部参数梯度,优化器根据梯度更新权重和偏置。

这一核心层不应被学成八个互不相干的定义。应当能够解释每个概念为什么出现:权重用于组合输入,偏置用于平移响应门槛,多个节点用于并行形成不同响应,激活函数防止多层坍缩成单层,损失给出可优化目标,反向传播高效计算责任,梯度下降根据局部坡度调整参数。

第三层是训练深化。初始化不仅给参数一个起点,还要打破节点之间的对称,并控制前向信号和反向梯度的尺度。Xavier 和 He 初始化分别针对不同激活与层宽设计合理方差。理解初始化后,才能解释全零权重可能带来的节点对称或梯度受阻风险:只有相关权重、偏置、下游连接、优化器状态及更新规则都保持节点间的对称性时,这些节点才会持续给出相同响应并接受相同更新。仅凭全部权重为零,不能断言节点永久学习相同内容;过大或过小初值也可能导致数值问题。

mini-batch 训练是在完整数据梯度与单样本随机梯度之间折中。一次只用一小批样本,可以利用硬件并行,又能频繁更新参数。batch size 会影响梯度噪声、显存占用和训练速度,因此它不仅是数据读取设置,也是优化超参数。

Adam、动量和学习率调度是在基本梯度下降上的进一步发展。动量累积历史方向,帮助减少狭长谷地中的来回震荡;Adam 根据梯度统计为不同参数调整有效步长;学习率调度则让训练早期迈较大步探索,后期用较小步细化。学习这些方法时,应始终保留共同主线:反向传播提供梯度,优化器决定如何使用梯度。

归一化、正则化和过拟合构成训练稳定性与泛化的另一组知识。批归一化或层归一化控制中间数值尺度;权重衰减、Dropout、数据增强和早停限制模型过度适应训练细节;训练、验证和测试划分用于区分参数学习、方案选择和最终评价。它们回答的不再只是“损失能否下降”,而是“训练是否稳定,以及下降是否能迁移到未见数据”。

第四层是架构延伸。卷积神经网络利用局部连接和参数共享处理具有空间结构的数据,例如图像。它仍然执行线性运算、激活、损失和反向传播,只是把全连接矩阵替换成更符合空间结构的卷积操作。

循环神经网络为序列保留随时间传递的隐藏状态,让早期输入能够影响后续输出,但也带来长路径上的梯度问题。注意力机制则让不同位置可以根据内容直接建立加权联系,减少信息必须逐步穿过整个序列的限制。Transformer 以注意力、前馈网络、残差连接和层归一化等组件构成深层架构。

残差网络重点解决深层模型难以优化的问题,通过:

y=x+F(x)

让若干层学习对输入的修正,并给信号和梯度提供更直接路径。这些架构看起来各不相同,但没有脱离本页原理:它们仍是参数化函数的复合,仍通过前向传播产生预测,通过损失定义目标,通过反向传播和优化器学习参数。

因此,学习新架构时最有效的问题不是“它有哪些模块”,而是:它对输入施加了什么结构假设;信息如何在模块间流动;参数在哪里共享;非线性在哪里产生;输出与损失如何定义;梯度通过哪些路径传播;它解决了普通全连接网络的什么限制。

第五层是可信与部署。可解释性研究模型为何作出某个判断,但内部激活与人类概念不天然一一对应,因此解释方法本身也需要验证。校准关心模型给出的置信度是否与真实正确率相符;一个准确率不错的模型仍可能过度自信,影响风险决策和阈值选择。

分布偏移发生在部署输入与训练数据不再同分布时,例如用户群体、设备、时间或业务规则变化。鲁棒性关心模型面对噪声、扰动、缺失信息或对抗输入时是否稳定。这些问题提醒我们:测试集表现只在测试数据代表未来环境时有效。

推理延迟、吞吐量、内存、能耗和模型大小则决定模型能否真正使用。模型压缩可以包括量化、剪枝、蒸馏或结构改造,但压缩后的模型仍需重新验证准确率、校准和不同数据切片上的表现。一个离线指标优秀、却无法在目标设备和时限内运行的模型,并不是完整的工程方案。

这条路线不是要求学完上一层的所有细节,才能接触下一层,而是说明遇到困难时应回到哪一层补基础。看不懂卷积和注意力的张量计算,可以回到向量、矩阵和形状;不理解优化器差异,可以回到梯度与学习率;不理解深层训练问题,可以回到链式法则;模型离线很好但线上失败,则要检查数据分布、校准与部署约束。

真正的核心过关标准可以用一次完整推导检查。给定:

z=Wx+b

应当能够说明权重和偏置的作用,计算激活 a=φ(z),把多层结果前向传播到输出 y-hat,根据任务选择损失 L(y-hat,y),用链式法则解释 ∂ L/∂ W 怎样得到,再写出参数更新:

W← W-η((∂ L) / (∂ W)), b← b-η((∂ L) / (∂ b))

同时,还应能解释为什么没有非线性时多层仍等价于一层,为什么梯度只提供局部方向,为什么训练损失下降不等于泛化成功。如果这些内容能够依靠因果关系自然讲清,而不是逐句背诵,就已经跨过神经网络的原理门槛。

这一节最终给出的不是一张必须机械执行的课程表,而是一棵依赖树:线性模型、矩阵和导数提供语言;节点、激活、损失、反向传播和梯度下降形成核心闭环;初始化、优化器、归一化和正则化让闭环稳定工作;卷积、循环、注意力、Transformer 与残差网络把同一原理组织成适合不同结构的架构;可解释性、校准、分布偏移和部署约束则决定训练好的模型能否被可靠使用。

资料来源与改编说明 本文为 AI 知识地图的原创中文教学页,结构与部分教学要点参考 Google Machine Learning Crash Course(内容除另有说明外采用 CC BY 4.0),并作了重新组织、扩写、手算推导与原创制图;未复制其交互组件。
访问日期:2026-07-20