Skip to content

神经网络基础与经典架构 ​

本页从离散输入、线性层和激活函数出发,逐步建立 MLP、CNN、RNN、LSTM 与 GRU 的结构和梯度直觉。

一、神经网络的基本组成 ​

神经网络由线性变换、偏置和非线性激活函数逐层组成。设 h(0)=x,第 ℓ 层可以写成:

a(ℓ)=W(ℓ)h(ℓ−1)+b(ℓ)h(ℓ)=ϕ(a(ℓ))

其中 W(ℓ) 和 b(ℓ) 是待学习参数,ϕ 是激活函数。最后一层的线性输出通常称为 logits,它们可以是任意实数,还没有被限制为概率;是否使用 Sigmoid 或 Softmax,要由任务的标签形式决定。

神经网络的输入和输出维度由任务决定,中间隐藏表示的宽度通常记为 hidden_dim。增大隐藏维度一般会增加模型的参数量、显存占用和计算量,但不保证泛化性能一定提升。

二、Embedding:从离散 token 到连续表示 ​

文本或类别特征不能直接把 token 的编号当作有序的连续数值输入神经网络。通常先由 tokenizer 将文本切分为 token,再把每个 token 映射为整数 ID;Embedding 层根据 ID 从可学习的矩阵中查出对应的稠密向量。

设词表大小为 V,Embedding 维度为 d,参数矩阵为:

E∈RV×d

对于 token ID j,Embedding 的输出是矩阵的第 j 行:

xj=Ej,:∈Rd,0≤j<V

这里的 j 是离散索引,不表示“这个 token 的数值大小”。例如,ID 为 523 的 token 不比 ID 为 12 的 token 更大或更重要;ID 只负责定位词表中的一行。

2.1 Tokenizer 与子词分词 ​

Tokenizer 在模型输入接口上的最终职责通常是把文本转换为整数 token ID 序列。这个过程可以拆成两步:先按照词、子词、字符或字节等规则切分出 token,再按照词表把每个 token 映射为整数 ID;Embedding 才负责把这些 ID 查表为连续向量。token 不一定对应完整单词,也可以是字符、字节或词的一部分。

在一个已经训练好的模型中,Tokenizer 的词表、切分规则和 token 到 ID 的映射通常在训练前确定,并在训练过程中保持固定;它们不是通过标准反向传播更新的连续参数。Embedding 则是神经网络中的可训练参数矩阵,梯度会更新与当前输入 token 对应的行。两者必须保持兼容:如果只替换 tokenizer,导致同一个 ID 对应了不同 token,原 Embedding 行的语义就会错位,通常需要同步调整词表相关参数并重新训练或转换模型。

完整词分词和字符分词各有明显缺点:

分词粒度优点代价
完整词常见词通常只占一个 token,序列较短词表很大,罕见词和新词容易变成未知词
单字符或单字节几乎不会遇到未知词序列很长,模型需要处理更多位置
子词(subword)在词表大小和序列长度之间折中,可复用词根、前缀和后缀同一词的切分依赖词表和具体算法

子词算法从较小的字符或字节单元出发,学习常见的相邻片段并将其作为词表项。例如:

text
playing → play + ing
player  → play + er
played  → play + ed

这样,词表不必为每个完整单词都保存独立条目,罕见词也有机会由已有子词组合表示。子词词表越大,通常序列越短但 Embedding 和输出层词表参数越多;词表越小,通常序列越长,后续 Transformer 的计算和位置数也会增加。

BPE:按相邻片段频率合并 ​

BPE(Byte-Pair Encoding)训练时从字符、字节或其他初始符号开始,反复执行以下过程:

  1. 统计当前语料中相邻 token 对的出现次数;
  2. 选择频率最高的相邻 token 对;
  3. 将它们合并成一个新 token,并加入词表;
  4. 持续合并,直到达到目标词表大小或满足停止条件。

因此 BPE 的核心判据是当前语料中的共现频率。训练完成后,推理阶段使用学习到的合并规则及其优先级,把新文本切分成词表中已有的子词。现代实现中常见 byte-level BPE,因此“从字符开始”不是所有 BPE 变体的硬性要求。

BPE 合并过程示例

假设初始符号按字符拆分,语料中出现:

text
l o w
l o w
l o w e r
n e w

如果 l 与 o 是当前频率最高的相邻对,就先合并为 lo;之后继续统计新的相邻对,例如 lo 与 w,再按照合并规则逐步形成更大的片段。最终得到的词表和合并顺序共同决定推理阶段的切分结果。

WordPiece:按语言模型目标选择片段 ​

