核心摘要

神经网络是参数化函数的组合。仿射变换混合特征,非线性增加可表示函数的范围,优化器根据目标函数的梯度调整参数。反向传播是链式法则的高效应用,不是生物学习的模拟,也不保证模型真正理解任务。

架构、损失、数据切分、初始化、优化器、正则化和评测协议构成一个整体。训练损失更低,可能同时伴随校准、鲁棒性、公平性或分布外表现变差。应始终在保留测试集上与简单基线比较。

从神经元到函数

生物神经元类比只适合建立直觉,并不代表二者相同。生物神经元是电化学、循环、自适应系统;人工层是由软件和硬件实现的数值运算。所谓“纳秒神经元”、大脑等价或能耗比较都需要统一工作负载和测量边界,不能从示意图推断。

对于输入批次 X,全连接层计算:

text
Z = X Wᵀ + b
A = φ(Z)

Wb 是学习参数,φ 是非线性函数。没有非线性时,堆叠多个仿射层仍然只是一个仿射函数。输入和输出维度属于数据契约;“输入层神经元”不是独立的生物式计算单元。

网络形状与输出语义

应在公式和测试中写明张量形状:

text
X: [batch, features]
W: [outputs, features]
b: [outputs]
Z: [batch, outputs]

输出头取决于目标:

任务 模型输出 常见损失
回归 实数预测 MSE、MAE、Huber 或领域损失
二分类 一个 logit 带 logits 的二元交叉熵
单标签多分类 每个类别一个 logit 以整数标签为目标的交叉熵
多标签分类 每个标签一个 logit 带 logits 的二元交叉熵
分布预测 分布参数 负对数似然

把 logits 交给数值稳定的框架损失。对于要求 logits 的交叉熵,事先调用 softmax 可能重复归一化并降低数值稳定性。

激活函数

ReLU 与变体

text
ReLU(x) = max(0, x)

ReLU 计算便宜且常作为基线,但某些单元可能对所有输入都失活。Leaky ReLU、GELU、SiLU 等变体会改变优化和计算取舍,没有一种对所有任务都最好。

Sigmoid 与 Tanh

Sigmoid 映射到 (0, 1),适合在二分类输出边界解释概率,但可能饱和。Tanh 映射到 (-1, 1) 且零中心,也会饱和。隐藏层选择应结合架构、归一化、初始化和实际梯度观察。

Softmax

Softmax 把一组 logits 映射为类别分布:

text
softmax(zᵢ) = exp(zᵢ - max(z)) / Σⱼ exp(zⱼ - max(z))

减去最大值是数值稳定技巧。概率向量不自动代表校准良好,校准需要独立评测。

前向传播与反向传播

对于两层网络:

text
z₁ = xW₁ᵀ + b₁
a₁ = φ(z₁)
z₂ = a₁W₂ᵀ + b₂
loss = L(z₂, y)

反向传播从损失向前应用链式法则。使用通常的 one-hot 约定时,交叉熵对输出 logits 的梯度具有 p - y 的简洁形式。框架计算的是向量-雅可比积,不需要构造完整雅可比矩阵。

参数更新可写成:

text
θ ← θ - η ∇θ L

其中 η 是学习率策略。小批量训练中的梯度是估计值,优化器状态会改变更新轨迹。

形状安全的 PyTorch 示例

下面使用 logits 和框架损失,刻意不宣称通用架构或超参数:

python
import torch
from torch import nn


class MLP(nn.Module):
    def __init__(self, input_features: int, classes: int) -> None:
        super().__init__()
        self.network = nn.Sequential(
            nn.Linear(input_features, 64),
            nn.ReLU(),
            nn.Linear(64, classes),
        )

    def forward(self, features: torch.Tensor) -> torch.Tensor:
        if features.ndim != 2:
            raise ValueError("expected [batch, features]")
        return self.network(features)


model = MLP(input_features=4, classes=3)
features = torch.randn(8, 4)
labels = torch.randint(0, 3, (8,))

logits = model(features)
loss = nn.CrossEntropyLoss()(logits, labels)
loss.backward()

生产训练仍需要优化器、数据校验、训练/验证/测试切分、设备和 dtype 管理、检查点策略,以及清理梯度的循环:

python
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)
optimizer.step()
optimizer.zero_grad(set_to_none=True)

不要不清理梯度就反复调用 backward(),除非明确要累积。训练使用 model.train(),评估使用 model.eval()torch.no_grad()

损失与优化器

损失函数必须匹配标签语义。MSE 对偏差对称处理;MAE 对异常值更不敏感;Huber 在二者之间取舍。交叉熵比较类别目标和 logits,带 logits 的二元交叉熵处理独立二元标签。

SGD、动量、Adam 和 AdamW 是更新规则,不保证找到全局最优。AdamW 的解耦权重衰减也不等同于所有参数化下直接加入 L2 惩罚。warmup、学习率调度、梯度裁剪、批量和归一化可能与优化器名称同样重要。

