Skip to content

第 12 章 神经网络基础

神经网络可以看成由许多神经元组成的函数。单个神经元先做线性组合,再经过非线性激活函数;多层神经元叠加后,模型就能表示比线性模型复杂得多的映射关系。

本章讨论最基础的一类神经网络:全连接神经网络,也叫多层感知机(Multilayer Perceptron, MLP)。后面的卷积神经网络、循环神经网络、Transformer 都是在这个基础上针对图像、序列等数据结构做出的改造。

12.1 神经元

一个神经元接收输入 x1,x2,,xn,给每个输入分配权重,再加上偏置:

z=w1x1+w2x2++wnxn+b

写成向量形式就是:

z=wTx+b

其中:

符号含义
x输入特征
w权重
b偏置
z加权求和结果

偏置 b 的作用是让函数可以平移。没有偏置时,模型表达会受到限制,例如很多分界面必须经过原点。

线性组合之后,神经元还会接一个激活函数:

a=g(z)

a 是神经元的输出,也叫激活值。

12.2 激活函数

如果网络中只有线性计算,多层网络仍然等价于一层线性模型。原因是多个线性变换叠加以后,结果仍然是线性变换:

W2(W1x)=(W2W1)x

因此,神经网络必须加入非线性激活函数。激活函数决定了神经元如何把线性结果 z 变成输出 a

常见激活函数:

激活函数公式特点
sigmoidσ(z)=11+ez输出在 0 到 1,常用于二分类输出层
tanhtanh(z)=ezezez+ez输出在 -1 到 1,零中心
ReLU(Rectified Linear Unit)max(0,z)计算简单,隐藏层最常用
Leaky ReLU$ \max(\alpha z,z)$负半轴保留很小斜率,缓解 ReLU 死亡问题

Leaky ReLU 中的 α 是负半轴斜率,通常取一个较小的正数,例如 0.01

可以配合这个页面看不同激活函数曲线:Visualising Activation Functions in Neural Networks

sigmoid 和 tanh

sigmoid 的输出在 0 到 1 之间,常用于二分类输出层,把输出解释为正类概率。它的问题是:当 z 很大或很小时,函数进入饱和区,导数非常接近 0。

tanh 的输出在 -1 到 1 之间,比 sigmoid 多了零中心特性,隐藏层中通常比 sigmoid 更容易训练。但 tanh 同样有饱和区,也会遇到梯度变小的问题。

ReLU

ReLU 在正半轴导数为 1,计算简单,训练深层网络时更常用:

ReLU(z)=max(0,z)

ReLU 的优点是不会在正半轴饱和,因此比 sigmoid、tanh 更不容易出现严重的梯度消失。

但 ReLU 也有问题:如果某个神经元长期落在负半轴,它的输出为 0,梯度也为 0,参数就很难继续更新。这种情况常叫 ReLU 死亡。实际中可以使用较小学习率,或使用 Leaky ReLU、ELU 等变体缓解。

梯度消失和梯度爆炸

反向传播时,梯度需要从输出层一层层传回输入层。这个过程会不断乘上各层的导数和权重。如果这些乘积长期小于 1,梯度会越传越小;如果长期大于 1,梯度会越传越大。

梯度消失指越靠近输入层,梯度越接近 0。结果是前面几层几乎学不动,参数更新很慢。sigmoid、tanh 在饱和区导数接近 0,因此深层网络中容易加重梯度消失。

梯度爆炸指梯度在反向传播中变得非常大。结果是参数更新过猛,损失函数剧烈震荡,甚至出现数值溢出。

常见现象:

问题训练表现常见原因
梯度消失loss 下降很慢,浅层参数几乎不更新激活函数饱和、网络太深、初始化不合适
梯度爆炸loss 剧烈震荡,可能变成 NaN学习率过大、权重尺度过大、反向传播连乘放大

常见缓解方法:

  • 使用 ReLU、Leaky ReLU 等激活函数。
  • 使用合适的参数初始化,例如 Xavier 初始化、He 初始化。
  • 使用 Batch Normalization 稳定中间层分布。
  • 对梯度做裁剪,尤其在循环神经网络中常见。
  • 调小学习率。

12.3 全连接神经网络

全连接神经网络的特点是:相邻两层之间的每个神经元都相互连接。

一个简单的全连接网络可以写成:

text
输入层 -> 隐藏层 -> 输出层

输入层只接收特征,不做真正的学习。隐藏层负责把原始特征转换成新的表示。输出层给出最终预测。

例如输入是房屋面积、房间数、楼层等特征,隐藏层中的不同神经元可能学习到不同组合:

  • 有的神经元更关注面积。
  • 有的神经元更关注位置和楼层。
  • 有的神经元更关注多个特征共同出现时的影响。

这些神经元的输出继续传给下一层,下一层再组合它们。神经网络的表达能力来自这种逐层组合。