WordPiece 同样学习子词词表,但合并时不只是选择出现次数最多的相邻对,而是更关注某次合并对语料概率模型或似然目标的改善。一个常见的直觉式评分可以写成:

score(a,b)∝freq(ab)freq(a)freq(b)

这个表达式用于说明:两个片段即使不是语料中绝对频率最高的 token,只要它们特别倾向于一起出现,合并后也可能更有价值。不同实现的具体训练目标和评分细节可能不同,但与 BPE 直接按频率合并的思想不同。

WordPiece 的常见推理策略是使用词表中的最长匹配片段进行切分,并用词内延续标记区分片段边界。BERT 使用的 WordPiece 词表通常用特殊前缀表示一个片段位于词内部。具体标记、预处理和未知词处理取决于 tokenizer 实现;子词算法能降低未知词概率,但不保证任何输入都不会产生未知 token。

BPE 与 WordPiece 的区别 ​

维度BPEWordPiece
基本类型子词分词子词分词
训练起点字符、字节或其他初始符号较小的词片段或字符单元
合并依据通常选择频率最高的相邻 token 对通常选择能带来更好概率/似然目标的合并
推理特点按已学习的合并顺序和优先级切分常见实现使用最长匹配策略
代表性应用GPT 早期及许多 byte-level tokenizer 变体BERT 系列
共同效果高频片段可合并为较大 token,罕见词可拆成多个已有子词高频片段可合并为较大 token,罕见词可拆成多个已有子词

即使使用完全相同的语料和目标词表大小,两种算法也不保证学出相同的词表,因为初始化符号、合并准则、边界标记和推理规则可能不同。

子词分词速记

BPE 主要按相邻片段频率合并;WordPiece 更关注合并对概率/似然目标的改善。二者都在完整词和字符之间折中,先产生 token ID,再由 Embedding 将 ID 映射为连续向量。

领域结构化文本的分词 ​

网络配置、命令行、日志和故障案例通常同时包含自然语言与大量结构化字段,例如命令关键字、IP 地址、MAC 地址、端口号、VLAN ID、OID、接口名、错误码和版本号。通用文本 tokenizer 可能把这些字段切得过碎,使模型需要额外学习原本可以由格式直接表达的结构。

例如下面的内容同时包含命令层级、接口路径和网络前缀:

text
display interface GigabitEthernet0/0/1
ip route 192.168.1.0/24 10.0.0.1
mac-address 00:1A:2B:3C:4D:5E

句点(.)、斜线(/)、冒号(:)、连字符以及大小写在不同字段中可能具有结构意义。将它们全部删除,或不加区分地把字符串拆成单字符,可能破坏地址层级、掩码、接口路径和标识符格式。因此领域 tokenizer 或预处理器通常需要:

  • 为命令关键字、常见协议术语、错误码和接口类型提供领域词表或受保护 token;
  • 识别 IP、MAC、端口、VLAN、OID 等字段的模式,在必要时将完整字段或结构化片段作为一个 span 处理;
  • 只进行不会改变语义的大小写、空白和别名归一化,并保留有结构作用的标点;
  • 对日志条目、命令块、告警事件和故障堆栈按语义边界切分,而不是从任意字符位置截断。

专用词表也不能简单等同于“把每个具体 IP 地址都加入词表”。IP、端口和 OID 等字段的取值空间很大且经常出现新值;将每个值都作为独立词表项会造成词表膨胀,并不能很好地处理未见过的地址。更常见的做法是固定高频命令和字段类型,对可变值使用模式化、分段化或受保护 span 表示。

分词只是输入表示的一部分。对于通信领域的检索或故障分析,还可以在领域语料上继续预训练或微调编码器,使 Embedding 更熟悉命令、告警和故障表述;检索侧则可以结合精确匹配与语义匹配:

检索信号更擅长处理的内容常见方法
词项和字段精确匹配命令名、错误码、接口名、IP 或版本号BM25、倒排索引、字段过滤
语义相似性不同措辞描述的相似故障、原因和解决方案领域 Embedding、向量检索、重排序
混合信号既要求关键字段一致,又要找到语义相近案例BM25 与向量检索融合,再进行重排序

因此,领域文本处理的目标不是单纯压缩字符串,而是在控制序列长度的同时保留字段结构,并让表示模型学习通信领域中的语义关系。

领域文本分词速记

结构化领域文本应保留命令、地址和标识符的格式信息,结合领域 tokenizer 与领域表示学习;日志和命令优先按语义单元切分,检索时可融合精确匹配与 Embedding 相似度。