记录优化器、学习率、betas/动量、权重衰减、裁剪、调度器、有效 batch、精度、硬件和种子。“Adam 永远是默认首选”只是经验捷径,不是定理。

初始化、归一化与梯度健康

不恰当初始化会造成激活和梯度爆炸或消失。Xavier/Glorot 和 He/Kaiming 初始化适用于常见 fan-in 与激活假设,但架构和归一化会改变选择。

应监控:

  • 激活和梯度分布;
  • NaN/Inf 数量与损失缩放;
  • 更新量与权重比值;
  • 失活或饱和单元;
  • 训练/验证损失和指标差距。

BatchNorm、LayerNorm、残差连接和初始化会改变优化动态,不是可以任意互换的“正则化开关”。

CNN、RNN 与 Transformer

卷积网络

卷积使用局部连接和权重共享,为网格输入提供与平移相关的归纳偏置。padding、stride、dilation、通道顺序、归一化和输入分辨率共同决定形状。除非输入形状固定且有断言,不要硬编码 flatten 尺寸;自适应池化或形状测试更稳妥。

循环网络

RNN 在时间步之间传递隐藏状态。普通循环可能难以处理长依赖,LSTM/GRU 的门控改变了这一取舍。应处理 padding mask,让隐藏状态与输入位于同一设备和 dtype,并明确任务使用最后状态还是每个时间步。循环的延迟还受到顺序依赖和批处理影响。

Transformer

自注意力通过 query、key、value 投影让 token 交互。标准注意力的成对交互通常随序列长度呈二次增长,但内核、稀疏性、循环和其他设计会改变实际扩展。Transformer 仍需要位置处理、注意力 mask、残差、归一化和任务头。

PyTorch 模块有明确形状约定。输入 [batch, sequence, embedding] 时配置 batch_first=True,有意识地传入 padding/causal mask,并测试输出形状。没有 mask 或位置处理的 block 不能作为完整语言模型。

训练协议与泛化

在增强或反复调参前切分数据。验证集用于模型和超参数决策,测试集只用于最终报告。应去重近似样本,检查时间、实体和基准污染。

正则化包括权重衰减、dropout、数据增强、标签平滑、早停、更小模型和更好的数据。每种方法都改变偏差/方差取舍,“加 dropout”不是诊断。

应报告:

  • 数据来源、许可证、预处理和切分策略;
  • 模型修订、分词器/特征、架构和参数量;
  • 优化器、调度、batch、精度、硬件、种子和运行时间;
  • 基线、指标、置信区间和错误切片;
  • 相关的校准、鲁棒性、公平性、隐私和分布外行为。

可复现不等同于完全确定。GPU 内核、并行、库版本和硬件即使使用相同种子也可能产生细微差异。

评测与调试

在增加模型规模前先建立最小基线。按以下顺序排查:

  1. 标签、范围、缺失、泄漏和类别平衡;
  2. 张量形状、dtype、mask 和标签对齐;
  3. 损失/激活组合和梯度流;
  4. 训练/验证曲线和刻意过拟合极小数据测试;
  5. 保留切片、校准和失败样例;
  6. 部署前处理一致性和监控。

准确率会掩盖类别不平衡。根据任务增加 precision/recall、F1、AUROC/PR-AUC、校准、混淆矩阵、代价加权错误或专用指标。生成系统还应以固定协议评测事实性、拒答、有害性、工具调用、引用和人工有用性。

常见问题

神经网络是按大脑建模的吗?

类比主要是历史和概念性的。人工层是数字硬件上的数学函数优化,不是生物神经元的忠实模拟。

每个隐藏层都应该用 ReLU 吗?

不应该。ReLU 是常见基线,但 GELU、SiLU、Tanh、门控单元、归一化、初始化和架构都会改变结果,应在任务上测试。

交叉熵前应该先 Softmax 吗?

当使用要求 logits 的框架损失(如 PyTorch CrossEntropyLoss)时通常不应该。它内部会执行稳定的 log-softmax。应遵循准确 API 契约。

为什么训练损失下降但测试变差?

可能是过拟合、切分污染、指标不代表任务或前处理不一致。应检查保留切片、数据血缘、校准和基线。

纳秒或更深网络意味着模型更好吗?

不意味着。硬件计时、参数量和深度本身不是质量指标。应在记录完整协议后比较任务表现、资源成本、鲁棒性和不确定性。

反向传播等同于生物学习吗?

不等同。反向传播是对计算图求导的算法;生物学习有不同机制和约束,普通训练循环没有表达它们。

一手来源

总结

神经网络是按目标训练的函数组合,不是魔法抽象,也不是字面意义上的数字大脑。应同时跟踪形状、数值稳定性、梯度、数据血缘、泛化和部署行为。先建立基线,使实验足够可审计,再依据证据选择架构和优化,而不是套用固定配方。