全连接网络适合处理已经整理成特征向量的数据。对于图像、文本、语音这类有明显结构的数据,直接使用全连接网络通常不是最好选择,所以后面会引入 CNN、RNN、Transformer。

12.4 神经网络参数初始化

神经网络的权重不能全部初始化为 0。

如果同一层所有神经元的权重完全相同,它们在前向传播中会得到相同输出,在反向传播中也会得到相同梯度。训练之后这些神经元仍然相同,相当于多个神经元只学到同一个东西。这叫对称性问题。

因此,权重通常要随机初始化。初始化的目的在于让各层的信号在前向传播和反向传播中保持合适尺度。

12.5 Xavier 初始化

Xavier 初始化适合 sigmoid、tanh 这类近似对称、容易饱和的激活函数。它希望每一层输入和输出的方差尽量保持稳定,避免信号在层与层之间不断变大或变小。

设某一层输入神经元数量为 nin,输出神经元数量为 nout。Xavier 均匀初始化常写为:

WU(6nin+nout,6nin+nout)

其中 W 是当前层的权重矩阵,U(a,b) 表示在区间 [a,b] 上采样的均匀分布。

如果用正态分布形式,常见写法是:

WN(0,2nin+nout)

其中 N(μ,σ2) 表示均值为 μ、方差为 σ2 的正态分布。

它的直觉是:输入连接越多,单个权重就应该越小,否则一层线性组合后输出方差会被放大。

12.6 He 初始化

He 初始化主要用于 ReLU 及其变体。

ReLU 会把负半轴输出截断为 0,大约会让一部分神经元输出变成 0。为了补偿这种方差损失,He 初始化会给权重稍大的方差。

设某一层输入神经元数量为 nin。He 正态初始化常写为:

WN(0,2nin)

也就是说,权重标准差为:

2nin

He 均匀初始化常写为:

WU(6nin,6nin)

它适合 ReLU 的原因是:ReLU 让一部分输入变成 0,如果还按普通小随机数初始化,信号可能越传越弱。He 初始化把 ReLU 的这一点考虑进去,使前向传播的激活值和反向传播的梯度更稳定。

简单记法:

初始化常用激活函数核心思想
Xavier 初始化sigmoid、tanh稳定输入和输出方差
He 初始化ReLU、Leaky ReLU补偿 ReLU 截断负半轴带来的方差变化

偏置通常可以初始化为 0。权重需要随机初始化,并且尺度要和网络结构匹配。

12.7 前向传播

前向传播就是从输入层开始,一层一层算到输出层。

对某一层来说,计算过程是:

  1. 线性组合:z=wTx+b
  2. 激活函数:a=g(z)

多层网络就是重复这个过程:

text
输入 x
-> 第 1 层线性组合
-> 第 1 层激活
-> 第 2 层线性组合
-> 第 2 层激活
-> 输出预测

二分类任务中,输出层常用 sigmoid:

y^=σ(z)

y^ 表示样本属于正类的概率。

多分类任务中,输出层常用 softmax:

y^k=ezkj=1Kezj

其中 K 是类别数,y^k 表示第 k 类的预测概率。

12.8 反向传播

训练神经网络时,前向传播得到预测值,损失函数衡量预测值和真实标签的差距。反向传播计算每个参数的梯度,也就是参数应该往哪个方向调整,才能让损失下降。

反向传播主要依赖链式法则。

如果损失是 L,某个参数是 w,训练需要计算:

Lw

这个值表示:参数 w 变化一点,损失 L 会如何变化。

反向传播可以分成两步:

  1. 先计算输出层误差。
  2. 再把误差一层层传回前面的层。

每一层的权重梯度可以直观理解成:

text
当前层误差 × 上一层输出

所以某个连接权重的更新,既取决于当前层错得多不多,也取决于上一层给了多大的输入。

现代深度学习框架会自动完成反向传播,但理解它仍然重要。因为损失不下降、梯度消失、梯度爆炸、学习率不合适等问题,都要从前向传播和反向传播的角度排查。

12.9 完整训练过程

神经网络的完整训练过程如下:

  1. 准备训练集、验证集和测试集。
  2. 选择网络结构,例如隐藏层层数、每层神经元个数、激活函数。
  3. 随机初始化权重,初始化偏置。
  4. 前向传播,得到预测值。
  5. 计算损失函数。
  6. 反向传播,计算参数梯度。
  7. 用优化算法更新参数。
  8. 在验证集上观察效果,调整模型结构、学习率、正则化等超参数。
  9. 最后在测试集上评估模型泛化能力。

一次前向传播和一次反向传播只完成一次参数更新。实际训练时,这个过程会在许多 mini-batch 上重复很多轮。

完整流程可以概括为:

text
初始化参数 -> 前向传播 -> 计算损失 -> 反向传播 -> 更新参数 -> 重复训练

Powered by VitePress