2.2 查表、张量形状与参数量 ​

Embedding 的输入通常是整数 token ID,而不是已经计算好的词向量,也不要求显式构造 one-hot 向量。常见输入输出形状如下:

输入输出含义
单个 ID,形状为 ()d 维向量,形状为 (d,)查出一个 token 的表示
单条 ID 序列,形状为 (T,)(T,d)长度为 T 的序列表示
一个 batch,形状为 (B,T)(B,T,d)B 条长度为 T 的序列表示

如果只考虑 Embedding 矩阵本身,参数量为:

Nparam=Vd

Embedding 通常是查表层,不包含像全连接层那样的 bias;如果使用额外的投影层或其他参数,应单独计算。词表大小和向量维度决定参数量,序列长度不会增加这张查表矩阵的参数量,但会影响一次前向计算产生的激活数量和显存占用。

Embedding 参数量与输出形状示例

若词表大小为 V=50000、Embedding 维度为 d=768,则参数矩阵形状为 50000×768,参数量为:

50000×768=38,400,000

一条长度为 512 的 ID 序列形状是 (512,),经过查表后形状变为 (512,768);若 batch size 为 32,输出形状则为 (32,512,768)。前者是层的参数形状,后两者是具体输入产生的激活形状,三者不要混淆。

从数学上看,查表等价于 one-hot 向量与 Embedding 矩阵相乘。若 ej∈RV 是第 j 个 token 的 one-hot 列向量,则:

xj=ETej

但实际实现一般直接读取 Ej,:,不会为每个 token 构造长度为 V 的 one-hot 向量,因此可以显著节省中间存储和无效乘法。

Embedding 矩阵通常与模型一起通过梯度下降学习。对一次输入中出现的 token,反向传播会把对应输出向量的梯度累积到相应的矩阵行;离散 ID 本身不是连续可微参数,不会像普通权重那样被梯度改成另一个整数。重复出现的 token 会共享同一行参数,并累积来自各个位置的梯度。

Embedding 的表示边界

Token embedding 解决的是“离散 ID 如何表示为连续向量”,本身不是概率分布,也不自动表示 token 的顺序或当前句子的上下文。相同 token ID 在不同句子、不同位置查表时,得到的初始向量仍然相同;它与其他 token 的关系需要经过 Transformer 的 Self-Attention 等上下文层建模。序列模型通常还需要加入位置编码或位置 embedding,例如将 token 表示与对应位置表示相加。

Embedding 速记

Tokenizer 将文本变成整数 token ID 序列,Embedding 再将 ID 查表为稠密向量,Transformer Attention 最后根据上下文交互更新 token 表示;Embedding 参数量是词表大小乘 Embedding 维度,序列长度只决定一次输入的输出形状。

三、MLP 与隐藏层激活函数 ​

MLP(Multi-Layer Perceptron,多层感知机)通常由多个全连接层和隐藏层激活函数组成。例如,两层 MLP 可以抽象为:

h=ϕ(W2ϕ(W1x+b1)+b2)

隐藏层激活函数的核心作用是引入非线性,使 MLP 能够拟合复杂模式。若连续堆叠的层之间没有非线性激活,多个线性变换仍可合并为一个线性变换:

W2(W1x+b1)+b2=(W2W1)x+(W2b1+b2)

因此,仅增加没有激活函数的线性层,并不会带来同等意义上的非线性表达能力。激活函数的主要职责不是把输出变成概率、替代损失函数或完成归一化;这些工作分别由输出层、损失函数和归一化模块负责。

常见激活函数的基础公式、输出范围,以及 Sigmoid、Tanh、Softmax 在不同任务中的位置,已在机器学习基础的分类输出函数中整理。下面重点补充深度学习中常见的隐藏层激活函数和门控结构。

3.1 ReLU:分段线性与零点不可导 ​

ReLU(Rectified Linear Unit)定义为:

