高级机器学习模型

神经网络

从节点、隐藏层、激活函数到反向传播,理解深层模型如何表示非线性。

50 分钟 纯学习时间 已去掉互动练习与测试
本模块学完后,你能够
  • 看懂前向传播
  • 理解隐藏层与激活函数
  • 解释反向传播
  • 掌握多类别输出
01
预计 5 分钟

简介

神经网络通过多层线性组合与非线性激活,自动学习复杂特征和弯曲决策边界。

先把神经网络看作一串可学习的函数:输入特征经过若干层变换,最后得到预测。训练仍是在调整参数,让损失变小;它并不会因为叫“神经”就自动理解业务。

深层结构能把简单模式组合成复杂模式。第一层可能识别局部变化,后面的层利用这些变化学习更抽象的组合。代价是更多参数、计算量和调参难度,因此要先与简单模型建立基线。

图示可左右滑动查看输入层、隐藏层与输出层把简单特征逐级组合
输入层、隐藏层与输出层把简单特征逐级组合

你需要理解

  • 输入层接收特征,隐藏层学习中间表示,输出层产生预测。
  • “深度”通常指隐藏层数量。
再看一个实际场景

判断图片里是否有猫时,单条直线难以直接描述所有像素组合;分层模型可以逐级组合边缘、局部形状和整体特征。

注意

网络深不代表一定更好。样本少、标签质量差时,复杂网络可能更容易过拟合。

02
预计 15 分钟

节点和隐藏层

每个节点先计算加权和,再把结果交给激活函数。层与层连接形成可组合的表示。

一个节点先做 z = w₁x₁ + w₂x₂ + … + b:每个输入乘以权重,加上偏置。接着把 z 交给激活函数得到输出 a。权重与偏置是训练学到的参数,输入特征不是参数。

一层有多个节点,每个节点有不同的一组参数;隐藏层把上一层输出继续组合。隐藏层的“隐藏”只是表示这些值不是原始输入也不是最终答案,仍可在程序里查看。

z = b + Σwᵢxᵢ

你需要理解

  • 权重决定连接强度,偏置移动响应阈值。
  • 更宽的层可表示更多模式,更深的网络可组合多级概念。
  • 容量增加也提高数据、计算和正则化要求。
再看一个实际场景

预测房价时,两个节点可能学到面积与地段的不同组合;下一层再利用它们形成“高价房”线索。节点的真实含义未必能像人工规则那样直接命名。

注意

增加层数或宽度会增加模型容量,也增加训练成本。先观察验证集指标再扩容。

03
预计 10 分钟

激活函数

没有非线性激活,多层线性变换仍等价于一层线性模型。

若每层都只有线性加权和,多层连起来仍可合并成一次线性变换,无法学到弯曲边界。激活函数在节点之间引入非线性。ReLU(x)=max(0,x) 实现简单、常用于隐藏层;Sigmoid 把数值压到 0~1,常用于二分类输出。

ReLU 在负半轴梯度为 0,某个节点如果长期输出 0,可能不再更新。Tanh 的输出在 -1~1,Sigmoid 和 Tanh 的两端会饱和,梯度接近 0。选择激活函数要结合层的位置和训练曲线。

图示可左右滑动查看线性、ReLU 与 Sigmoid 的函数形状对比
线性、ReLU 与 Sigmoid 的函数形状对比
ReLU(z) = max(0, z)

你需要理解

  • ReLU=max(0,z),计算简单且常用。
  • Sigmoid 适合二元概率输出。
  • Softmax 适合互斥多类别输出。
  • 激活选择会影响梯度传播。
再看一个实际场景

以“温度适中才有人逛街”为例,客流量对温度的关系可能先升后降。带非线性激活的网络可以组合出这种折线或曲线形状。

04
预计 10 分钟

使用反向传播进行训练

前向传播得到预测和损失;反向传播按照链式法则把误差信号从输出层传回各层。

一次训练有两趟:前向传播算出每层输出和最终损失;反向传播利用链式法则,计算损失对每个参数的梯度。优化器随后按梯度更新参数。反向传播是求梯度的方法,梯度下降是利用梯度更新参数的方法。

链式法则可以拆成“下游错误有多大”乘“当前参数对下游结果影响有多大”。例如 z=wx+b,若损失对 z 的导数是 3、输入 x=2,则损失对 w 的导数为 3×2=6;学习率为 0.01 时,w 减少 0.06。真实网络会把这种计算从输出层逐层传回输入层。

若梯度在层间反复乘以很小的导数,前面层几乎学不到,叫梯度消失。可以记录每层梯度的范数:输出层有明显梯度、越靠前越接近 0,是一条排查线索。反复乘上大数则可能梯度爆炸,表现为损失突然飙升或出现 NaN。先检查输入尺度、学习率、初始化与激活函数,再考虑归一化或梯度裁剪;裁剪只能限制更新幅度,不能修好错误数据。

