
第一次把二十多种神经网络画在同一张纸上是在一个项目选型的下午。那天我打算从零搭一个识别类任务的原型脑子里飞速过了一遍手头能用的结构结果发现一个尴尬的事实能叫出名字的模型有几十个能说清“它为什么长这样、什么时候该用它”的不超过十个。后来我把它们全部画成示意图贴在墙上按发表年份从左到右排越看越乱——因为时间线只告诉你谁先谁后不告诉你谁替代了谁、谁和谁是同一族。真正的转折点是我把排序方式换成“数据怎么流动、形状怎么变、训练信号从哪来”整张图才突然清晰起来。这篇要聊的就是那套重新排序后的神经网络图解。它会覆盖 27 种常见结构的核心机制、输入输出形状、参数量怎么手算、以及在实际项目里选型的判断依据。适合两类人看一类是刚把反向传播搞明白、想建立全局地图的入门者另一类是做过几个项目、但每次选模型还是靠“听说这个好用”的实践者。我尽量不写成论文摘要合集而是按“这类结构在解决什么麻烦”来讲中间夹一些我踩过的坑和手算参数的例子方便你直接拿去对着自己的任务做判断。1. 二十七个模型排成一行会看晕根源是排序维度选错了大多数“神经网络大全”类的图解排序逻辑是发表时间。感知机在最左边卷积网络在中间Transformer 在右边看起来很整齐但它传递的隐性信息是“后面的比前面的高级”。这个暗示非常有害因为它会让人误以为新结构是旧结构的全面替代。实际情况是很多老结构在特定数据规模下依然是最优解而很多新结构在样本量不足时表现远不如一个老老实实的全连接网络。我后来用的是三个正交维度来做分组。第一个维度是连接拓扑也就是神经元之间怎么连全连接、局部连接加权重共享、带环的递归连接、全局两两相连的注意力、按图边连的消息传递。第二个维度是输入的数据形状向量、二维网格、变长序列、图结构、事件流。第三个维度是训练信号的形式监督标签、重建目标、对抗博弈、变分下界、去噪目标。这三个维度一交叉很多看起来孤立的模型会立刻归位自编码器和生成对抗网络在拓扑上都属于“编码器—解码器”这一类区别只在训练信号卷积网络和视觉 Transformer 在输入形状上完全一样区别只在拓扑。一个判断技巧如果你说不清某个模型“属于哪一族”先问自己它的训练信号是什么。训练信号相同、拓扑相近的模型改造思路往往是通用的迁移经验也最有效。这个分组还有一个附带好处就是能解释“为什么有些当年的明星模型消失了”。它们不是被更强的模型打败而是被同一族里更省参数或更稳定的变体替代了。理解了族的边界你就不会在新模型出来时慌因为九成情况下它只是族内的一次参数效率优化。2. 先搭一张定位底图27 种结构的四列速查表下面这张表是我自己用的版本四列分别是“输入形状”“核心算子”“一句话定位”。它不追求严谨的数学定义追求的是你在三五秒内想起它长什么样。编号结构输入形状核心算子一句话定位1感知机向量加权求和 阶跃单层线性划分只能切一刀2多层感知机向量全连接 非线性万能逼近的基本盘3径向基网络向量距离 高斯核局部响应小样本插值4自组织映射向量竞争 邻域更新无监督降维与拓扑保序5自适应共振网络向量相似度 警戒阈值解决稳定性与可塑性冲突6卷积网络二维网格局部卷积 池化平移等变的特征提取器7残差网络二维网格卷积 恒等捷径让极深网络可训练8密集连接网络二维网格逐层拼接特征复用参数更省9轻量可分离卷积网络二维网格深度卷积 逐点卷积移动端算力友好10全卷积网络二维网格卷积替代全连接逐像素输出11U 型编解码网络二维网格下采样 跳跃连接精细分割与复原12循环网络变长序列隐状态递推序列建模的起点13长短期记忆网络变长序列三门 细胞状态长依赖记忆14门控循环单元变长序列两门合并LSTM 的轻量替代15双向循环网络变长序列正反两向递推上下文双向融合16时序卷积网络变长序列膨胀因果卷积并行化的序列建模17注意力序列模型序列对序列对齐权重求和打破定长瓶颈18Transformer序列 / 集合多头自注意力全局依赖一次建模19双向编码器序列双向注意力 掩码语言建模理解型表征20自回归解码器序列因果掩码注意力生成型表征21视觉 Transformer图像块序列分块 自注意力图像上的全局建模22自编码器任意编码 解码重建无监督特征压缩23变分自编码器任意重参数化 KL 约束可采样的连续潜空间24生成对抗网络噪声向量生成器与判别器博弈高保真样本合成25扩散模型噪声 条件加噪与去噪回归稳定训练的生成范式26图神经网络图结构邻域聚合与消息传递非欧几里得关系建模27脉冲神经网络事件流膜电位累积与发放时序稀疏的事件驱动读这张表有个小方法不要横向读纵向读。先看“核心算子”这一列你会发现真正的新算子只有五类——加权求和、卷积、递推、注意力、聚合。剩下的二十多个模型本质上是这五类算子的不同堆叠方式与不同训练目标。把这一层看透你的记忆负担会从二十七个降到五个。2.1 参数量必须能手算这是选型的第一道闸门我在做方案评审时最常问的一个问题是“这个模型大概多少参数”如果对方答不上来基本可以判断他没真正落地过。参数量不是学术指标它直接决定显存占用、推理延迟和是否能塞进目标设备。三个基础公式必须背下来。全连接层参数量等于输入维度乘输出维度再加输出维度偏置。输入 512 维、输出 256 维就是 512×256256131328约 13 万。卷积层参数量等于卷积核宽乘高乘输入通道数乘输出通道数再加输出通道数的偏置。输入三通道、用 3×3 核、输出 64 通道就是 3×3×3×64641792。注意卷积参数量与输入图像的尺寸完全无关这正是它比全连接省参数的根本原因——一张 224×224 的图接一个 512 维全连接层参数量是 224×224×3×512 约七千七百万而同样输入接 64 通道的 3×3 卷积只要 1792。循环层以 LSTM 为例参数量等于四倍的门结构参数公式是 4×(隐藏维度×(输入维度隐藏维度)隐藏维度)。输入 64 维、隐藏 128 维就是 4×(128×192128)98816接近十万。我习惯在纸上先算这三笔账再决定要不要看论文细节。很多时候一笔账算完方案就不用讨论了目标设备只有几百 KB 的模型存储空间那你只能在轻量卷积或小型循环网络里挑再大的结构都是空谈。3. 前馈与经典联想派感知机到自组织映射的朴素智慧这一族的共同点是“一次性前向传播没有时间维度”。它们是最容易被轻视的一批但我见过太多项目在这些结构上翻车恰恰是因为大家觉得它们太简单跳过了必要的检查。3.1 多层感知机万能逼近的前提条件常被忽略多层感知机的理论保证是“足够宽的单隐层网络可以逼近任意连续函数”但这句话里有三个隐藏前提激活函数必须非线性、隐层宽度可以任意大、权重可以任意精确。工程上这三个前提全部不成立所以“理论上能拟合”和“实际能训出来”是两件事。非线性激活的必要性可以用一个反例说明。两层线性网络叠起来等价于一次线性变换深度完全浪费。这也是为什么早期用阶跃函数时网络训不动——阶跃函数的导数几乎处处为零梯度传不回去。后来换成平滑的饱和函数再换成不饱和的整流函数才解决了深层网络的梯度问题。宽度与深度的取舍我有个粗糙的经验法则同等参数量下优先加深度但深度超过一定层数后必须加捷径连接。原因是深层网络表达同样函数所需的参数量通常更少但深到一定程度会出现退化——训练误差不降反升这不是过拟合而是优化困难。这个现象直接催生了后面要讲的残差结构。3.2 径向基网络为什么它适合小样本却难做大径向基网络的隐层不是做加权求和再激活而是计算输入到每个“中心点”的距离再过一个钟形函数。它的输出是若干局部响应的加权组合每个隐单元只对输入空间中某个邻域敏感。这个设计带来两个直接后果。好处是局部性让它的学习速度很快少量样本就能把中心点挪到合适位置插值行为也平滑所以在一些样本极少的回归拟合场景里它比多层感知机更稳。坏处是维度一高就麻烦输入维度是 d要覆盖整个空间所需的中心点数量大致随维度指数增长这就是维度灾难在局部方法上的体现。我在一个几十维的传感器数据回归任务里试过径向基网络样本只有几百条时它确实赢过多层感知机但把维度提到上百之后中心点怎么初始化都救不回来。3.3 自组织映射与自适应共振两个无监督的老思路自组织映射做的是“把高维数据压到低维网格上同时尽量保持邻近关系”。训练时对每个输入找最相似的网格节点然后不仅更新这个节点还更新它周围一圈邻居。这个邻域更新是精髓它让整个网格形成一种拓扑保序的映射——原始空间里相近的样本落到网格上位置也相近。我在做高维特征的可视化时用过它效果比直接做主成分分析更有“结构感”因为主成分分析是线性的只能给你几个方向的投影而自组织映射能展示出簇的相对位置。它的坑在于邻域半径和更新幅度的退火策略退火太快网格会碎成一堆孤立点退火太慢则训练时间不可控。自适应共振网络解决的是一个更哲学的问题网络既要能学新东西可塑性又不能学了新东西就把旧的忘光稳定性。它的做法是给每个类别维护一个原型新样本进来先算相似度超过警戒阈值就归入已有类别并微调原型低于阈值才新建类别。这个机制在增量学习场景里非常实用我见过用它在流式数据上做在线聚类的方案不需要预先指定类别数。警戒阈值是唯一的灵魂参数调高会导致类别爆炸调低会导致不同模式被强行合并。这一族最容易被忽略的实操细节是输入标准化。径向基网络和自组织映射都对量纲极其敏感某个特征取值范围是另一个的一千倍距离计算就完全被它主导了。我吃过这个亏调了两天模型结构最后发现问题出在忘了做归一化。4. 卷积家族ResNet、DenseNet、轻量卷积与 U 型网络各自在补什么短板卷积这一族是结构演化最清晰的一组每一代都在补上一代的一个具体缺陷。理解这条演化链比单独记每个模型的结构图有用得多。4.1 从卷积尺寸公式推导出的三个工程约束先把手算能力建立起来。输出尺寸公式是输入尺寸 − 卷积核 2×填充除以步长再加一。输入 224、核 3、填充 1、步长 1输出还是 224步长改成 2输出变成 112。这个公式决定了三件事下采样的位置、特征图尺寸的匹配、以及残差连接能不能直接相加。参数量前面算过与输入尺寸无关。但如果加上计算量就要另算了浮点运算次数大致是输出尺寸的宽乘高、乘核宽高、乘输入通道、乘输出通道。这意味着计算量随空间尺寸线性增长随通道数平方增长所以设计网络时通道数的增长要克制通常在空间下采样两倍的同时把通道数翻倍让计算量大致守恒。感受野的递推公式是新感受野等于旧感受野加上核尺寸减一乘当前累计步长累计步长逐层相乘。三层 3×3 卷积、步长都是 1感受野是 12227。如果步长是 1、2、2感受野会更大。这个数字很关键它决定了网络“看得多远”如果你的任务需要判断全局形状而感受野只有几十像素那不管加多少层都没用。4.2 残差、密集连接、轻量卷积三种省法残差结构解决的是深层网络的退化问题。做法是把输入直接加到输出上让网络学的是“残差”而不是完整映射。很多人把它解释成梯度高速公路这没错但不完整。另一个同样重要的效果是恒等映射变得容易学如果某一层什么都不做是最优的网络只要把残差学成零就行这在优化上比“用一堆权重拼出恒等变换”容易太多。import torch import torch.nn as nn class BasicResidualBlock(nn.Module): def __init__(self, channels): super().__init__() self.conv1 nn.Conv2d(channels, channels, 3, padding1, biasFalse) self.bn1 nn.BatchNorm2d(channels) self.conv2 nn.Conv2d(channels, channels, 3, padding1, biasFalse) self.bn2 nn.BatchNorm2d(channels) self.relu nn.ReLU(inplaceTrue) def forward(self, x): identity x out self.relu(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) out out identity return self.relu(out)这个块在 64 通道时的参数量是两个 3×3×64×64 加偏置约 7.4 万。注意卷积层关了偏置因为后面紧跟批归一化偏置会被归一化抵消纯属浪费参数。密集连接网络走的是另一条路每一层的输出都拼接到后面所有层的输入上。它的直接好处是特征复用浅层提取的边缘信息可以直接被深层用到不需要靠层层传递。参数效率很高因为每层的通道数可以设得很小靠拼接凑够宽度。代价是显存占用大因为拼接产生的中间特征都要保存下来做反向传播我在显存紧张时最先砍的就是这一类结构。轻量可分离卷积则是把标准卷积拆成两步先每个通道单独做空间卷积再用 1×1 卷积做通道混合。参数量对比很直观输入输出都是 64 通道、3×3 核的情况下标准卷积是 3×3×64×6436864可分离卷积是 3×3×1×64 加上 1×1×64×64等于 57640964672只有原来的约八分之一。精度损失通常在几个百分点以内在端侧部署里这个交换非常划算。4.3 全卷积与 U 型结构把分辨率找回来全卷积网络的核心思想简单粗暴既然分类网络最后用全连接层把空间信息压没了那就干脆不要全连接层全部用卷积输出一张和输入同尺寸的分数图。这个改动让网络可以接受任意尺寸输入也让逐像素任务成为可能。但粗暴下采样会丢细节。U 型结构的解法是跳跃连接把编码阶段的高分辨率特征直接接到解码阶段的对应层上让解码器在恢复尺寸时能拿到原始细节。这个设计在医学图像和遥感图像的分割里几乎是默认选项因为那些任务的边界精度要求极高光靠上采样插值恢复不出来。我在这类结构上踩过的坑是通道数不匹配。跳跃连接要做拼接时两边的通道数必须能对上而下采样路径和上采样路径的通道规划很容易算错报错信息又只告诉你维度不一致找起来很费时间。后来我养成习惯先在纸上把每一层的空间尺寸和通道数全部列一遍再动手写代码。5. 循环网络三兄弟与时间卷积门控究竟在门什么序列建模这一族的演化逻辑和卷积完全不同。卷积的问题是感受野有限序列的问题是记忆有限。5.1 朴素循环网络为什么会忘事循环网络把上一步的隐状态和当前输入拼在一起过一个全连接层得到新隐状态。训练时梯度要沿着时间步一路回传这叫沿时间反向传播。问题在于每一步都要乘一次权重矩阵序列长了之后这个连乘要么趋近于零要么爆炸。梯度消失不是抽象概念它是连乘的直接数学后果。我用一个具体的数字说明。假设每步的雅可比矩阵谱半径是 0.9回传五十步之后就是 0.9 的五十次方约等于 0.005梯度几乎消失了。谱半径是 1.1 的话五十步之后是 117 倍梯度爆炸。所以朴素循环网络在超过二三十步的依赖上基本无能为力。5.2 三门机制把“记住”变成一个可学习的开关长短期记忆网络的核心创新不是增加参数而是引入了一条几乎线性传递的细胞状态通路让梯度可以沿着这条通路几乎无衰减地回传。控制这条通路的是三个门遗忘门决定旧信息保留多少输入门决定新信息写入多少输出门决定当前暴露多少。门的本质是一个取值在零到一之间的软开关用 Sigmoid 函数实现。这里有个容易混淆的点门控不是硬性截断而是连续加权所以它是可微的能被梯度训练。这也是它比早期“跳跃连接固定步数”的方案更优的原因。参数量前面算过输入 64、隐藏 128 时约九万九千。这个数字意味着什么如果你的序列任务数据只有几千条九万多的参数很容易过拟合这时候换成门控循环单元会更好它把遗忘门和输入门合并成一个更新门参数量大约少四分之一精度损失通常很小。import torch.nn as nn # 双向 LSTM注意 batch_first 与维度顺序 encoder nn.LSTM( input_size64, hidden_size128, num_layers2, batch_firstTrue, bidirectionalTrue, dropout0.1, ) # 输出特征维度是 hidden_size * 2 256双向结构把正向和反向两个方向的隐状态拼起来让每个位置都能看到完整上下文。代价是不能用于实时流式推理因为反向那一遍需要等整个序列结束。我在一个在线场景里误用过双向结构离线评估指标非常漂亮上线后发现延迟根本不可接受只能推倒重来。这个坑值得写在方案文档的第一页。5.3 时序卷积用并行换记忆时序卷积网络换了个思路不用递推用因果卷积加膨胀。因果的意思是第 t 个输出只看 t 及之前的输入靠左侧填充实现膨胀的意思是卷积核采样点之间隔开固定间隔让感受野指数增长。感受野可以手算。核尺寸为 3、膨胀率依次为 1、2、4 的三层感受野是 1 加 2×(124) 等于 15。四层加上膨胀率 8感受野到 31。这个增长速度比同层数的普通卷积快得多。它最大的优势是训练时可以并行因为不存在时间步依赖整个序列一次前向算完不像循环网络必须一步步来。在长序列任务上训练速度的差距可能是几倍到十几倍。代价是推理时如果要流式输出需要维护缓存实现复杂度上升。6. 注意力与 Transformer 系把“距离”变成可学习的权重这一族是近些年结构创新的主战场但它的核心思想其实非常朴素不要固定谁和谁相连让模型自己学。6.1 缩放点积注意力里的那个根号注意力的计算是三件事用查询向量和每个键向量做点积得到相关性分数除以维度的平方根过 Softmax 归一化再对值向量加权求和。除以平方根这一步经常被当成经验技巧其实有明确理由。假设查询和键的每个分量都是独立同分布、均值零方差一那么点积的方差就是维度 d。维度越大点积的数值范围越宽Softmax 之后就会变得极端尖锐梯度接近于零。除以根号 d 正好把方差拉回一让不同维度下的注意力分布保持可比。我在自己实现注意力时忘了这一步训练前几百步损失几乎不动加上之后立刻正常这个教训记得很牢。import torch import torch.nn.functional as F def scaled_dot_product_attention(q, k, v, maskNone): d_k q.size(-1) scores torch.matmul(q, k.transpose(-2, -1)) / (d_k ** 0.5) if mask is not None: scores scores.masked_fill(mask 0, float(-inf)) weights F.softmax(scores, dim-1) return torch.matmul(weights, v)多头的作用是把表示空间切成若干子空间每个头独立做一次注意力最后拼接。这相当于让模型同时从多个角度判断“谁该关注谁”单个头容易退化成只关注相邻位置多头能缓解这个问题。6.2 位置编码不是可选项自注意力对输入顺序是置换等变的把序列打乱输出也只是跟着打乱模型本身感知不到顺序。这对语言任务来说是致命的所以必须显式注入位置信息。常见做法是把正弦函数生成的位置向量加到词向量上或者用可学习的位置嵌入。我在一个结构化数据任务里用过不带位置编码的注意力当时觉得字段之间没有顺序结果发现模型确实学到了“集合”级别的模式但一旦字段顺序在预处理阶段发生变化结果就飘了。后来加了位置编码稳定性明显提升。这个例子说明位置编码该不该加取决于你的数据里顺序是不是承载信息而不是取决于任务类型。还有一个必须算的账是计算量。自注意力的分数矩阵是序列长度乘序列长度计算量随长度平方增长。序列长度一千时是一百万个分数长度一万时就是一亿显存直接爆掉。这也是为什么长序列场景会出现各种稀疏注意力、分块注意力的变体。6.3 编码器、解码器、双向、自回归的分工这几种变体的差别只在掩码方式。双向编码器不做掩码每个位置可以看全序列适合理解型任务比如分类、抽取自回归解码器用下三角掩码每个位置只能看自己和左边适合生成型任务两者的组合就是经典的编码解码结构编码器读输入解码器在生成每一步时通过交叉注意力看编码器的输出。视觉 Transformer 的改动是把图像切成小块每块展平成一个向量当成序列喂进去。它证明了注意力并不依赖文本只要有合适的序列化方式就能处理图像。代价是它缺少卷积自带的那种平移等变先验所以在数据量小时往往不如卷积网络需要更强的数据增强和更长的训练。一个实际经验中小规模的数据集上卷积结构加注意力的混合方案通常比纯注意力结构更稳。纯注意力要发挥优势样本量和训练轮次都得跟上。7. 四个生成模型的分工边界AE、VAE、GAN 与扩散这四个经常被并列讨论但它们解决的问题根本不同。搞清楚“各自擅长什么”比比较谁的生成质量高有用得多。7.1 自编码器与变分自编码器潜空间能不能用自编码器的目标是压缩再重建。编码器把输入压成低维向量解码器还原。训练信号是重建误差不需要标签。它能做特征压缩、去噪、异常检测但有一个致命问题潜空间是散的。你随便在潜空间里取一个点解码出来大概率是一团噪声因为训练时从没约束过没被数据占据的区域。变分自编码器补的正是这一环。它不输出一个确定的潜向量而是输出一个分布的均值和方差训练时从这个分布里采样再解码。为了让采样可导用了重参数化技巧把随机性挪到一个独立的标准正态噪声上让梯度的路径绕开随机采样。损失函数里加了一项 KL 散度把编码出来的分布往标准正态上拉。这个 KL 项是把双刃剑。权重太小潜空间仍然散采样出来的东西没法看权重太大编码器会把所有输入都映射到同一个分布上这叫后验崩塌重建质量直接崩掉。我调这个权重的方法是先让它从很小开始观察重建损失是否正常下降再逐步加大找到一个重建和采样的平衡点。这个平衡点没有通用值跟数据维度关系很大。7.2 生成对抗网络与扩散模型博弈与去噪生成对抗网络用一个判别器当裁判生成器不断骗它。这个方法能产出很锐利的样本因为它学的本质是“像不像真样本”不需要逐像素对齐。但训练极不稳定判别器太强生成器拿不到有效梯度判别器太弱生成器学不到东西。模式崩塌也是老问题生成器可能只学会数据分布里的少数几个模式其他全丢掉。扩散模型换了个完全不同的思路先定义一个固定的加噪过程把数据一步步变成纯噪声再训练一个网络学会逆转这个过程从噪声一步步还原数据。它的训练目标极其稳定就是回归每一步的噪声没有博弈没有对抗。代价是采样慢因为要迭代几十到上千步。维度自编码器变分自编码器生成对抗网络扩散模型训练目标重建误差重建 KL对抗博弈噪声回归训练稳定性高高低高潜空间可用性差好一般较好采样速度一次前向一次前向一次前向多步迭代样本锐利度一般偏模糊高高主要风险潜空间散乱后验崩塌模式崩塌采样成本高我在选型时的判断顺序是这样如果目标是把数据压成可用的向量做检索选变分自编码器如果目标是高质量的样本合成且能承受训练不稳定的调试成本可以试生成对抗网络如果希望训练过程稳定、可控接受较慢的采样那就用扩散模型。这个顺序不是绝对的但它能帮你在一开始就排除掉一半错误选项。8. 图网络与脉冲网络两种非主流输入以及没进名单的那几个这 27 个里面图神经网络和脉冲神经网络是最不像“常规神经网络”的两个因为它们改变了输入的基本假设。8.1 图神经网络把邻域聚合写成矩阵运算图神经网络处理的数据没有固定网格结构每个节点邻居数量不同。它的核心操作叫消息传递每个节点收集邻居的特征聚合求和、求平均或求最大值再和自己的特征一起过一层变换。堆叠若干层每个节点就能获得多跳邻居的信息。它的一个关键性质是置换不变性节点的编号打乱输出只是跟着打乱模型结果不变。这个性质靠聚合函数的选择保证求和和求平均都满足但如果用拼接或者带顺序的操作就破坏了。实际的坑主要在三处。一是过平滑层数堆多了所有节点特征趋同分类效果反而不如浅层。二是邻居采样大图上每个节点的邻居可能上万不采样显存撑不住。三是归一化方式不同实现里对邻接矩阵的归一化细节不一样直接搬代码很容易出现数值量级偏差。8.2 脉冲神经网络时间是信息本身脉冲神经网络模仿的是事件驱动机制神经元累积膜电位超过阈值就发放一个脉冲然后复位。它的输入不是每帧的数值而是一串带时间戳的事件。优势是稀疏和低功耗因为大部分时间没有脉冲不需要计算。难点是训练脉冲发放是不可导的阶跃函数得用替代梯度来近似。我在这块只做过很浅的尝试感受是它离“拿来就用”还有距离工具链和数据表示都不如主流成熟。如果你的任务确实是事件相机输出或者极低功耗的传感场景值得投入如果只是普通图像分类暂时没必要绕这条路。8.3 为什么胶囊网络、霍普菲尔德网络、受限玻尔兹曼机没进这 27 个这是我刻意做的取舍理由值得说一下。胶囊网络提出用向量而不是标量作为神经元的输出向量长度表示存在概率方向表示姿态。这个想法很漂亮也确实解决了卷积网络对旋转不够敏感的问题但它在主流任务上始终没有明显超越卷积结构工程实现也更麻烦所以我把它归为“思路有价值但未成为通用选项”。霍普菲尔德网络和受限玻尔兹曼机属于能量模型这一支训练方式和前向网络差别很大更多出现在理论分析和特定的生成场景里。它们是有历史意义的模型但作为通用工具箱里的一件使用频率已经很低。混合专家结构我没放进来因为它更像一个层内组件而不是一种独立架构核心是让不同的子网络处理不同的输入靠一个路由网络决定分发。你可以把它塞进任何架构里所以单独列成一种“神经网络类型”会误导人。至于近几年出现的状态空间模型它用线性递推加结构化参数化来实现长序列建模训练可以并行推理是常数内存。这类结构确实值得关注但我倾向于先观察一段时间等它在更多任务上被验证再决定是否纳入自己的常备清单。这条取舍标准可以复用判断一个结构该不该进你的工具箱看它是否改变了“拓扑—数据形状—训练信号”这三者中的至少一个并且在实际任务上带来可复现的收益。只是换了个激活函数或者加了个归一化层那是改进不是新类别。9. 选型对照与落地踩坑把结构选择变成一张决策表讲完结构真正难的是选。我把自己常用的判断整理成下面这张表横轴是任务类型纵轴是数据规模。数据规模图像类任务序列类任务关系型任务数千条以内小卷积网络 强增强门控循环或时序卷积图网络 手工特征数万条残差网络中等深度双向循环或 Transformer图网络两三层十万条以上深层残差或视觉 TransformerTransformer 或状态空间模型多层图网络 采样这张表只是起点真正踩坑都在细节里。9.1 第一个坑批归一化对批大小极其敏感批归一化在训练时用当前批的统计量做归一化。批太小比如二或四统计量噪声极大训练会剧烈震荡。我遇到过一次同样的代码在批大小三十二时收敛得很好改成四就完全训不动查了半天以为是学习率问题最后发现是归一化层。解决方案有两个换成对批大小不敏感的归一化方式或者用梯度累积模拟大批量。后者的做法是多次前向反向累加梯度再统一更新一次注意此时归一化的统计仍然按小批算所以只解决优化问题不解决统计问题。真正要解决统计问题还是得换层。9.2 第二个坑损失不下降时的排查顺序这个问题我被问过很多次我自己的固定排查顺序是这样。先看数据和标签是否对得上把一批样本画出来肉眼检查我至少有三次发现问题出在标签错位或者预处理把通道顺序搞反了。再看学习率用一个极小值跑几十步如果损失完全不动说明梯度没传过去检查计算图是否断开比如某处用了不可导的转换或者误用了原地操作。然后看初始化全零初始化会导致对称性无法打破每层学到的特征完全一样。用标准初始化后如果还是不动检查是否某一层的输出方差被压到极小逐层打印激活值的均值和标准差正常情况应该保持在合理范围。最后才怀疑结构设计。顺序很重要因为前面三项的排查成本远低于重新设计结构而我见过太多人一上来就怀疑模型不够强。9.3 第三个坑评估指标的陷阱类别极不均衡时准确率会骗人。九成样本属于一类模型全猜这一类就有九成准确率。这时候要看每一类的召回和精确率或者用对不均衡更鲁棒的聚合指标。序列任务里还有另一个陷阱训练时用了完整的目标序列做输入教师强制推理时只能用自己上一步的输出。这两个阶段的数据分布不一致会导致离线指标虚高。缓解办法是训练时按一定概率把模型自己的预测喂回去让它提前适应推理时的输入分布。10. 我自己画图解笔记的方法怎么画才能真的记住最后聊点方法层面的东西。我墙上那张图改过很多版最后稳定下来的画法有三条规则分享出来可能对你有用。第一条一张图只放一个新东西。如果一个模型图和上一个相比只有一处不同那就只画那一处其余部分用方框写“同前”。早期我总想画完整的结构图结果每一张都长得很像看多了反而混淆。后来改成差异图记忆效率高很多。第二条每个方框必须标张量形状。这是我从调试经验里总结的硬规矩。不看形状的结构图等于没画因为你无法判断两个模块能不能接上。我现在的笔记里每个箭头旁边都写着类似“批×通道×高×宽”的标注画的时候就能发现通道数对不上的问题。第三条用十行代码验证理解。看完一个结构的描述立刻写一个最小实现随机造一个输入跑一次前向打印输出形状和参数量和论文里的数字对一遍。对不上就说明理解有偏差。这个方法帮我发现过好几次“以为自己懂了其实没懂”的情况尤其是那些带掩码或者带状态复用的结构光看图很容易漏掉细节。关于这份清单本身我的建议是别一次看完。二十七种结构一次塞进脑子能记住的不会超过五个。更有效的做法是按族推进这周只搞卷积族把参数量公式手算三遍写两个最小实现下周再进序列族。族内的结构共享大量设计思路一起学能互相印证跨族之间的迁移反而少。我现在还保留着一个习惯每接一个新任务先把候选结构在纸上列出来然后逐个算参数量和数据量需求通常算到第三个就能排除掉大部分选项。剩下两三个再动手写代码做小规模对比。这个流程比“凭直觉挑一个最强的”要慢一点但它省下的返工时间远超这点前期投入。