ReLU(x)=max(0,x)={x,x>00,x≤0

在 x>0 时,ReLU 保留输入;在 x<0 时,将输入置为 0。两侧的导数为:

ReLU′(x)={1,x>00,x<0

x=0 处左导数为 0、右导数为 1,因此严格来说不可导。神经网络实现会人为选择一个次梯度,常见约定是令 ReLU′(0)=0;代码中写成 x≤0 对应梯度为 0,属于工程约定,不表示数学上在零点存在唯一导数。

ReLU 的优点是计算简单、正区间梯度稳定,缺点是负区间梯度为 0。这表示梯度被截断或局部消失,并不是梯度爆炸。如果某个神经元长期落在负区间,它可能几乎不再获得有效梯度,形成“死亡 ReLU”。Leaky ReLU 在负区间保留一个小斜率:

LeakyReLU(x)=max(αx,x),α>0

它可以降低神经元永久失活的风险;PReLU 则进一步把 α 设为可学习参数。

Dead ReLU:形成条件与恢复边界 ​

设某个 ReLU 神经元的线性输入为:

z=wTx+b

如果一个 mini-batch 中的样本都满足 z<0,则:

f(z)=0,f′(z)=0

令上游梯度为 gf=∂L/∂f(z),根据链式法则:

∂L∂z=gff′(z)=0

于是该样本对这个神经元的入边参数不产生梯度:

∂L∂w=∂L∂zx=0,∂L∂b=∂L∂z=0

如果只有部分样本处于负区间,那么只会丢失这些样本在该神经元上的梯度;只有当神经元对绝大多数或全部训练样本都落在负区间时,才容易形成持续性的 Dead ReLU。

较大的学习率可能让一次参数更新跨过较大的区域,把神经元推到对多数样本都满足 z<0 的位置;不合适的初始化、过大的负偏置和输入分布偏移也可能增加这种风险。Dead ReLU 通常很难恢复,但“死亡”不是严格意义上的永久状态:如果前一层参数变化、输入分布变化或后续样本使 z 重新变为正数,神经元仍可能恢复激活。若它始终对所有样本处于负区间,且没有其他路径改变其输入,则其自身参数会因梯度为 0 而长期无法通过这条路径更新。

Leaky ReLU 在负区间的导数为 α>0,因此即使神经元暂时位于负区间,也能保留一条非零梯度路径,从而降低 Dead ReLU 风险。

3.2 GELU:连续的软门控 ​

GELU(Gaussian Error Linear Unit)使用标准正态分布的累积分布函数 Φ 产生连续门控:

GELU(x)=xΦ(x)

常用的近似形式为:

GELU(x)≈x2[1+tanh⁡(2π(x+0.044715x3))]

这里的 Φ(x) 是确定性的函数调用,不需要额外采样随机变量。与 ReLU 的硬阈值不同,GELU 对输入进行平滑衰减,负值通常不会被直接截断为 0。它处处连续且通常更平滑,但计算成本高于 ReLU,也不保证保持输入的均值或方差。

GELU 的导数可以写成:

GELU′(x)=Φ(x)+xφ(x)

其中 φ 是标准正态分布的概率密度函数。其导数峰值约为 1.13,因此最大梯度可以略大于 ReLU 的 1;这只说明局部梯度形状不同,不能单独据此断言 GELU 一定优于 ReLU。

3.3 ReLU 与 GELU 的梯度传播对比 ​

设激活层为 h=f(a),上游传来的梯度为 gh=∂L/∂h,则反向传播到激活输入时满足:

ga=ghf′(a)

对 ReLU 而言,正区间的局部梯度乘数为 1,负区间为 0,因此梯度要么原样通过,要么被截断;零点则需要按照前文所述的工程次梯度约定处理。对 GELU 而言,局部梯度随输入连续变化,例如:

GELU′(0)=Φ(0)+0⋅φ(0)=12

这意味着在零点附近,GELU 会把上游梯度乘以约 0.5,而不是像 ReLU 那样使用硬性的 0 或 1。当多层网络反复应用这些局部导数和权重矩阵时,差异可能累积:

∇h0L=J1TJ2T⋯JLT∇hLL

其中 Jℓ 表示第 ℓ 层的局部雅可比矩阵,包含线性变换和激活函数导数。因此,在某些固定初始化、输入分布和网络结构的实验中,GELU 可能使初始梯度的 ℓ2 范数小于 ReLU,尤其是在大量单元位于 GELU 的低斜率区域时;但这只是条件下的经验趋势,不是对所有模型都成立的定理。

零点附近的局部梯度示例

假设上游梯度为 gh=2。在 a=0 处,GELU 的局部梯度为 0.5,所以:

ga=2×0.5=1

ReLU 在 a=0 处数学上不可导,不能直接把某个取值称为它的“真实导数”。如果工程实现采用常见的次梯度约定 ReLU′(0)=0,则该点的反向值为 0;如果从 a>0 一侧观察,局部梯度乘数则为 1,上游梯度保持为 2。

激活函数与梯度范数

不能仅凭“GELU 的梯度更平滑”就断言替换 ReLU 后梯度范数一定显著减小。梯度大小还取决于输入分布、权重初始化、网络深度、LayerNorm、残差连接和损失函数;GELU 的导数在部分输入区域甚至大于 1。比较具体模型时,应在相同条件下实际统计梯度,而不是把题目中的趋势当作普遍规律。

3.4 SiLU、GLU 与 SwiGLU ​

SiLU(也常称 Swish)是另一种平滑自门控函数:

SiLU(x)=xσ(x)

其中 σ 是 Sigmoid。GLU(Gated Linear Unit)的基本思想是用一条分支产生门控信号,用另一条分支承载待调制的表示:

GLU(a,b)=a⊙g(b)

其中 g 是门控分支上的激活函数,⊙ 表示逐元素相乘。SwiGLU 使用 SiLU 作为门控函数,在 Transformer 的前馈子层中通常写成:

SwiGLU(x)=SiLU(xWg+bg)⊙(xWu+bu)

随后再通过输出投影映射回模型隐藏维度:

FFNSwiGLU(x)=SwiGLU(x)Wd+bd

因此,SwiGLU 不是把一个标量激活函数逐元素应用一次,而是由两条线性投影分支、一个 SiLU 门控和一个输出投影共同构成的前馈结构。它通常比单个 GELU 前馈层包含更多投影参数,实际设计会调整中间维度,使总参数量和计算量处于可接受范围。GeGLU 等变体则使用 GELU 等其他函数替换门控分支中的 SiLU。

SwiGLU 常见于现代 Transformer 的 FFN,但这不意味着它在所有模型中都必然取代 GELU。激活函数或门控结构的选择还要结合模型架构、参数预算、吞吐量和验证集效果判断。

3.5 常见激活函数的对比 ​

函数或结构核心机制梯度与数值特点常见位置
ReLU负值截断,正值线性通过计算便宜;负区间梯度为 0;零点数学上不可导MLP、CNN 隐藏层
Leaky ReLU负区间保留小斜率降低死亡 ReLU 风险,但引入超参数 α对 ReLU 的改进版本
GELU使用 Φ(x) 的连续门控平滑;梯度峰值约为 1.13;计算比 ReLU 更复杂Transformer、部分 MLP
SiLU / Swish输入与 Sigmoid 门控相乘平滑、自门控;常作为门控分支激活深度网络、Transformer 变体
SwiGLUSiLU 门控分支与线性分支逐元素相乘表达能力强,但需要额外投影和计算Transformer FFN

3.6 饱和激活、阶跃函数与梯度可用性 ​

Sigmoid 和 Tanh 的任务位置与基本性质可参见机器学习基础的分类输出函数。从反向传播角度看,它们的共同问题是:输入绝对值较大时,函数进入饱和区,局部导数接近 0。

Sigmoid 的导数为:

σ′(x)=σ(x)(1−σ(x))

当 x 很大或很小时,σ(x) 接近 1 或 0,导数都会接近 0。

因为 σ(x)(1−σ(x)) 在 σ(x)=12 时达到最大值,而 σ(0)=12,所以:

σ′(0)=12(1−12)=14

这说明 Sigmoid 在输入为 0 附近的梯度最大,远离 0 后进入饱和区,梯度逐渐变小。

Tanh 的导数为:

tanh′⁡(x)=1−tanh2⁡(x)

Tanh 的严格输出范围是 (−1,1),教材有时写成 [−1,1] 来强调它是有界函数;同时 tanh⁡(0)=0,所以输出以 0 为中心。这里的“零中心”描述的是函数的对称性,并不保证任意一批输入经过 Tanh 后的样本均值恰好等于 0。与 Sigmoid 的导数上界 14 相比,Tanh 在 x=0 附近的导数最大为 1,因此传统网络中常作为隐藏层激活;但当输入绝对值变大、输出接近 −1 或 1 时,导数同样会趋近于 0。在多层网络中,许多小于 1 的局部导数连续相乘,容易造成梯度逐层衰减,也就是梯度消失。

阶跃函数可以抽象为:

H(x)={0,x<01,x≥0

它在阈值处不连续,阈值点没有普通导数;在其他位置导数几乎处处为 0。因此,阶跃函数不能直接为标准梯度下降提供有用的反向信号。量化网络或脉冲神经网络如果需要使用离散阶跃行为,通常会额外采用直通估计器或代理梯度,但那已经不是原始阶跃函数的普通导数。

ReLU 在正区间的导数为常数 1,所以对于处于激活状态的单元,ReLU 本身不会像 Sigmoid 或 Tanh 的饱和区那样缩小梯度。这是 ReLU 适合深层网络、并成为许多 MLP 和 CNN 默认选择的重要原因之一。不过,ReLU 的负区间导数为 0,并且整个网络的梯度还会受到权重矩阵、网络深度和残差结构影响,因此不能把“正区间梯度为 1”理解为深层网络绝不会发生梯度消失。

函数局部梯度特征反向传播中的主要问题
Sigmoidx=0 处导数最大为 14,大输入绝对值时趋近 0容易饱和并导致梯度消失
Tanh输出范围为 (−1,1) 且零中心,x=0 附近导数最大为 1大绝对值输入下容易梯度消失
阶跃函数几乎处处导数为 0,阈值处不可导无法直接提供有效的梯度下降信号
ReLU正区间为 1,负区间为 0激活单元不饱和,但可能出现死亡 ReLU

激活函数梯度速记

Sigmoid/Tanh 的饱和区会让导数接近 0;阶跃函数几乎处处没有可用梯度;ReLU 的正区间梯度为 1,能减轻激活函数造成的梯度衰减,但不保证整个深层网络没有梯度消失。

选择激活函数时,先区分它承担的角色:隐藏层激活主要提供非线性,输出层的 Sigmoid 或 Softmax 则由标签形式决定;损失函数仍然负责定义训练目标。平滑激活或门控结构可能改善优化和表达能力,但也会增加计算、参数或实现复杂度,应结合验证集指标和资源约束评估。

MLP 与激活函数速记

线性层负责变换表示,激活函数负责引入非线性;没有隐藏层非线性时,深层线性网络仍然只是一个线性模型。

四、卷积神经网络基础 ​

卷积神经网络(CNN)利用局部连接和参数共享提取空间结构特征。与全连接层相比,一个卷积核只连接局部区域,并在不同空间位置复用同一组权重,因此参数量通常与特征图的空间尺寸无关。

4.1 卷积输出尺寸与参数量 ​

对于输入空间尺寸为 H×W 的二维卷积,卷积核尺寸为 Kh×Kw,padding 为 P,stride 为 S,dilation 为 D 时,输出空间尺寸通常为:

Hout=⌊H+2P−D(Kh−1)−1S⌋+1Wout=⌊W+2P−D(Kw−1)−1S⌋+1

当输入为正方形(H=W)、D=1 且卷积核为正方形 K×K 时,公式可简化为:

Hout=Wout=⌊H+2P−KS⌋+1

普通卷积的每个卷积核都会跨越全部输入通道。输入为 H×W×Cin、卷积核为 Kh×Kw 时,单个卷积核的权重形状是 Kh×Kw×Cin;卷积核数量就是输出通道数 Cout。

卷积输出尺寸示例

输入为 224×224×3,使用 5 个 7×7 卷积核,且 P=1、S=1、D=1:

Hout=224+2×1−71+1=220

宽度同理,因此输出形状为 220×220×5。每个卷积核的完整形状是 7×7×3,而不是只覆盖一个通道的 7×7。

如果使用 bias,普通卷积的可训练参数量为:

Nparam=KhKwCinCout+Cout

其中最后一项是每个输出通道对应的一个偏置;如果关闭 bias,则去掉该项。输入的 H、W、stride 和 padding 会影响输出特征图尺寸,但不会改变卷积核参数量。

卷积参数量示例

卷积核为 5×5、输入通道数为 3、输出通道数为 16,并且每个输出通道使用一个 bias 时:

Nparam=5×5×3×16+16=1216

stride、padding 和输入特征图的空间尺寸只影响输出形状,不影响这个参数量。

4.2 1×1 卷积、步幅卷积与池化 ​

当 stride 为 1 时,1×1 卷积不扩大空间邻域,主要用于改变或融合通道:

H×W×Cin⟶H×W×Cout

在每一个空间位置,它等价于对通道向量做一次线性变换:

yh,w=Wxh,w+b

因此,1×1 卷积可以融合通道信息、降维或升维,并且可以与后续激活函数组合;如果它的 stride 大于 1,空间尺寸也会随之下采样。

stride 大于 1 的卷积可以同时完成特征提取和下采样。与 Max Pooling 固定选择窗口中的最大值不同,步幅卷积的卷积核权重通过训练学习,因此网络可以学习下采样时应保留哪些模式。

Max Pooling 则在局部窗口中保留最大响应:

yh,w,c=max(i,j)∈Wxh+i,w+j,c

它没有可训练参数,通常只沿空间维度操作,不负责通道混合。池化可以降低空间尺寸和后续计算量,并对窗口内的小幅平移提供一定鲁棒性;但它会丢失精确位置信息,也不是严格的去噪算法。如果噪声在窗口中形成异常大的响应,Max Pooling 反而可能把噪声保留下来。

操作参数是否可学习主要作用典型代价或边界
stride 卷积是特征提取并学习下采样方式有卷积参数和计算量
Max Pooling否保留局部强响应并降低空间尺寸丢失精确位置,不能保证去噪
1×1 卷积是通道融合、降维或升维stride 为 1 时不扩大空间感受野

4.3 感受野与小卷积核堆叠 ​

感受野是某个特征位置在输入上能够看到的区域。对连续卷积层,可以用感受野大小 rℓ 和相邻特征位置在输入上的间隔 jℓ 递推:

r0=1,j0=1rℓ=rℓ−1+(Kℓ−1)Dℓjℓ−1jℓ=jℓ−1Sℓ

在 stride 和 dilation 都为 1 时,两个连续的 3×3 卷积的感受野为:

3+(3−1)=5

三个连续的 3×3 卷积则可以获得 7×7 的理论感受野。假设中间通道数都为 C 且忽略 bias,一个 5×5 卷积需要约 25C2 个权重,而两个 3×3 卷积需要约 18C2 个权重;后者还可以在卷积层之间插入额外的非线性激活。

小卷积核堆叠并不意味着实际效果一定优于大卷积核,还需要考虑网络深度、内存访问、优化难度和任务数据;“感受野相同”也不等于模型学到的特征完全相同。

4.4 深度可分离卷积 ​

深度可分离卷积(Depthwise Separable Convolution)把普通卷积拆成两个阶段:

  1. Depthwise Conv:每个输入通道单独使用空间卷积核,不在通道之间混合信息;
  2. Pointwise Conv:使用 1×1 卷积融合通道,并生成所需的输出通道。
空间特征提取⟶通道信息融合

在 depthwise multiplier 为 1 且忽略 bias 时,Depthwise 阶段的参数量为 KhKwCin,Pointwise 阶段的参数量为 CinCout,总参数量为:

NDW-PW=KhKwCin+CinCout

普通卷积的对应参数量是 KhKwCinCout。当通道数较大时,拆分后通常可以显著减少参数和乘加计算。

深度可分离卷积的参数量示例

设 K=3、Cin=32、Cout=64,忽略 bias。普通卷积需要:

3×3×32×64=18432

Depthwise 和 Pointwise 分别需要:

3×3×32=2881×1×32×64=2048

合计为 2336,约为普通卷积权重数量的 12.7%。MobileNet V1 的核心就是这种深度可分离卷积;MobileNet V2 进一步引入 inverted residual 和 linear bottleneck,MobileNet V3 又加入 SE 和 h-swish 等设计。

4.5 空洞卷积 ​

空洞卷积(Dilated Convolution)在卷积核采样点之间插入间隔,用更大的覆盖范围获得更大的感受野。有效卷积核尺寸为:

Keff=K+(K−1)(D−1)

例如 K=3、D=2 时,Keff=5。实际卷积核仍然只有 3×3 个权重位置,因此在输入通道和输出通道不变、忽略 bias 时,参数量仍按 3×3CinCout 计算,而不是按 5×5 计算。

空洞卷积常在 S=1 时配合合适的 padding 使用,从而扩大感受野但尽量保留空间分辨率,适合语义分割等需要兼顾上下文和定位精度的任务。它不会因为“打孔”就自动减少乘加次数;同样大小的基础卷积核仍然要计算相同数量的采样点,较大的 dilation 还可能带来稀疏采样和 gridding artifact 等问题。

CNN 速记

卷积参数量由卷积核尺寸和通道数决定,不由特征图的高宽决定;1×1 卷积调通道,stride 卷积学习下采样,池化固定保留局部响应;小卷积核堆叠可扩大感受野,Depthwise 管空间、Pointwise 管通道,空洞卷积用稀疏采样扩大感受野。

五、循环神经网络:RNN、LSTM 与 GRU ​

循环神经网络(RNN)通过在时间步之间传递隐藏状态,将序列的历史信息带入当前计算。它适合处理时间序列、文本、语音等具有顺序关系的数据;与只根据当前输入独立计算的前馈网络相比,RNN 的关键是跨时间步复用同一组参数。

5.1 RNN 的递归计算与时间反向传播 ​

最基本的 RNN 可以写成:

ht=ϕ(Wxxt+Whht−1+bh)y^t=g(Wyht+by)

其中 xt 是当前输入,ht 是当前隐藏状态,ht−1 携带过去的信息,ϕ 和 g 分别表示隐藏层与输出层的变换。Wx、Wh 和 Wy 在不同时间步之间共享,因此序列变长时不会为每个时间步新增一套参数。

训练 RNN 通常需要沿时间展开计算图并执行 BPTT(Backpropagation Through Time)。以只在最后时刻产生损失的情形为例,跨越较长序列时,梯度会连续乘上循环层的局部 Jacobian:

∂L∂h1=∂L∂hT∂hT∂hT−1⋯∂h2∂h1

如果这些矩阵乘积的范数持续小于 1,容易出现梯度消失;如果持续大于 1,则可能出现梯度爆炸。因此,普通 RNN 对长期依赖的学习能力有限,实际训练还可能结合梯度裁剪等手段缓解梯度爆炸。

5.2 LSTM:用门控维护细胞状态 ​

LSTM 在隐藏状态 ht 之外引入细胞状态 ct,并通过三个门控制信息的保留、写入和输出。令:

qt=[ht−1,xt]

其中方括号表示向量拼接,则三个门和候选记忆可以写成:

ft=σ(Wfqt+bf)it=σ(Wiqt+bi)c~t=tanh⁡(Wcqt+bc)ot=σ(Woqt+bo)

细胞状态和隐藏状态的更新为:

ct=ft⊙ct−1+it⊙c~tht=ot⊙tanh⁡(ct)

其中 ft、it、ot 是三个门,c~t 是候选新记忆,不是第四个门。由于门使用 Sigmoid,它们的每个分量通常位于 (0,1),可以理解为软性的保留比例、写入比例和输出比例。

遗忘门主要筛选上一时刻的细胞状态 ct−1,并不是直接把隐藏状态 ht−1 按比例保留;ht−1 会参与计算各个门,但长期记忆的载体是 ct。细胞状态中的加法路径使信息和梯度可以更稳定地跨越多个时间步,从而缓解普通 RNN 的长期依赖问题,但 LSTM 仍不保证完全没有梯度消失或爆炸。

组件作用
遗忘门 ft决定旧细胞状态 ct−1 保留多少
输入门 it决定候选记忆 c~t 写入多少
候选记忆 c~t根据当前输入和历史隐藏状态生成待写入内容
输出门 ot决定细胞状态中有多少暴露为当前隐藏状态 ht

5.3 GRU:更简化的门控循环单元 ​

GRU 将细胞状态和隐藏状态合并为一个状态 ht,通常使用更新门和重置门:

zt=σ(Wzxt+Uzht−1+bz)rt=σ(Wrxt+Urht−1+br)h~t=tanh⁡(Whxt+Uh(rt⊙ht−1)+bh)ht=(1−zt)⊙ht−1+zt⊙h~t

这里 zt 控制旧状态与候选状态的混合比例,rt 控制生成候选状态时使用多少旧状态。不同实现可能对更新门的符号约定相反,但“保留旧状态与写入候选状态之间的门控插值”这一结构不变。

GRU 没有独立的细胞状态和输出门,结构比 LSTM 简单,通常参数更少、计算成本更低、训练速度更快;代价是状态控制更耦合,在某些需要精细区分长期记忆和短期输出的任务中,表达取舍可能不同。

在输入维度为 dx、隐藏维度为 dh 且只比较循环单元内部投影、包含 bias 的粗略条件下,RNN、GRU 和 LSTM 分别大约包含 1、3 和 4 组形状为 (dx+dh)×dh 的仿射参数。因此,GRU 通常位于 RNN 的表达能力与 LSTM 的门控能力之间,是性能和计算效率之间的常见折中。

模型状态结构主要特点常见取舍
RNN一个隐藏状态 ht结构简单、计算便宜长期依赖下容易梯度消失或爆炸
LSTM隐藏状态 ht 与细胞状态 ct,三个门对长期记忆控制更细致参数和计算开销较大
GRU一个隐藏状态,更新门和重置门简化门控,参数和计算通常少于 LSTM记忆与输出控制没有 LSTM 分离得细

传统序列建模中,短序列可以使用普通 RNN,存在长期依赖时通常优先考虑 LSTM 或 GRU;现代长文本生成和长上下文建模则更多使用 Transformer。模型选择仍需结合序列长度、数据规模、延迟和验证集效果,而不能只按“结构越复杂越好”判断。

RNN、LSTM、GRU 速记

RNN 把 ht−1 带到当前;LSTM 用 f 保留旧细胞状态、用 i 写入候选记忆、用 o 产生隐藏输出;GRU 去掉独立的 ct 和输出门,用更少的门完成状态更新。

使用 Markdown 与 VitePress 构建