在如今的 AI 时代,当你打开购物 APP 收到精准的商品推荐、用手机相机识别植物种类、或通过语音助手生成会议纪要时,背后都离不开两大核心技术的支撑 ------人工神经网络 (构建智能的 "骨架")与梯度算法(赋予智能 "学习" 的能力)。对于深度学习初学者而言,神经网络的分层结构看似复杂,梯度算法的数学推导也常令人却步,但只要从 "原理 - 组件 - 实战" 的逻辑逐步拆解,就能掌握其核心本质。本文将以通俗语言 + 严谨推导 + 实战案例的形式,全面解析神经网络的定义、核心组件及梯度算法的工作机制,全文篇幅超 5000 字,兼顾理论深度与工程实用性。
一、神经网络的定义:从生物灵感到人工构造
要理解 "人工神经网络",首先需要回到其灵感源头 ------ 生物神经网络。只有明确了大脑如何处理信息,才能真正明白人工模型的设计逻辑。
1.1 生物神经网络:智能的天然原型
人类大脑是一个由约860 亿个神经元 (Neuron)构成的复杂网络,每个神经元通过突触(Synapse)与数千个其他神经元连接,形成一张可动态调整的信号传递网络。单个生物神经元的工作流程,堪称自然界最精密的 "信息处理器",具体可分为四步:
- 信号接收:神经元的 "树突"(Dendrite)如同树枝般延伸,接收来自其他神经元通过突触传递的化学信号(如神经递质)或电信号。例如,当你看到苹果时,视网膜的感光细胞会将光信号转化为电信号,传递给视觉皮层的神经元树突。
- 信号整合:所有输入信号被传递到神经元的 "细胞体"(Soma),细胞体会对这些信号进行 "加权求和"------ 重要的信号(如危险信号)会被赋予更高权重,无关的背景噪音则权重极低。
- 激活判断:若整合后的信号强度超过某个 "阈值",神经元会被激活,产生电脉冲;若未达阈值,则不产生任何信号。比如,当 "苹果的红色 + 圆形" 信号强度足够时,视觉神经元才会激活,识别出 "这是苹果"。
- 信号传递:激活后的电脉冲通过 "轴突"(Axon)传递到末端,再通过突触传递给下一个神经元,完成一次信息传递。整个过程在 0.1 秒内完成,数百万个神经元协同工作,就能实现复杂的认知活动(如思考、决策)。
正是这种 "分层传递、加权整合、阈值激活" 的机制,让大脑能高效处理复杂信息。而人工神经网络,就是对这一自然机制的数学简化与工程实现。
1.2 人工神经网络的基础:感知机(Perceptron)
1957 年,心理学家 Frank Rosenblatt 提出的感知机(Perceptron),是第一个可训练的人工神经网络模型,标志着神经网络领域的诞生。它的设计完全对标生物神经元,结构简洁却蕴含了神经网络的核心逻辑。
1.2.1 感知机的核心结构
感知机模拟单个生物神经元,仅包含 4 个关键组件,各组件与生物神经元的对应关系如下表所示:
感知机组件 | 对应生物神经元结构 | 功能描述 |
---|---|---|
输入层(Input) | 树突 | 接收外部输入的特征值(如判断 "是否下雨" 的特征:湿度、云量、风速),用\(x_1,x_2,...,x_n\)表示 |
权重(Weight) | 突触连接强度 | 每个输入\(x_i\)对应一个权重\(w_i\),权重越大,该输入对输出的影响越显著 |
偏置(Bias) | 激活阈值 | 额外的常数参数b,调整神经元的激活难度(偏置越大,神经元越难被激活) |
激活函数(Activation) | 细胞体信号整合 | 对 "输入加权和 + 偏置" 的结果进行转换,输出最终结果(如 "激活输出 1,未激活输出 0") |
1.2.2 感知机的计算过程(数学拆解)
感知机的核心是 "加权求和→激活转换" 的两步计算,用数学公式可清晰表达:
-
第一步:计算净输入(加权和 + 偏置) 先将每个输入与对应的权重相乘,再加上偏置,得到 "净输入"z,代表神经元接收的总信号强度:\(z = w_1x_1 + w_2x_2 + ... + w_nx_n + b\) 为了简化表达,可使用向量点积形式(适用于高维输入):\(z = \boldsymbol{w} \cdot \boldsymbol{x} + b\) 其中\(\boldsymbol{w} = [w_1,w_2,...,w_n]\)是权重向量,\(\boldsymbol{x} = [x_1,x_2,...,x_n]\)是输入向量,"\(\cdot\)" 表示向量点积(对应元素相乘后求和)。
-
第二步:激活函数转换 净输入z经过激活函数\(f(\cdot)\)转换,得到感知机的输出y。感知机最常用的激活函数是阶跃函数(Step Function),模拟生物神经元 "非激活即抑制" 的特性:\(f(z) = \begin{cases} 1 & \text{if } z \geq 0 \quad (\text{神经元激活}) \\ 0 & \text{if } z < 0 \quad (\text{神经元抑制}) \end{cases}\)
1.2.3 感知机的实战:实现逻辑运算
感知机的强大之处在于 "可训练"------ 通过调整权重和偏置,它能拟合简单的逻辑关系。我们以 "逻辑与(AND)" 和 "逻辑或(OR)" 为例,直观感受感知机的工作原理。
案例 1:实现 "逻辑与(AND)" AND 运算的规则是:仅当两个输入\(x_1,x_2\)均为 1 时,输出\(y=1\);否则输出\(y=0\),其真值表如下:
输入\(x_1\) | 输入\(x_2\) | 目标输出y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
我们需要找到一组权重\(w_1,w_2\)和偏置b满足上述规则。经过调试,可选择参数:\(w_1=0.5, w_2=0.5, b=-0.8\),验证过程如下:
- 当\(x_1=0,x_2=0\):\(z=0.5×0 + 0.5×0 - 0.8 = -0.8 < 0\) → \(y=0\)(符合规则);
- 当\(x_1=0,x_2=1\):\(z=0.5×0 + 0.5×1 - 0.8 = -0.3 < 0\) → \(y=0\)(符合规则);
- 当\(x_1=1,x_2=0\):\(z=0.5×1 + 0.5×0 - 0.8 = -0.3 < 0\) → \(y=0\)(符合规则);
- 当\(x_1=1,x_2=1\):\(z=0.5×1 + 0.5×1 - 0.8 = 0.2 ≥ 0\) → \(y=1\)(符合规则)。
案例 2:实现 "逻辑或(OR)" OR 运算的规则是:只要有一个输入为 1,输出即为 1;否则为 0。只需调整偏置即可实现,选择参数:\(w_1=0.5, w_2=0.5, b=-0.3\),验证如下:
- 当\(x_1=0,x_2=1\):\(z=0 + 0.5 - 0.3 = 0.2 ≥ 0\) → \(y=1\)(符合规则);
- 其他输入组合均满足 OR 运算规则,此处不再赘述。
1.2.4 感知机的训练规则:误差驱动的参数更新
感知机的 "学习" 本质是通过 "误差调整参数",让预测输出逐步接近真实标签。其训练过程基于 "误差反馈",具体步骤如下:
- 参数初始化:随机初始化权重\(w_1,w_2,...,w_n\)(通常为 0 附近的小随机数,如\([-0.1,0.1]\))和偏置b(初始化为 0);
- 预测输出计算:对每个训练样本,用当前参数计算预测输出\(y = f(\boldsymbol{w}·\boldsymbol{x} + b)\);
- 误差计算:计算预测输出与真实标签的误差\(e = t - y\),其中t是样本的真实标签(如 AND 运算中的目标输出);
- 参数更新 :根据误差调整权重和偏置,更新公式为:\(w_i \leftarrow w_i + \eta·e·x_i \quad (i=1,2,...,n)\)\(b \leftarrow b + \eta·e\) 其中\(\eta\)是学习率(Learning Rate),取值范围通常为 0.01~0.1,用于控制每次参数更新的幅度 ------ 学习率过大会导致参数震荡不收敛,过小则会使训练速度极慢;
- 迭代终止:重复步骤 2~4,直到所有样本的预测误差小于设定阈值(如 0.01),或迭代次数达到上限(如 1000 次)。
1.2.5 感知机的致命缺陷:线性不可分问题
1969 年,人工智能先驱 Marvin Minsky 在《Perceptrons》一书中指出:感知机无法解决 "异或(XOR)" 问题 ------ 这一结论直接导致了第一次 "AI 寒冬",神经网络研究陷入近 20 年的低谷。
XOR 运算的规则是:两个输入相同(均为 0 或均为 1)时输出 0,输入不同时输出 1,其真值表如下:
输入\(x_1\) | 输入\(x_2\) | 目标输出y |
---|---|---|
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
为什么感知机无法解决 XOR?因为感知机本质是线性模型------ 它只能用一条直线(2 维输入)或一个平面(3 维输入)将数据分为两类。而 XOR 的样本在平面上的分布是 "交叉式" 的(如下图所示):输出为 1 的样本((0,1)、(1,0))和输出为 0 的样本((0,0)、(1,1))相互交错,无论如何绘制直线,都无法将两类样本完全分隔开 ------ 这就是 "线性不可分" 问题。
(注:实际示意图中,XOR 样本呈 "对角线分布",直线无法分割,可自行搜索 "XOR 线性不可分" 查看可视化效果)
感知机的局限让研究者意识到:单一层的线性模型无法处理复杂的非线性问题,必须通过 "多层结构 + 非线性激活" 突破限制 ------ 这为多层感知机(MLP)的诞生奠定了基础。
1.3 突破线性限制:多层感知机(MLP)的定义与结构
解决线性不可分问题的核心思路有两个:一是增加网络层数,将输入数据映射到更高维度的空间;二是使用非线性激活函数,打破 "线性叠加仍是线性" 的桎梏。基于这两个思路,多层感知机(Multi-Layer Perceptron, MLP) 应运而生,它也被称为 "标准人工神经网络模型"。
1.3.1 MLP 的分层结构
MLP 的结构如同 "金字塔",从下到上分为三大层(隐藏层可多层),各层功能明确:
-
输入层(Input Layer):接收原始数据的特征,仅负责信号传递,不进行任何计算。例如,在手写数字识别任务中,输入层节点数等于图片的像素数(如 28×28=784 个节点);若输入是 "身高、体重、年龄" 三个特征,则输入层有 3 个节点。输入层的激活输出记为\(a^{(0)} = \boldsymbol{x}\)(\(\boldsymbol{x}\)为输入特征向量)。
-
隐藏层(Hidden Layer):位于输入层与输出层之间,是 MLP 的 "核心计算层"。通过加权求和与非线性激活,隐藏层能将输入的线性特征转换为非线性特征(如将 "像素点" 转换为 "边缘、纹理" 等高级特征)。隐藏层可以有 1 层、2 层甚至数十层 ------ 当隐藏层超过 3 层时,MLP 通常被称为 "深度神经网络(DNN)"。隐藏层的数量和节点数是神经网络的重要超参数,需根据任务复杂度调整。
-
输出层(Output Layer):输出模型的预测结果,节点数由任务类型决定:
- 二分类任务(如 "是否为猫"):输出层 1 个节点,激活函数用 Sigmoid(输出范围 (0,1),代表属于正类的概率);
- 多分类任务(如 0~9 手写数字识别):输出层节点数等于类别数(10 个节点),激活函数用 Softmax(输出各类别概率,总和为 1);
- 回归任务(如预测房价):输出层 1 个节点,无需激活函数(直接输出连续值)。
以解决 XOR 问题的 MLP 为例,其结构为:输入层(2 个节点)→ 隐藏层(2 个节点)→ 输出层(1 个节点),通过这三层结构即可完美解决线性不可分问题。
1.3.2 MLP 如何解决 XOR 问题?
MLP 解决 XOR 的核心逻辑是 "分两步映射":先通过隐藏层将数据映射到高维空间,再通过输出层在高维空间实现线性分隔。具体过程如下:
-
第一步:隐藏层提取非线性特征 隐藏层的两个神经元分别学习 "逻辑或非(NOR)" 和 "逻辑与(AND)" 的特征:
- 隐藏层神经元 1(NOR):规则是 "仅当输入均为 0 时输出 1",参数选择\(w_{11}=1, w_{12}=1, b_1=-1.5\),激活函数用 Sigmoid(输出范围 (0,1),近似 0 或 1);
- 隐藏层神经元 2(AND):规则是 "仅当输入均为 1 时输出 1",参数选择\(w_{21}=1, w_{22}=1, b_2=-0.5\),激活函数同样用 Sigmoid。
对 XOR 的 4 个样本,隐藏层输出如下:
- 样本 (0,0):神经元 1 输出≈1(NOR 激活),神经元 2 输出≈0(AND 抑制)→ 隐藏层特征 (1,0);
- 样本 (0,1):神经元 1 输出≈0(NOR 抑制),神经元 2 输出≈0(AND 抑制)→ 隐藏层特征 (0,0);
- 样本 (1,0):神经元 1 输出≈0(NOR 抑制),神经元 2 输出≈0(AND 抑制)→ 隐藏层特征 (0,0);
- 样本 (1,1):神经元 1 输出≈0(NOR 抑制),神经元 2 输出≈1(AND 激活)→ 隐藏层特征 (0,1)。
-
第二步:输出层实现线性分隔 输出层将隐藏层的特征进行 "逻辑或(OR)" 运算,参数选择\(w_{31}=1, w_{32}=1, b_3=-1.5\),激活函数用阶跃函数。此时,隐藏层特征 (1,0)、(0,1) 对应输出 0(符合 XOR 规则),特征 (0,0) 对应输出 1(符合 XOR 规则)------ 在高维空间中,一条直线即可将两类样本完全分隔,从而解决 XOR 问题。
1.3.3 神经网络的 "进化图谱"
MLP 的 "分层 + 非线性" 逻辑为后续神经网络的发展奠定了基础。随着任务需求的细化,研究者在 MLP 的基础上优化结构,衍生出针对特定场景的专用网络:
- 卷积神经网络(CNN):针对图像任务,通过 "卷积层" 提取局部特征(边缘、纹理、形状),"池化层" 减少参数数量,解决 MLP 处理大图片时 "参数爆炸" 的问题;
- 循环神经网络(RNN):针对序列任务(文本、语音),通过 "循环连接" 让网络记住历史信息(如理解 "他" 指代前文的 "小明");
- Transformer:基于 "自注意力机制",能捕捉序列中远距离的依赖关系(如一句话中开头与结尾的关联),是 ChatGPT、GPT-4 等大语言模型的核心结构。
无论结构如何变化,这些网络的核心仍遵循 MLP 的逻辑 ------ 通过分层计算和非线性激活拟合复杂数据;而让它们 "学会" 优化参数的,正是梯度算法。
二、神经网络的核心组件:从数学到实践
要真正掌握神经网络的工作原理,需拆解其 "最小运行单元"------ 激活函数、前向传播、损失函数。这些组件是神经网络 "正向计算" 的核心,也是后续梯度算法的基础。
2.1 激活函数:赋予神经网络 "非线性能力"
激活函数是神经网络能拟合非线性数据的关键------ 若没有激活函数,无论多少层网络,最终都会退化为线性模型(线性变换的叠加仍是线性变换)。
2.1.1 为什么必须用非线性激活函数?
我们以 "输入层→1 个隐藏层→输出层" 的 2 层网络为例(无激活函数),验证这一结论:
- 隐藏层计算:\(a^{(1)} = z^{(1)} = W^{(1)}a^{(0)} + b^{(1)}\)(\(W^{(1)}\)为隐藏层权重矩阵,\(b^{(1)}\)为偏置);
- 输出层计算:\(a^{(2)} = z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}\)(\(W^{(2)}\)为输出层权重矩阵,\(b^{(2)}\)为偏置)。
将隐藏层结果代入输出层公式:\(a^{(2)} = W^{(2)}(W^{(1)}a^{(0)} + b^{(1)}) + b^{(2)} = (W^{(2)}W^{(1)})a^{(0)} + (W^{(2)}b^{(1)} + b^{(2)})\)
令\(W' = W^{(2)}W^{(1)}\)(新权重矩阵),\(b' = W^{(2)}b^{(1)} + b^{(2)}\)(新偏置),则输出层可简化为:\(a^{(2)} = W'a^{(0)} + b'\)
这与单一层的线性模型完全一致!也就是说,没有激活函数的多层网络,和 "一层网络" 没有任何区别 ------ 这就是激活函数必须是非线性的根本原因。
2.1.2 常见激活函数的全面对比
不同激活函数的特性差异极大,选择错误会导致模型收敛慢、梯度消失等问题。以下是 5 种最常用的激活函数,从公式、导数、优缺点到适用场景进行详细对比:
激活函数 | 数学公式 | 导数公式 | 核心优点 | 主要缺点 | 适用场景 |
---|---|---|---|---|---|
Sigmoid | \(f(z) = \frac{1}{1+e^{-z}}\) | \(f'(z) = f(z)(1-f(z))\) | 1. 输出范围 (0,1),可直接表示概率; 2. 曲线平滑,连续可导; 3. 物理意义直观(模拟神经元激活概率) | 1. 梯度消失:当\(|z|>5\)时,导数≈0,参数难以更新; 2. 输出非零均值,导致梯度偏移(更新方向偏向一侧); 3. 计算需指数运算,速度较慢 | 1. 二分类任务的输出层; 2. 早期神经网络的隐藏层(已被 ReLU 替代) |
Tanh | \(f(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}\) | \(f'(z) = 1 - [f(z)]^2\) | 1. 输出范围 (-1,1),零均值,梯度更稳定; 2. 比 Sigmoid 收敛速度更快; 3. 对噪音的鲁棒性更强 | 1. 仍存在梯度消失问题(\(|z|>3\)时导数≈0); 2. 计算需指数运算,效率较低 | 1. RNN 的隐藏层; 2. 需零均值输出的场景(如语音信号处理) |
ReLU | \(f(z) = \max(0, z)\) | \(f'(z) = \begin{cases} 1 & z>0 \\ 0 & z \leq 0 \end{cases}\) | 1. 计算极快(仅需比较大小,无指数 / 三角函数); 2. 缓解梯度消失(\(z>0\)时导数 = 1,梯度不衰减); 3. 稀疏激活(\(z≤0\)时神经元休眠),减少过拟合 | 1. 死亡 ReLU:当\(z≤0\)时,神经元永久失活(梯度 = 0,参数不再更新); 2. 输出非零均值,可能影响训练稳定性 | 1. 现代深度学习的默认隐藏层(CNN、Transformer、DNN); 2. 大数据量、深层数的场景 |
Leaky ReLU | \(f(z) = \begin{cases} z & z>0 \\ \alpha z & z \leq 0 \end{cases}\)(\(\alpha≈0.01\)) | \(f'(z) = \begin{cases} 1 & z>0 \\ \alpha & z \leq 0 \end{cases}\) | 1. 解决 "死亡 ReLU" 问题(\(z≤0\)时仍有梯度\(\alpha\),参数可更新); 2. 继承 ReLU 的计算速度优势; 3. 对负输入更鲁棒 | 1. 需要手动调整\(\alpha\)(无统一最优值,需交叉验证); 2. 理论解释不足,缺乏生物学依据 | 1. 替代 ReLU 的隐藏层; 2. 易出现死亡 ReLU 的场景(如深层 CNN) |
Softmax | \(f(z_i) = \frac{e^{z_i}}{\sum_{j=1}^k e^{z_j}}\)(k为类别数) | \(f'(z_i) = f(z_i)(\delta_{ij} - f(z_j))\)(\(\delta_{ij}\)为克罗内克函数) | 1. 输出k个类别概率,总和为 1,物理意义明确; 2. 能突出概率最大的类别("概率最大化" 特性); 3. 与交叉熵损失搭配时,梯度计算简洁 | 1. 数值不稳定:当\(z_i\)过大时,\(e^{z_i}\)易溢出(可通过 "减去最大值" 优化); 2. 梯度计算复杂,需矩阵运算 | 多分类任务的输出层(如手写数字识别、图像分类、文本分类) |
实战选择建议:
- 隐藏层:优先选择ReLU (计算快、效果好);若训练中出现 "死亡 ReLU"(模型准确率停滞不前),则换用Leaky ReLU(\(\alpha=0.01\)是安全默认值);
- 输出层:二分类用Sigmoid ,多分类用Softmax,回归任务无需激活函数(直接输出连续值)。
2.2 前向传播:从输入到输出的 "计算流"
前向传播(Forward Propagation)是神经网络根据输入计算预测输出的过程,本质是 "逐层计算净输入→激活转换→传递给下一层" 的迭代。掌握前向传播,是理解后续梯度算法的基础。
2.2.1 统一符号定义(关键!后续推导依赖)
为了清晰描述多层网络的计算,我们定义以下符号系统(适用于任意层数的神经网络):
- L:神经网络的总层数(输入层不计入,如 "输入层 + 1 隐藏层 + 输出层" 的网络,\(L=2\));
- \(n^{(l)}\):第l层的神经元数量(如输入层\(n^{(0)}=2\),隐藏层\(n^{(1)}=2\),输出层\(n^{(2)}=1\));
- \(W^{(l)}\):第l层的权重矩阵,维度为\(n^{(l)} \times n^{(l-1)}\)(每行对应第l层一个神经元的权重);
- \(b^{(l)}\):第l层的偏置向量,维度为\(n^{(l)} \times 1\)(每个元素对应第l层一个神经元的偏置);
- \(z^{(l)}\):第l层的 "净输入" 向量(加权和 + 偏置),维度为\(n^{(l)} \times 1\);
- \(a^{(l)}\):第l层的 "激活输出" 向量(净输入经过激活函数),维度为\(n^{(l)} \times 1\);
- \(f^{(l)}(\cdot)\):第l层的激活函数(隐藏层和输出层可不同)。
2.2.2 前向传播的完整流程(以 3 层 MLP 为例)
我们以 "输入层\(l=0\)→隐藏层\(l=1\)(ReLU 激活)→输出层\(l=2\)(Sigmoid 激活)" 的 3 层 MLP 为例(二分类任务),详细拆解前向传播的每一步:
-
步骤 1:输入层初始化 输入层不进行计算,直接将原始特征向量作为激活输出:\(a^{(0)} = \boldsymbol{x}\) 其中\(\boldsymbol{x}\)是输入特征向量,维度为\(n^{(0)} \times 1\)。例如,若输入是 "湿度、云量" 两个特征,则\(n^{(0)}=2\),\(\boldsymbol{x} = [x_1, x_2]^T\)(\(x_1\)为湿度,\(x_2\)为云量)。
-
步骤 2:隐藏层(\(l=1\))计算 隐藏层是首次进行计算的层级,分为 "净输入计算" 和 "激活转换" 两步:
- 净输入计算:权重矩阵与上一层激活输出相乘,再加上偏置:\(z^{(1)} = W^{(1)}a^{(0)} + b^{(1)}\) 假设\(n^{(0)}=2\),\(n^{(1)}=2\),则\(W^{(1)}\)是\(2 \times 2\)矩阵(如\(W^{(1)} = \begin{bmatrix} w_{11} & w_{12} \\ w_{21} & w_{22} \end{bmatrix}\)),\(a^{(0)}\)是\(2 \times 1\)向量,相乘后得到\(2 \times 1\)向量,再与\(2 \times 1\)的偏置\(b^{(1)}\)相加,最终\(z^{(1)}\)是\(2 \times 1\)向量(如\(z^{(1)} = [z_1^{(1)}, z_2^{(1)}]^T\))。
- 激活转换:用 ReLU 激活函数对净输入进行转换:\(a^{(1)} = f^{(1)}(z^{(1)}) = \text{ReLU}(z^{(1)})\) 激活函数对向量的作用是 "逐元素转换",即\(a_1^{(1)} = \max(0, z_1^{(1)})\),\(a_2^{(1)} = \max(0, z_2^{(1)})\),因此\(a^{(1)}\)的维度与\(z^{(1)}\)一致,为\(2 \times 1\)。
-
步骤 3:输出层(\(l=2\))计算 输出层的计算逻辑与隐藏层一致,但激活函数需匹配任务类型(此处为二分类,用 Sigmoid):
- 净输入计算:\(z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}\) 二分类任务中\(n^{(2)}=1\),因此\(W^{(2)}\)是\(1 \times 2\)矩阵(如\(W^{(2)} = [w_{31}, w_{32}]\)),\(a^{(1)}\)是\(2 \times 1\)向量,相乘后得到\(1 \times 1\)向量,与\(1 \times 1\)的偏置\(b^{(2)}\)相加,\(z^{(2)}\)是\(1 \times 1\)向量。
- 激活转换:\(a^{(2)} = f^{(2)}(z^{(2)}) = \text{Sigmoid}(z^{(2)})\)\(a^{(2)}\)是\(1 \times 1\)向量,取值范围 (0,1),代表模型对该样本的预测概率(如\(a^{(2)}=0.9\)表示样本属于正类的概率为 90%)。
-
步骤 4:输出预测结果 输出层的激活输出\(a^{(L)}\)(此处\(L=2\))即为模型的预测结果,记为\(\hat{y}\):\(\hat{y} = a^{(L)}\)
2.2.3 批量计算:提升训练效率的关键
实际训练中,我们不会一次只处理一个样本,而是采用 "批量样本"(Batch)进行计算 ------ 这能充分利用 GPU 的并行计算能力,大幅提升训练效率。此时,输入\(a^{(0)}\)不再是向量,而是矩阵,维度为\(n^{(0)} \times \text{batch_size}\),其中\(\text{batch_size}\)是批量大小(常用值为 32、64、128),每一列代表一个样本的特征向量。
以批量大小 = 2 为例(两个样本\(\boldsymbol{x}_1, \boldsymbol{x}_2\)),前向传播的计算调整如下:
- 输入层:\(a^{(0)} = \boldsymbol{X}\),\(\boldsymbol{X}\)是\(2 \times 2\)矩阵(如\(\boldsymbol{X} = \begin{bmatrix} x_{11} & x_{12} \\ x_{21} & x_{22} \end{bmatrix}\),\(x_{11}\)为样本 1 的湿度,\(x_{12}\)为样本 2 的湿度);
- 隐藏层:\(z^{(1)} = W^{(1)}\boldsymbol{X} + b^{(1)}\)(偏置\(b^{(1)}\)通过 "广播机制" 自动扩展为\(2 \times 2\)矩阵,与\(W^{(1)}\boldsymbol{X}\)的维度匹配),\(a^{(1)} = \text{ReLU}(z^{(1)})\)(\(a^{(1)}\)是\(2 \times 2\)矩阵,每一列对应一个样本的隐藏层输出);
- 输出层:\(z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}\),\(a^{(2)} = \text{Sigmoid}(z^{(2)})\)(\(a^{(2)}\)是\(1 \times 2\)矩阵,每一列对应一个样本的预测概率)。
批量计算的核心优势在于:将单次前向传播的时间从 "处理 1 个样本" 缩短到 "处理 batch_size 个样本"(GPU 并行计算矩阵乘法),训练效率可提升数十倍。
2.3 损失函数:衡量 "预测与真实" 的差距
神经网络的 "学习目标" 是让预测输出\(\hat{y}\)尽可能接近真实标签y,而损失函数(Loss Function)就是量化这种 "差距" 的工具 ------ 损失值越小,模型的预测越准确。损失函数的选择直接影响梯度计算和模型收敛,必须根据任务类型(回归 / 分类)精准匹配。
2.3.1 回归任务:预测连续值(如房价、温度)
回归任务的目标是预测一个连续的数值(如预测某套房子的价格、明天的最高温度),常用均方误差(Mean Squared Error, MSE) 作为损失函数。
MSE 的数学公式
对于单个样本,MSE 的定义为:\(L(\hat{y}, y) = \frac{1}{2} \|\hat{y} - y\|^2 = \frac{1}{2} \sum_{i=1}^d (\hat{y}_i - y_i)^2\) 其中:
- d是输出维度(回归任务通常\(d=1\),如预测房价;若同时预测 "房价 + 面积",则\(d=2\));
- \(\hat{y}_i\)是预测值的第i个维度,\(y_i\)是真实值的第i个维度;
- 乘以\(\frac{1}{2}\)是为了简化后续梯度计算(求导后\(\frac{1}{2}\)与平方的 2 抵消,得到\(\hat{y}_i - y_i\),避免额外系数)。
对于批量样本(batch_size 个样本),通常计算 "平均 MSE" 作为批量损失(减少单个样本的噪音影响):\(L_{batch} = \frac{1}{2 \times \text{batch_size}} \sum_{j=1}^{\text{batch_size}} \sum_{i=1}^d (\hat{y}{ij} - y{ij})^2\)
MSE 的特性与适用场景
- 优点:数学性质优良(连续可导、凸函数),梯度计算简单(导数为\(\hat{y} - y\)),收敛稳定;
- 缺点:对异常值敏感(异常值的误差会被平方放大,导致模型偏向异常值);
- 适用场景:房价预测、股票价格预测、温度预测等所有输出为连续值的任务。
2.3.2 分类任务:预测离散类别(如猫 / 狗、手写数字)
分类任务的目标是预测样本属于哪个离散类别(如 "猫""狗""鸟"),常用交叉熵损失(Cross-Entropy Loss) ------ 它能有效衡量 "预测概率分布" 与 "真实概率分布" 的差异,且梯度下降速度远快于 MSE。
交叉熵的数学本质
交叉熵源于信息论,用于衡量两个概率分布P(真实分布)和Q(预测分布)的 "距离",公式为:\(H(P, Q) = -\sum_{i=1}^k P(i) \log Q(i)\) 其中k是类别数,\(P(i)\)是真实分布中样本属于第i类的概率,\(Q(i)\)是预测分布中样本属于第i类的概率。
在分类任务中,真实标签y可表示为 "独热编码(One-Hot Encoding)" 的概率分布 ------ 例如,3 分类任务中,类别 2 的真实标签为\(y = [0, 0, 1]^T\),即\(P(1)=0, P(2)=1, P(3)=0\);而预测输出\(\hat{y}\)是模型输出的概率分布(如 Softmax 激活后的结果),即\(Q(i) = \hat{y}_i\)。
二分类任务的交叉熵损失
二分类任务中,类别数\(k=2\)(如 "猫" 和 "非猫"),真实标签\(y \in \{0, 1\}\),预测输出\(\hat{y} \in (0, 1)\)(Sigmoid 激活,代表样本属于正类的概率)。此时,交叉熵损失的公式简化为:\(L(\hat{y}, y) = -[y \log \hat{y} + (1 - y) \log (1 - \hat{y})]\)
我们分两种情况理解这一公式:
- 当\(y=1\)(样本属于正类):损失简化为\(-\log \hat{y}\)------ 若\(\hat{y}=0.9\)(预测准确),损失≈0.105;若\(\hat{y}=0.1\)(预测错误),损失≈2.303,即 "预测越不准,损失越大";
- 当\(y=0\)(样本属于负类):损失简化为\(-\log (1 - \hat{y})\)------ 若\(\hat{y}=0.1\)(预测准确),损失≈0.105;若\(\hat{y}=0.9\)(预测错误),损失≈2.303,同样符合 "预测准确性与损失负相关" 的逻辑。
多分类任务的交叉熵损失
多分类任务中,类别数\(k \geq 3\)(如 0~9 的手写数字识别,\(k=10\)),真实标签y用独热编码表示(如类别 5 的标签为\(y = [0,0,0,0,0,1,0,0,0,0]^T\)),预测输出\(\hat{y}\)是k维概率向量(Softmax 激活,\(\sum_{i=1}^k \hat{y}i = 1\))。此时,交叉熵损失的公式为:\(L(\hat{y}, y) = -\sum{i=1}^k y_i \log \hat{y}_i\)
由于独热编码中只有真实类别对应的\(y_i=1\),其余\(y_i=0\),公式可进一步简化为:\(L(\hat{y}, y) = -\log \hat{y}{true}\) 其中\(\hat{y}{true}\)是预测为真实类别的概率 ------ 例如,真实类别是 5,若\(\hat{y}_5=0.9\)(预测准确),损失≈0.105;若\(\hat{y}_5=0.1\)(预测错误),损失≈2.303。
为什么分类任务不用 MSE?
很多初学者会疑惑:"为什么分类任务不用 MSE?" 我们以多分类任务(Softmax 激活)为例,从梯度角度解释这一问题:
若损失用 MSE,损失对输出层权重\(W^{(L)}\)的梯度(通过链式法则推导)为:\(\frac{\partial L}{\partial W^{(L)}} = (\hat{y} - y) \cdot \hat{y} \cdot (1 - \hat{y}) \cdot a^{(L-1)^T}\)
当模型预测错误时(如\(\hat{y}_{true}=0.1\)),\(\hat{y} \cdot (1 - \hat{y}) = 0.1 \times 0.9 = 0.09\),会导致梯度被 "缩小",参数更新缓慢;而交叉熵损失的梯度为:\(\frac{\partial L}{\partial W^{(L)}} = (\hat{y} - y) \cdot a^{(L-1)^T}\)
没有\(\hat{y} \cdot (1 - \hat{y})\)这一 "缩小项",梯度大小直接由 "预测与真实的差距" 决定,收敛速度远快于 MSE。因此,分类任务必须用交叉熵损失,回归任务用 MSE------ 这是深度学习的 "黄金法则" 之一。
2.4 小结:神经网络的 "正向逻辑链"
到这里,我们已理清神经网络的正向工作流程,可总结为一条清晰的 "逻辑链":
- 输入:原始特征向量\(\boldsymbol{x}\)输入网络,作为输入层的激活输出\(a^{(0)}\);
- 前向传播:从隐藏层到输出层,逐层计算净输入\(z^{(l)} = W^{(l)}a^{(l-1)} + b^{(l)}\)和激活输出\(a^{(l)} = f^{(l)}(z^{(l)})\);
- 预测:输出层的激活输出\(a^{(L)}\)即为模型的预测结果\(\hat{y}\);
- 损失计算:用损失函数(MSE / 交叉熵)计算\(\hat{y}\)与真实标签y的差距L。
接下来的核心问题是:如何调整参数\(W^{(1)}, b^{(1)}, ..., W^{(L)}, b^{(L)}\),让损失L最小化?这就需要梯度算法登场了。
三、梯度算法:让神经网络 "学会优化" 的核心
神经网络的参数优化本质是一个无约束优化问题:找到一组参数\(\theta = \{W^{(1)}, b^{(1)}, ..., W^{(L)}, b^{(L)}\}\),使得损失函数\(L(\theta)\)达到最小值。而梯度算法,是解决这一问题的最有效工具。
3.1 梯度的本质:函数 "下降最快" 的方向
要理解梯度算法,首先需要明确 "梯度" 的数学定义与物理意义 ------ 它并非复杂概念,而是 "多变量函数的导数向量"。
3.1.1 从单变量导数到多变量梯度
我们先从熟悉的单变量函数入手,再过渡到多变量函数,逐步理解梯度的内涵。
1. 单变量函数的导数 对于单变量函数\(f(x)\)(如\(f(x) = x^2\)),导数\(f'(x)\)表示函数在x处的 "变化率",有两个核心意义:
- 方向:若\(f'(x) > 0\),则x增大时\(f(x)\)上升;若\(f'(x) < 0\),则x增大时\(f(x)\)下降;
- 大小:导数的绝对值越大,函数在该点的变化越剧烈(如\(f(x)=x^2\)在\(x=2\)处的导数为 4,变化率比\(x=1\)处的导数 2 更显著)。
要最小化\(f(x)\),只需沿导数的反方向调整x:若\(f'(x) > 0\),则减小x;若\(f'(x) < 0\),则增大x------ 这就是单变量函数的 "梯度下降" 思想。
2. 多变量函数的梯度 对于多变量函数\(L(\theta_1, \theta_2, ..., \theta_n)\)(如神经网络的损失函数,参数\(\theta\)是高维向量),单个参数的导数已无法描述整体变化,需用 "梯度" 表示。
梯度(Gradient)是由函数对每个参数的偏导数组成的向量,记为\(\nabla_\theta L(\theta)\):\(\nabla_\theta L(\theta) = \left[ \frac{\partial L}{\partial \theta_1}, \frac{\partial L}{\partial \theta_2}, ..., \frac{\partial L}{\partial \theta_n} \right]^T\)
例如,若损失函数L仅与两个参数\(w_1\)(权重)和b(偏置)相关,则梯度为:\(\nabla_{w_1, b} L = \left[ \frac{\partial L}{\partial w_1}, \frac{\partial L}{\partial b} \right]^T\)
3.1.2 梯度的核心性质(必须掌握!)
梯度有两个决定其 "优化能力" 的核心性质,也是梯度下降算法的理论基础:
- 方向性质 :梯度向量的方向,是函数值上升最快 的方向;反之,梯度的反方向,是函数值下降最快的方向 ------ 这意味着,沿梯度反方向调整参数,能以最快速度减小损失;
- 大小性质:梯度向量的模长(向量的长度),是函数在该点沿 "上升最快方向" 的最大变化率 ------ 模长越大,函数在该点的变化越剧烈(离最优值越远,梯度通常越大;越接近最优值,梯度越小)。
我们可以用一个直观的比喻理解梯度:将损失函数\(L(\theta)\)想象成一座 "山",我们站在山的某个位置(当前参数\(\theta\)),梯度向量就像一个 "指南针",指向 "上山最快" 的方向;而我们的目标是 "下山"(最小化损失),因此只需沿指南针的反方向走 ------ 这就是梯度下降的核心逻辑。
3.2 梯度下降的基本公式:参数如何更新?
基于梯度的性质,梯度下降(Gradient Descent)的参数更新公式非常简洁:\(\theta \leftarrow \theta - \eta \cdot \nabla_\theta L(\theta)\)
其中:
- \(\theta\):当前的参数(可以是权重\(W^{(l)}\)或偏置\(b^{(l)}\));
- \(\leftarrow\):表示 "更新为";
- \(\eta\):学习率(Learning Rate),控制每次参数更新的 "步长";
- \(\nabla_\theta L(\theta)\):损失函数对参数\(\theta\)的梯度。
3.2.1 公式的物理意义
参数更新公式的本质是 "沿梯度反方向走一小步",具体可分为两种情况:
- 若梯度\(\nabla_\theta L(\theta) > 0\)(损失随\(\theta\)增大而上升):则\(\theta\)需减小(\(\theta - \eta \cdot 正数\)),以降低损失;
- 若梯度\(\nabla_\theta L(\theta) < 0\)(损失随\(\theta\)增大而下降):则\(\theta\)需增大(\(\theta - \eta \cdot 负数 = \theta + 正数\)),以降低损失。
学习率\(\eta\)的作用至关重要:
- \(\eta\)太大:可能一步跨到山的另一边(参数震荡,无法收敛到最优值);
- \(\eta\)太小:下山速度太慢(训练周期极长,甚至在有限迭代次数内无法接近最优值)。
3.2.2 学习率的实战选择技巧
学习率是梯度下降中最关键的超参数,选择不当会直接导致模型训练失败。以下是工业界常用的选择技巧:
- 初始学习率选择:通常从 0.1、0.01、0.001 中选择(优先尝试 0.001,避免步长过大导致震荡);
- 学习率调度(Learning Rate Scheduling):训练过程中逐步减小学习率 ------ 例如,每训练 10 个 "轮次(Epoch)",学习率减小为原来的 1/10("步降法");或采用 "余弦退火",让学习率随迭代次数呈余弦曲线下降,前期快速接近最优值,后期精细调整;
- 自适应学习率优化器:使用 Adam、RMSprop 等优化器,自动根据梯度大小调整学习率 ------ 梯度大时步长小(避免震荡),梯度小时步长大(加速收敛),无需手动调整;
- 避免极端值:不要使用过大的学习率(如 1.0),否则参数会剧烈震荡;也不要使用过小的学习率(如 1e-6),否则训练到收敛可能需要数十万次迭代,耗时极长。
3.3 梯度下降的 "家族成员":从基础到进阶
根据 "计算梯度时使用的样本数量" 和 "参数更新方式",梯度下降可分为多个变体,各有优缺点和适用场景。我们从基础到进阶,逐一解析最常用的 5 种梯度下降算法。
3.3.1 批量梯度下降(Batch Gradient Descent, BGD)
原理 :用全部训练样本计算梯度,再更新参数。梯度计算公式(批量损失对参数\(\theta\)的梯度)为:\(\nabla_\theta L(\theta) = \frac{1}{m} \sum_{i=1}^m \nabla_\theta L^{(i)}(\theta)\) 其中m是训练样本总数,\(L^{(i)}(\theta)\)是第i个样本的损失。
优点:
- 梯度估计准确:用所有样本计算梯度,无随机噪音,梯度方向稳定;
- 收敛路径平滑:参数更新方向始终指向最优值方向,不会出现震荡;
- 计算效率高(小数据集):可通过矩阵运算优化,单次迭代即可利用所有样本信息。
缺点:
- 大数据集计算慢:每次迭代需加载所有样本,内存占用高(如百万级样本的图像数据,可能无法一次性加载到内存),GPU 利用率低;
- 无法在线学习:新样本加入后,需重新用所有样本计算梯度,无法实时更新模型。
适用场景:小数据集(样本数 < 1 万),如学术研究、小规模实验(如验证算法有效性)。
3.3.2 随机梯度下降(Stochastic Gradient Descent, SGD)
原理 :用单个随机样本计算梯度,再更新参数。梯度计算公式(单个样本损失对参数\(\theta\)的梯度)为:\(\nabla_\theta L(\theta) \approx \nabla_\theta L^{(i)}(\theta)\) 其中i是从 1 到m中随机选择的样本索引(每次迭代随机选一个样本)。
优点:
- 大数据集计算快:每次迭代只需加载 1 个样本,内存占用极低,可实时更新(在线学习);
- 随机噪音的优势:单个样本的梯度存在噪音,可能让参数从局部最优区域跳出,有机会找到全局最优值;
- 训练灵活:可随时加入新样本,无需重新训练整个模型。
缺点:
- 梯度估计不准确:单个样本的梯度噪音大,参数更新方向不稳定;
- 收敛路径震荡:参数更新方向频繁变化,需要更多迭代次数才能收敛;
- 学习率难调整:固定学习率可能导致后期震荡不收敛(需手动调整学习率)。
适用场景:大数据集(样本数 > 10 万),在线学习场景(如实时推荐系统、实时语音识别)。
3.3.3 小批量梯度下降(Mini-Batch Gradient Descent, MBGD)
原理 :用一小批随机样本(Batch Size)计算梯度,再更新参数 ------ 这是 BGD 和 SGD 的折中方案,也是目前最常用的梯度下降算法。梯度计算公式(小批量损失对参数\(\theta\)的梯度)为:\(\nabla_\theta L(\theta) = \frac{1}{B} \sum_{i=1}^B \nabla_\theta L^{(i)}(\theta)\) 其中B是批量大小(Batch Size),常用值为 32、64、128、256。
优点:
- 梯度估计较准确:批量样本的梯度噪音比 SGD 小,比 BGD 计算速度快;
- 适合 GPU 并行计算:GPU 擅长处理矩阵运算,批量样本的矩阵乘法能最大化 GPU 的并行计算能力(效率比 SGD 高数十倍);
- 收敛稳定:参数更新方向比 SGD 稳定,迭代次数比 BGD 少(平衡速度与稳定性)。
缺点:
- 需调整批量大小:批量太大(如 1024)会接近 BGD,计算慢、内存占用高;批量太小(如 8)会接近 SGD,震荡明显;
- 学习率仍需手动调整:固定学习率可能导致后期收敛慢(需搭配学习率调度)。
适用场景:绝大多数深度学习场景(如图像分类、文本生成、语音识别),是工业界的默认选择。
批量大小选择技巧:
- 优先选择 2 的幂次(如 32、64、128):GPU 对 2 的幂次批量大小的矩阵运算优化更好,计算速度更快;
- 小数据集(<1 万):批量大小 = 样本数(即 BGD),充分利用样本信息;
- 大数据集(>10 万):批量大小 = 64 或 128(平衡速度与稳定性,若 GPU 内存不足,可减小到 32);
- 内存限制处理:若 GPU 内存不足,可使用 "梯度累积(Gradient Accumulation)"------ 将 1 个大批次拆分为多个小批次,累积多个小批次的梯度后再更新参数,效果等同于大批次。
3.3.4 动量梯度下降(Momentum)
原理:在 MBGD 的基础上,引入 "动量" 概念 ------ 模拟物理中的 "惯性",让参数更新不仅考虑当前梯度,还考虑上一次的更新方向,从而减少震荡、加速收敛。
参数更新公式分为两步:
-
计算动量:上一次动量 × 衰减系数 + 当前梯度,得到本次动量(模拟惯性):\(v_t = \gamma v_{t-1} + \eta \nabla_\theta L(\theta_t)\) 其中\(v_t\)是第t次迭代的动量,\(\gamma\)是动量衰减系数(通常取 0.9,控制惯性大小),\(v_{t-1}\)是第\(t-1\)次迭代的动量(初始为 0)。
-
更新参数:用动量替代原梯度,更新参数:\(\theta_{t+1} = \theta_t - v_t\)
核心作用:
- 减少震荡:当当前梯度方向与上一次动量方向相反时,动量会 "缓冲" 梯度的变化(如上次动量向右,本次梯度向左,动量会抵消部分向左的梯度),让参数更新更平稳;
- 加速收敛:当当前梯度方向与上一次动量方向相同时,动量会 "叠加" 梯度(如上次动量向右,本次梯度也向右,动量会增强向右的更新力度),尤其在损失函数的平缓区域(梯度小但方向稳定),能加速下降。
优点 :比 MBGD 收敛更快,震荡更少,适合深层网络; 缺点 :需调整动量系数\(\gamma\)(通常 0.9 是安全选择,无需过多调试); 适用场景:深层数、高维度的模型(如 CNN、Transformer),减少训练过程中的参数震荡。
3.3.5 Adam 优化器:自适应学习率的 "终极选择"
原理:Adam(Adaptive Moment Estimation)是目前最流行的优化器,结合了 "动量梯度下降" 和 "自适应学习率"(AdaGrad、RMSprop)的优点,能自动调整每个参数的学习率,无需手动调参。
Adam 的参数更新分为四步:
-
计算一阶动量(动量项):类似 Momentum,累积梯度的移动平均,捕捉梯度的方向信息:\(m_t = \beta_1 m_{t-1} + (1 - \beta_1) \nabla_\theta L(\theta_t)\) 其中\(\beta_1\)是一阶动量系数(通常取 0.9),\(m_{t-1}\)是上一次迭代的一阶动量(初始为 0)。
-
计算二阶动量(自适应学习率项):累积梯度平方的移动平均,捕捉梯度的 "稳定性"(梯度波动大的参数,二阶动量大;梯度波动小的参数,二阶动量小):\(v_t = \beta_2 v_{t-1} + (1 - \beta_2) [\nabla_\theta L(\theta_t)]^2\) 其中\(\beta_2\)是二阶动量系数(通常取 0.999),平方是 "逐元素平方"(每个参数的梯度单独平方),\(v_{t-1}\)是上一次迭代的二阶动量(初始为 0)。
-
偏差修正:由于初始时\(m_0=0, v_0=0\),前几次迭代的动量估计存在偏差,需进行修正(消除初始偏差对训练的影响):\(\hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t}\) 其中t是迭代次数(从 1 开始计数)。
-
更新参数:用修正后的动量和自适应学习率更新参数:\(\theta_{t+1} = \theta_t - \frac{\eta}{\sqrt{\hat{v}_t} + \epsilon} \hat{m}_t\) 其中\(\epsilon\)是一个极小值(通常取 1e-8),避免分母为 0(当\(\hat{v}_t\)接近 0 时,防止除以 0 错误),\(\eta\)是初始学习率(默认取 0.001)。
优点:
- 无需手动调参:默认参数(\(\beta_1=0.9, \beta_2=0.999, \eta=0.001\))在 90% 以上的任务中都能取得良好效果;
- 收敛快:结合动量和自适应学习率,在复杂模型(如深层 CNN、大语言模型)中收敛速度比 MBGD 快 3~5 倍;
- 稳定性高:对噪音梯度不敏感,即使梯度存在波动,也能稳定更新参数;
- 适用范围广:无论是小数据集、大数据集,还是简单模型、复杂模型,都能适用。
缺点 :参数较多(需维护一阶动量、二阶动量),计算量比 MBGD 略大(但在 GPU 上可忽略不计); 适用场景:所有深度学习任务(尤其是大语言模型、复杂 CNN、Transformer),是工业界和学术界的 "默认优化器"------ 在不确定选择哪种优化器时,优先用 Adam。
梯度下降算法对比总结:
算法名称 | 核心特点 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
批量梯度下降(BGD) | 用全部样本计算梯度 | 梯度准确,收敛稳定 | 大数据集计算慢,内存占用高 | 小数据集(<1 万样本) |
随机梯度下降(SGD) | 用单个样本计算梯度 | 计算快,支持在线学习 | 梯度噪音大,收敛震荡 | 大数据集,在线学习 |
小批量梯度下降(MBGD) | 用批量样本计算梯度 | 平衡速度和稳定性,适合 GPU 并行 | 需调整批量大小和学习率 | 绝大多数深度学习场景 |
动量梯度下降(Momentum) | 引入惯性,累积上一次更新方向 | 减少震荡,加速收敛 | 需调整动量系数 | 深层数、高维度模型 |
Adam 优化器 | 结合动量和自适应学习率 | 无需调参,收敛快,稳定性高 | 计算量略大 | 所有场景(默认选择) |
3.4 反向传播:梯度如何高效计算?
梯度下降的核心是 "计算损失对每个参数的梯度",而神经网络的参数分布在不同层(隐藏层、输出层),直接计算梯度会面临 "维度灾难"(参数数量可能达数百万甚至上亿)。1986 年,Rumelhart 等人提出的反向传播算法(Backpropagation, BP) ,解决了这一问题 ------ 它通过 "链式法则",从输出层到输入层反向计算梯度,将梯度计算的复杂度从 "指数级" 降低到 "线性级",为深度学习的发展奠定了基础。
3.4.1 反向传播的核心思想:链式法则
链式法则是微积分中的基本法则,用于计算 "复合函数的导数"。例如,若\(L = f(z)\)且\(z = g(w, x)\)(L是z的函数,z是w和x的函数),则L对w的导数为:\(\frac{\partial L}{\partial w} = \frac{\partial L}{\partial z} \cdot \frac{\partial z}{\partial w}\)
在神经网络中,损失L是 "参数→净输入→激活输出→损失" 的复合函数,因此梯度计算可通过链式法则 "反向传递":
- 输出层:先计算损失对输出层净输入\(z^{(L)}\)的梯度(记为\(\delta^{(L)} = \frac{\partial L}{\partial z^{(L)}}\));
- 隐藏层:用输出层的梯度\(\delta^{(L)}\)计算隐藏层净输入\(z^{(L-1)}\)的梯度\(\delta^{(L-1)}\),再用\(\delta^{(L-1)}\)计算\(z^{(L-2)}\)的梯度\(\delta^{(L-2)}\),依此类推,直到输入层(输入层无参数,无需计算梯度);
- 参数梯度:用每层的\(\delta^{(l)}\)计算该层权重\(W^{(l)}\)和偏置\(b^{(l)}\)的梯度(\(\frac{\partial L}{\partial W^{(l)}}\)和\(\frac{\partial L}{\partial b^{(l)}}\))。
3.4.2 反向传播的详细推导(以 3 层 MLP 为例)
我们以 "输入层\(l=0\)→隐藏层\(l=1\)(ReLU 激活)→输出层\(l=2\)(Sigmoid 激活)" 的 3 层 MLP 为例(二分类任务,交叉熵损失),详细推导反向传播的每一步,确保公式清晰、逻辑严谨。
符号回顾(与前向传播一致)
- 输入层:\(a^{(0)} = \boldsymbol{x}\)(输入特征向量,维度\(n^{(0)} \times 1\));
- 隐藏层(\(l=1\)):\(z^{(1)} = W^{(1)}a^{(0)} + b^{(1)}\),\(a^{(1)} = \text{ReLU}(z^{(1)})\)(维度\(n^{(1)} \times 1\));
- 输出层(\(l=2\)):\(z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}\),\(a^{(2)} = \text{Sigmoid}(z^{(2)}) = \hat{y}\)(维度\(n^{(2)} \times 1 = 1 \times 1\));
- 损失函数:\(L = -[y \log \hat{y} + (1 - y) \log (1 - \hat{y})]\)(二分类交叉熵损失)。
步骤 1:计算输出层的梯度\(\delta^{(2)} = \frac{\partial L}{\partial z^{(2)}}\)
根据链式法则,\(\frac{\partial L}{\partial z^{(2)}} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial z^{(2)}}\),需分两步计算:
-
第一步:计算\(\frac{\partial L}{\partial \hat{y}}\)(损失对输出层激活输出的梯度) 对交叉熵损失函数求导(\(\hat{y}\)是输出层激活输出):\(\frac{\partial L}{\partial \hat{y}} = -\left( \frac{y}{\hat{y}} - \frac{1 - y}{1 - \hat{y}} \right) = \frac{\hat{y} - y}{\hat{y}(1 - \hat{y})}\) 推导过程:对\(L = -[y \log \hat{y} + (1 - y) \log (1 - \hat{y})]\)求导,第一项导数为\(-\frac{y}{\hat{y}}\),第二项导数为\(\frac{1 - y}{1 - \hat{y}}\),合并后得到上述结果。
-
第二步:计算\(\frac{\partial \hat{y}}{\partial z^{(2)}}\)(输出层激活输出对净输入的梯度) 输出层用 Sigmoid 激活函数,其导数公式为 (\text {Sigmoid}'(z) = \text {Sigmoid}(z)(1 - \text {Sigmoid}(z)) = \hat {y}(1 - \hat {