ReLU 节点若对大部分样本都输出 0,其负半轴梯度也是 0,可能成为“死亡节点”。可检查各层激活值分布,尝试降低学习率、调整初始化或使用允许负半轴有小梯度的激活函数。Dropout 只在训练阶段随机屏蔽部分激活,以减少节点之间的过度依赖;验证和正式预测时要切换为推理模式,否则同一输入会得到不稳定结果。

怀疑反向传播实现有错时,可以对一个很小的模型做数值梯度检查:把单个权重增加和减少一个很小的 ε,观察损失差,再与反向传播的梯度比较。它只用于调试,因为对每个参数重复计算损失太慢,不能代替日常训练。

图示可左右滑动查看前向计算预测与损失,反向计算各层梯度
前向计算预测与损失,反向计算各层梯度

你需要理解

  • 自动微分计算每个参数的梯度。
  • 优化器根据梯度更新参数。
  • 梯度消失或爆炸会让深层训练困难。
  • 初始化、归一化和残差连接有助于稳定训练。
再看一个实际场景

如果训练损失一直是 NaN,先取一个小批次查看输入是否有 NaN/无穷大、各层输出范围和梯度范数;若训练正常但验证变差,则优先排查过拟合,而不是继续调大网络。

注意

“梯度为 0”可能是已到平坦区域,也可能是 ReLU 长期关闭或计算图被意外断开。要结合损失曲线、各层梯度和激活分布判断。

05
预计 10 分钟

多类别分类

互斥类别通常使用 Softmax 和交叉熵;多标签任务则为每个标签独立输出概率。

多类别且互斥时,输出节点数量等于类别数。Softmax 把各类别分数转成总和为 1 的概率,训练常搭配交叉熵。例如猫、狗、鸟只能选一种。

如果一张图片可同时包含猫和狗,这不是互斥的多类别,而是多标签问题。应给每个标签单独的 Sigmoid 概率,并分别决定阈值。不要把两种任务的输出解释混为一谈。

你需要理解

  • 一对多简单但模型数量随类别增长。
  • Softmax 让类别概率总和为 1。
  • 多标签输出通常使用多个 sigmoid。
再看一个实际场景

猫 0.7、狗 0.2、鸟 0.1 是互斥多类别的一组 Softmax 输出;“猫 0.8、室内 0.9”是可同时成立的多标签输出。

整章演算案例

算一遍神经网络如何学习

两个已缩放到 0~1 的输入特征 x₁=0.8、x₂=0.2,真实二元标签 y=1。以下参数只是教学用初始值,训练会改变它们。

  1. 前向传播到隐藏层

    两个节点分别计算加权和,再经过 ReLU。h₁ 输出 0.7,h₂ 输出 0.2;不同节点有各自的权重和偏置。

    h₁=ReLU(0.8−0.2+0.1)=0.7;h₂=ReLU(−0.5×0.8+2×0.2+0.2)=0.2
  2. 输出概率

    输出层先得到分数 0.55,再通过 Sigmoid 转成约 0.634 的概率。线性回归通常直接输出连续值,二分类这里需要概率。

    z=1.5×0.7+0.5×0.2−0.6=0.55;p=1/(1+e⁻⁰·⁵⁵)≈0.634
  3. 计算损失

    因为真实标签为 1,二元交叉熵为 −ln(p),约 0.455。模型把真类别的概率给得越低,损失越大。

    L=−[y ln(p)+(1−y)ln(1−p)]=−ln(p)≈0.455
  4. 求梯度并更新

    Sigmoid 配合交叉熵时,输出分数处的梯度为 p−y≈−0.366。对输出权重 w₁ 还需乘 h₁,得到约 −0.256。学习率为 0.1 时,w₁ 从 1.5 更新到约 1.526。其余参数也要通过链式法则各自求梯度。

    ∂L/∂w₁=(p−y)h₁≈−0.256;w₁←1.5−0.1×(−0.256)≈1.526
  5. 重复训练并看验证集

    一次更新不能证明模型学会。实际会对许多样本和多个批次重复以上过程,并同时观察训练集与验证集;如果训练损失降而验证损失升,可能已经过拟合。

用 Python 复算
import math
x1, x2, y = 0.8, 0.2, 1
h1 = max(0, x1 - x2 + 0.1)
h2 = max(
    0, -0.5*x1 + 2*x2 + 0.2
)
z = 1.5*h1 + 0.5*h2 - 0.6
p = 1 / (1 + math.exp(-z))
loss = -math.log(p)
new_w1 = 1.5 - 0.1*(p-y)*h1
print(round(p, 3))       # 0.634
print(round(loss, 3))    # 0.455
print(round(new_w1, 3))  # 1.526

把它串起来:前向传播算预测,损失量错误,反向传播求梯度,优化器按梯度更新参数;这是一次训练迭代的完整链条。

参考与许可

本页依据 Google Machine Learning Crash Course 的课程结构与概念重新编写,文字和图示经过中文化重构。查看 Google 官方对应模块。Google 页面文字通常采用 CC BY 4.0,代码示例采用 Apache 2.0;第三方图片未直接复制。