神经网络入门:从感知机到 MLP——理解深度学习的算法根基

文章目录

深度学习的影响力不必赘述------但很多工程师在使用 PyTorch 或 TensorFlow 之前,从未真正理解神经网络作为一个数学对象是什么。

神经网络不是魔法。感知机做线性分类,MLP 堆叠几层就能拟合任意连续函数,反向传播用链式法则逐层调整参数。把这三件事搞清楚,所有深度学习架构的工作原理就有了根基。

本文不写 PyTorch 代码,用 sklearn 的 MLPClassifier 就够了。核心目标只有一个:理解"神经网络为什么能学习",以及"它和传统 ML 的边界在哪里"。


一、感知机:最简单的线性分类器

1957 年,Rosenblatt 提出感知机模型。输入向量 x \mathbf{x} x,权重向量 w \mathbf{w} w,偏置 b b b,输出:

y ^ = sign ( w ⋅ x + b ) \hat{y} = \text{sign}(\mathbf{w} \cdot \mathbf{x} + b) y^=sign(w⋅x+b)

sign ( z ) = + 1 \text{sign}(z) = +1 sign(z)=+1 若 z ≥ 0 z \geq 0 z≥0,否则 − 1 -1 −1。

感知机的学习规则极其简单:若预测正确,不更新;若预测错误,沿误差方向调整权重:

w ← w + η ⋅ ( y − y ^ ) ⋅ x \mathbf{w} \leftarrow \mathbf{w} + \eta \cdot (y - \hat{y}) \cdot \mathbf{x} w←w+η⋅(y−y^)⋅x

感知机收敛定理 (Rosenblatt, 1957):若数据线性可分,感知机算法一定在有限步内收敛。

这里有个关键词:线性可分。

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Perceptron
from sklearn.datasets import make_classification

# 线性可分数据------感知机可以正确分类
X, y = make_classification(n_samples=100, n_features=2, n_redundant=0,
                           n_informative=2, random_state=42, n_clusters_per_class=1)
y = np.where(y == 0, -1, 1)

clf = Perceptron(max_iter=1000, tol=1e-3)
clf.fit(X, y)
print(f"准确率: {clf.score(X, y):.3f}")

1.1 感知机的致命缺陷:XOR 问题

1969 年,Minsky 和 Papert 在《感知机》一书中证明:单层感知机无法学习 XOR 函数

XOR 真值表:

x 1 x_1 x1 x 2 x_2 x2 x 1 ⊕ x 2 x_1 \oplus x_2 x1⊕x2
0 0 0
0 1 1
1 0 1
1 1 0

在二维平面上,XOR 的四个点不存在任何一条直线能把 0 和 1 分开。这不是感知机的实现问题------是几何上的不可能。

这一发现导致了第一次"AI 冬天"(1970 年代),神经网络研究几乎停滞十年。


二、MLP:加一层隐藏单元,突破线性限制

解决 XOR 问题的思路很直接:加一层中间层,先把输入映射到一个新的特征空间,在那个空间里数据变得线性可分,再做线性分类。

这就是多层感知机(Multi-Layer Perceptron,MLP)的核心思想。
#mermaid-svg-845099MrWTkmel6P{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-845099MrWTkmel6P .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-845099MrWTkmel6P .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-845099MrWTkmel6P .error-icon{fill:#552222;}#mermaid-svg-845099MrWTkmel6P .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-845099MrWTkmel6P .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-845099MrWTkmel6P .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-845099MrWTkmel6P .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-845099MrWTkmel6P .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-845099MrWTkmel6P .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-845099MrWTkmel6P .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-845099MrWTkmel6P .marker{fill:#333333;stroke:#333333;}#mermaid-svg-845099MrWTkmel6P .marker.cross{stroke:#333333;}#mermaid-svg-845099MrWTkmel6P svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-845099MrWTkmel6P p{margin:0;}#mermaid-svg-845099MrWTkmel6P .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-845099MrWTkmel6P .cluster-label text{fill:#333;}#mermaid-svg-845099MrWTkmel6P .cluster-label span{color:#333;}#mermaid-svg-845099MrWTkmel6P .cluster-label span p{background-color:transparent;}#mermaid-svg-845099MrWTkmel6P .label text,#mermaid-svg-845099MrWTkmel6P span{fill:#333;color:#333;}#mermaid-svg-845099MrWTkmel6P .node rect,#mermaid-svg-845099MrWTkmel6P .node circle,#mermaid-svg-845099MrWTkmel6P .node ellipse,#mermaid-svg-845099MrWTkmel6P .node polygon,#mermaid-svg-845099MrWTkmel6P .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-845099MrWTkmel6P .rough-node .label text,#mermaid-svg-845099MrWTkmel6P .node .label text,#mermaid-svg-845099MrWTkmel6P .image-shape .label,#mermaid-svg-845099MrWTkmel6P .icon-shape .label{text-anchor:middle;}#mermaid-svg-845099MrWTkmel6P .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-845099MrWTkmel6P .rough-node .label,#mermaid-svg-845099MrWTkmel6P .node .label,#mermaid-svg-845099MrWTkmel6P .image-shape .label,#mermaid-svg-845099MrWTkmel6P .icon-shape .label{text-align:center;}#mermaid-svg-845099MrWTkmel6P .node.clickable{cursor:pointer;}#mermaid-svg-845099MrWTkmel6P .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-845099MrWTkmel6P .arrowheadPath{fill:#333333;}#mermaid-svg-845099MrWTkmel6P .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-845099MrWTkmel6P .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-845099MrWTkmel6P .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-845099MrWTkmel6P .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-845099MrWTkmel6P .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-845099MrWTkmel6P .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-845099MrWTkmel6P .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-845099MrWTkmel6P .cluster text{fill:#333;}#mermaid-svg-845099MrWTkmel6P .cluster span{color:#333;}#mermaid-svg-845099MrWTkmel6P div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-845099MrWTkmel6P .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-845099MrWTkmel6P rect.text{fill:none;stroke-width:0;}#mermaid-svg-845099MrWTkmel6P .icon-shape,#mermaid-svg-845099MrWTkmel6P .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-845099MrWTkmel6P .icon-shape p,#mermaid-svg-845099MrWTkmel6P .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-845099MrWTkmel6P .icon-shape .label rect,#mermaid-svg-845099MrWTkmel6P .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-845099MrWTkmel6P .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-845099MrWTkmel6P .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-845099MrWTkmel6P :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输出层
隐藏层
输入层
x₁
x₂
h₁
h₂
h₃
ŷ

MLP 每一层的计算:

h ( l ) = σ ( W ( l ) h ( l − 1 ) + b ( l ) ) \mathbf{h}^{(l)} = \sigma\left(\mathbf{W}^{(l)} \mathbf{h}^{(l-1)} + \mathbf{b}^{(l)}\right) h(l)=σ(W(l)h(l−1)+b(l))

其中 σ \sigma σ 是激活函数, W ( l ) \mathbf{W}^{(l)} W(l) 是第 l l l 层的权重矩阵。

关键洞察 :MLP 是一个"可学习的函数组合器"。每一层都是一次非线性变换,多层叠加就是多次变换的组合------本质上是复合函数

解决 XOR 的 MLP(1 个隐藏层,2 个神经元):

python 复制代码
from sklearn.neural_network import MLPClassifier
import numpy as np

# XOR 数据
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])

# 两层网络就能解 XOR
mlp = MLPClassifier(hidden_layer_sizes=(2,), activation='tanh',
                    max_iter=10000, random_state=42)
mlp.fit(X, y)
print(f"XOR 准确率: {mlp.score(X, y):.3f}")  # 1.000

三、通用近似定理:一层就够,但不够用

1989 年,Cybenko 和 Hornik 分别独立证明了通用近似定理(Universal Approximation Theorem):

定理 :对于任意连续函数 f : R n → R f: \mathbb{R}^n \to \mathbb{R} f:Rn→R 和任意 ϵ > 0 \epsilon > 0 ϵ>0,存在一个单隐藏层 MLP(宽度足够大),使得网络输出 f ^ \hat{f} f^ 满足 ∥ f − f ^ ∥ ∞ < ϵ \|f - \hat{f}\|_\infty < \epsilon ∥f−f^∥∞<ϵ。

通俗理解:一个宽度足够的单隐藏层可以近似任何连续函数,精度任意高。

但"理论上够"不等于"实践中够用":

  1. 所需宽度可能指数级大:拟合复杂函数需要的神经元数量可能是不可接受的
  2. 深度提供指数级的表达效率:L 层深网络能表达的函数类,浅网络需要指数量级的神经元才能表达
  3. 优化困难:极宽的浅网络在实践中很难训练

这就是为什么深度比宽度更重要------深度网络用更少的参数表达更复杂的函数
#mermaid-svg-KDZyBb3NZR7FvAS7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KDZyBb3NZR7FvAS7 .error-icon{fill:#552222;}#mermaid-svg-KDZyBb3NZR7FvAS7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KDZyBb3NZR7FvAS7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .marker.cross{stroke:#333333;}#mermaid-svg-KDZyBb3NZR7FvAS7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KDZyBb3NZR7FvAS7 p{margin:0;}#mermaid-svg-KDZyBb3NZR7FvAS7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster-label text{fill:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster-label span{color:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster-label span p{background-color:transparent;}#mermaid-svg-KDZyBb3NZR7FvAS7 .label text,#mermaid-svg-KDZyBb3NZR7FvAS7 span{fill:#333;color:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .node rect,#mermaid-svg-KDZyBb3NZR7FvAS7 .node circle,#mermaid-svg-KDZyBb3NZR7FvAS7 .node ellipse,#mermaid-svg-KDZyBb3NZR7FvAS7 .node polygon,#mermaid-svg-KDZyBb3NZR7FvAS7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .rough-node .label text,#mermaid-svg-KDZyBb3NZR7FvAS7 .node .label text,#mermaid-svg-KDZyBb3NZR7FvAS7 .image-shape .label,#mermaid-svg-KDZyBb3NZR7FvAS7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-KDZyBb3NZR7FvAS7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .rough-node .label,#mermaid-svg-KDZyBb3NZR7FvAS7 .node .label,#mermaid-svg-KDZyBb3NZR7FvAS7 .image-shape .label,#mermaid-svg-KDZyBb3NZR7FvAS7 .icon-shape .label{text-align:center;}#mermaid-svg-KDZyBb3NZR7FvAS7 .node.clickable{cursor:pointer;}#mermaid-svg-KDZyBb3NZR7FvAS7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .arrowheadPath{fill:#333333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KDZyBb3NZR7FvAS7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KDZyBb3NZR7FvAS7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KDZyBb3NZR7FvAS7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster text{fill:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 .cluster span{color:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KDZyBb3NZR7FvAS7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KDZyBb3NZR7FvAS7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-KDZyBb3NZR7FvAS7 .icon-shape,#mermaid-svg-KDZyBb3NZR7FvAS7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KDZyBb3NZR7FvAS7 .icon-shape p,#mermaid-svg-KDZyBb3NZR7FvAS7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KDZyBb3NZR7FvAS7 .icon-shape .label rect,#mermaid-svg-KDZyBb3NZR7FvAS7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KDZyBb3NZR7FvAS7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KDZyBb3NZR7FvAS7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KDZyBb3NZR7FvAS7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 同样精度

参数≈100倍
更优
浅网络(1层 × 10000个神经元)

理论可行

实践训练困难
深网络(10层 × 100个神经元)

参数更少

优化更稳定
实际任务性能


四、激活函数:非线性的来源

没有激活函数,多层 MLP 退化为单层线性模型(多个线性变换的组合仍是线性变换)。激活函数提供了非线性。
#mermaid-svg-xCe2dlxrdfmuvPzf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xCe2dlxrdfmuvPzf .error-icon{fill:#552222;}#mermaid-svg-xCe2dlxrdfmuvPzf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xCe2dlxrdfmuvPzf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xCe2dlxrdfmuvPzf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xCe2dlxrdfmuvPzf .marker.cross{stroke:#333333;}#mermaid-svg-xCe2dlxrdfmuvPzf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xCe2dlxrdfmuvPzf p{margin:0;}#mermaid-svg-xCe2dlxrdfmuvPzf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster-label text{fill:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster-label span{color:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster-label span p{background-color:transparent;}#mermaid-svg-xCe2dlxrdfmuvPzf .label text,#mermaid-svg-xCe2dlxrdfmuvPzf span{fill:#333;color:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf .node rect,#mermaid-svg-xCe2dlxrdfmuvPzf .node circle,#mermaid-svg-xCe2dlxrdfmuvPzf .node ellipse,#mermaid-svg-xCe2dlxrdfmuvPzf .node polygon,#mermaid-svg-xCe2dlxrdfmuvPzf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xCe2dlxrdfmuvPzf .rough-node .label text,#mermaid-svg-xCe2dlxrdfmuvPzf .node .label text,#mermaid-svg-xCe2dlxrdfmuvPzf .image-shape .label,#mermaid-svg-xCe2dlxrdfmuvPzf .icon-shape .label{text-anchor:middle;}#mermaid-svg-xCe2dlxrdfmuvPzf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xCe2dlxrdfmuvPzf .rough-node .label,#mermaid-svg-xCe2dlxrdfmuvPzf .node .label,#mermaid-svg-xCe2dlxrdfmuvPzf .image-shape .label,#mermaid-svg-xCe2dlxrdfmuvPzf .icon-shape .label{text-align:center;}#mermaid-svg-xCe2dlxrdfmuvPzf .node.clickable{cursor:pointer;}#mermaid-svg-xCe2dlxrdfmuvPzf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xCe2dlxrdfmuvPzf .arrowheadPath{fill:#333333;}#mermaid-svg-xCe2dlxrdfmuvPzf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xCe2dlxrdfmuvPzf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xCe2dlxrdfmuvPzf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xCe2dlxrdfmuvPzf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xCe2dlxrdfmuvPzf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xCe2dlxrdfmuvPzf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster text{fill:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf .cluster span{color:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xCe2dlxrdfmuvPzf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xCe2dlxrdfmuvPzf rect.text{fill:none;stroke-width:0;}#mermaid-svg-xCe2dlxrdfmuvPzf .icon-shape,#mermaid-svg-xCe2dlxrdfmuvPzf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xCe2dlxrdfmuvPzf .icon-shape p,#mermaid-svg-xCe2dlxrdfmuvPzf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xCe2dlxrdfmuvPzf .icon-shape .label rect,#mermaid-svg-xCe2dlxrdfmuvPzf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xCe2dlxrdfmuvPzf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xCe2dlxrdfmuvPzf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xCe2dlxrdfmuvPzf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} GELU
z·Φ(z)

光滑近似 ReLU

Transformer 默认激活
ReLU
max(0, z)

范围: [0,+∞)

梯度: 0 或 1
tanh
tanh(z) = (eᶻ-e⁻ᶻ)/(eᶻ+e⁻ᶻ)

范围: (-1,1)

梯度: 1-tanh²(z) ≤ 1.0
sigmoid
σ(z) = 1/(1+e⁻ᶻ)

范围: (0,1)

梯度: σ(z)(1-σ(z)) ≤ 0.25

4.1 各激活函数的选型指南

sigmoid

  • 优点:输出可解释为概率,二分类输出层常用
  • 缺点:梯度最大为 0.25,深层网络中梯度逐层衰减(梯度消失的根源)
  • 适用:输出层(二分类)、浅层网络

tanh

  • 优点:零中心(输出均值接近 0),梯度比 sigmoid 大,训练更稳定
  • 缺点:仍有梯度消失问题(梯度最大为 1)
  • 适用:RNN 的隐状态层

ReLU(Rectified Linear Unit):

  • 优点:梯度为 1(正区间无梯度消失)、计算极快、实践效果好
  • 缺点:Dead Neuron------当某个神经元的输入始终为负,梯度永远为 0,该神经元永久"死亡"
  • 适用:隐藏层的默认选择(2012 年 AlexNet 之后成为主流)

GELU(Gaussian Error Linear Unit):

  • GELU ( z ) = z ⋅ Φ ( z ) \text{GELU}(z) = z \cdot \Phi(z) GELU(z)=z⋅Φ(z),其中 Φ \Phi Φ 是标准正态 CDF
  • 光滑版本的 ReLU,在负区间不完全置零而是有小幅负值
  • BERT、GPT、Vision Transformer 的默认激活函数
python 复制代码
import numpy as np
import matplotlib.pyplot as plt

z = np.linspace(-3, 3, 300)
sigmoid = 1 / (1 + np.exp(-z))
tanh_vals = np.tanh(z)
relu = np.maximum(0, z)
gelu = z * 0.5 * (1 + np.tanh(np.sqrt(2/np.pi) * (z + 0.044715 * z**3)))

# 梯度
d_sigmoid = sigmoid * (1 - sigmoid)
d_tanh = 1 - tanh_vals**2

print("sigmoid 最大梯度:", d_sigmoid.max())   # 0.25
print("tanh 最大梯度:", d_tanh.max())          # 1.0
print("ReLU 正区间梯度: 1.0")

五、反向传播:链式法则的工程化实现

反向传播(Backpropagation)是 MLP 学习参数的核心算法。很多人把它说得很神秘,实际上它就是链式法则的逐层应用

5.1 前向传播

以两层网络为例:

h = σ ( W 1 x + b 1 ) \mathbf{h} = \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) h=σ(W1x+b1)

y ^ = σ ( W 2 h + b 2 ) \hat{y} = \sigma(\mathbf{W}_2 \mathbf{h} + \mathbf{b}_2) y^=σ(W2h+b2)

L = CrossEntropy ( y , y ^ ) L = \text{CrossEntropy}(y, \hat{y}) L=CrossEntropy(y,y^)

5.2 反向传播的链式法则

要更新 W 1 \mathbf{W}_1 W1,需要计算 ∂ L ∂ W 1 \frac{\partial L}{\partial \mathbf{W}_1} ∂W1∂L:

∂ L ∂ W 1 = ∂ L ∂ y ^ ⏟ 损失对输出 ⋅ ∂ y ^ ∂ h ⏟ 输出对隐藏 ⋅ ∂ h ∂ W 1 ⏟ 隐藏对权重 \frac{\partial L}{\partial \mathbf{W}1} = \underbrace{\frac{\partial L}{\partial \hat{y}}}{\text{损失对输出}} \cdot \underbrace{\frac{\partial \hat{y}}{\partial \mathbf{h}}}_{\text{输出对隐藏}} \cdot \underbrace{\frac{\partial \mathbf{h}}{\partial \mathbf{W}1}}{\text{隐藏对权重}} ∂W1∂L=损失对输出 ∂y^∂L⋅输出对隐藏 ∂h∂y^⋅隐藏对权重 ∂W1∂h
#mermaid-svg-0IdqD2opaFQ5H1X5{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0IdqD2opaFQ5H1X5 .error-icon{fill:#552222;}#mermaid-svg-0IdqD2opaFQ5H1X5 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0IdqD2opaFQ5H1X5 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .marker.cross{stroke:#333333;}#mermaid-svg-0IdqD2opaFQ5H1X5 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0IdqD2opaFQ5H1X5 p{margin:0;}#mermaid-svg-0IdqD2opaFQ5H1X5 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster-label text{fill:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster-label span{color:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster-label span p{background-color:transparent;}#mermaid-svg-0IdqD2opaFQ5H1X5 .label text,#mermaid-svg-0IdqD2opaFQ5H1X5 span{fill:#333;color:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .node rect,#mermaid-svg-0IdqD2opaFQ5H1X5 .node circle,#mermaid-svg-0IdqD2opaFQ5H1X5 .node ellipse,#mermaid-svg-0IdqD2opaFQ5H1X5 .node polygon,#mermaid-svg-0IdqD2opaFQ5H1X5 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .rough-node .label text,#mermaid-svg-0IdqD2opaFQ5H1X5 .node .label text,#mermaid-svg-0IdqD2opaFQ5H1X5 .image-shape .label,#mermaid-svg-0IdqD2opaFQ5H1X5 .icon-shape .label{text-anchor:middle;}#mermaid-svg-0IdqD2opaFQ5H1X5 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .rough-node .label,#mermaid-svg-0IdqD2opaFQ5H1X5 .node .label,#mermaid-svg-0IdqD2opaFQ5H1X5 .image-shape .label,#mermaid-svg-0IdqD2opaFQ5H1X5 .icon-shape .label{text-align:center;}#mermaid-svg-0IdqD2opaFQ5H1X5 .node.clickable{cursor:pointer;}#mermaid-svg-0IdqD2opaFQ5H1X5 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .arrowheadPath{fill:#333333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0IdqD2opaFQ5H1X5 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0IdqD2opaFQ5H1X5 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0IdqD2opaFQ5H1X5 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster text{fill:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 .cluster span{color:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0IdqD2opaFQ5H1X5 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0IdqD2opaFQ5H1X5 rect.text{fill:none;stroke-width:0;}#mermaid-svg-0IdqD2opaFQ5H1X5 .icon-shape,#mermaid-svg-0IdqD2opaFQ5H1X5 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0IdqD2opaFQ5H1X5 .icon-shape p,#mermaid-svg-0IdqD2opaFQ5H1X5 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0IdqD2opaFQ5H1X5 .icon-shape .label rect,#mermaid-svg-0IdqD2opaFQ5H1X5 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0IdqD2opaFQ5H1X5 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0IdqD2opaFQ5H1X5 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0IdqD2opaFQ5H1X5 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 反向传播
前向传播
W₁
W₂
∂L/∂ŷ
∂ŷ/∂h
∂h/∂W₁
输入 x
隐藏层 h

h = σ(W₁x + b₁)
输出 ŷ

ŷ = σ(W₂h + b₂)
损失 L

CrossEntropy(y, ŷ)

核心步骤

  1. 前向传播:从输入到输出,计算每层的激活值,保存中间结果
  2. 计算损失 :用真实标签和预测值计算 L L L
  3. 反向传播:从输出层往输入层,用链式法则逐层计算梯度
  4. 参数更新 : W ← W − η ⋅ ∂ L ∂ W \mathbf{W} \leftarrow \mathbf{W} - \eta \cdot \frac{\partial L}{\partial \mathbf{W}} W←W−η⋅∂W∂L

5.3 直觉理解

如果把每层的权重 w i j w_{ij} wij 想象成水管阀门,损失 L L L 是水塔的水位:

  • 前向传播:水从输入流向输出,各阀门控制流量
  • 反向传播:追溯"哪个阀门对水位上升贡献最大",然后相应地调小它

反向传播不需要枚举每个参数并分别求导------链式法则让这个过程从 O ( W 2 ) O(W^2) O(W2) 降到 O ( W ) O(W) O(W),这才是它的工程价值所在。


六、梯度消失与爆炸:深层网络的核心障碍

6.1 梯度消失

使用 sigmoid 激活时,每层的梯度会乘以 σ ′ ( z ) ≤ 0.25 \sigma'(z) \leq 0.25 σ′(z)≤0.25。经过 L L L 层:

∂ L ∂ W 1 ≈ ∏ l = 2 L σ ′ ( z ( l ) ) ≤ 0.25 L − 1 \frac{\partial L}{\partial \mathbf{W}1} \approx \prod{l=2}^{L} \sigma'(z^{(l)}) \leq 0.25^{L-1} ∂W1∂L≈l=2∏Lσ′(z(l))≤0.25L−1

10 层网络: 0.25 9 ≈ 3.8 × 10 − 6 0.25^9 \approx 3.8 \times 10^{-6} 0.259≈3.8×10−6

梯度几乎为零,底层权重无法更新,网络学不到任何东西。

解决方案

  • 使用 ReLU(正区间梯度为 1)
  • 批归一化(Batch Normalization)------将每层输入归一化,保持梯度稳定
  • 残差连接(ResNet)------直接连接跨层的梯度通路

6.2 梯度爆炸

反过来,若权重初始化过大,梯度经过多层累乘会指数级增长,导致参数更新步长过大、训练发散。

解决方案

  • 梯度裁剪(Gradient Clipping): if ∥ ∇ ∥ 2 > threshold : ∇ ← ∇ ⋅ threshold ∥ ∇ ∥ 2 \text{if } \|\nabla\|_2 > \text{threshold}: \nabla \leftarrow \nabla \cdot \frac{\text{threshold}}{\|\nabla\|_2} if ∥∇∥2>threshold:∇←∇⋅∥∇∥2threshold
  • 合理的权重初始化

6.3 Xavier 与 He 初始化

权重初始化的目标:让每层输出的方差保持稳定,既不膨胀也不衰减。

Xavier 初始化(Glorot, 2010):适合 sigmoid/tanh:

W ∼ U ( − 6 n in + n out , 6 n in + n out ) W \sim \mathcal{U}\left(-\sqrt{\frac{6}{n_{\text{in}} + n_{\text{out}}}}, \sqrt{\frac{6}{n_{\text{in}} + n_{\text{out}}}}\right) W∼U(−nin+nout6 ,nin+nout6 )

He 初始化(He, 2015):适合 ReLU(考虑到 ReLU 截断了一半输出):

W ∼ N ( 0 , 2 n in ) W \sim \mathcal{N}\left(0, \sqrt{\frac{2}{n_{\text{in}}}}\right) W∼N(0,nin2 )

python 复制代码
import torch
import torch.nn as nn

# PyTorch 中的初始化(sklearn MLP 内部自动处理)
layer = nn.Linear(100, 50)
nn.init.kaiming_normal_(layer.weight, nonlinearity='relu')  # He 初始化
nn.init.xavier_uniform_(layer.weight)                        # Xavier 初始化

七、MLP 训练三件套

7.1 损失函数

任务 损失函数 公式
二分类 Binary Cross-Entropy y log ⁡ p \^ + ( 1 − y ) log ⁡ ( 1 − p \^ ) -y \\log \\hat{p} + (1-y)\\log(1-\\hat{p})ylogp\^+(1−y)log(1−p\^)
多分类 Categorical Cross-Entropy − ∑ k y k log ⁡ p ^ k -\sum_k y_k \log \hat{p}_k −∑kyklogp^k
回归 MSE 1 N ∑ i ( y i − y ^ i ) 2 \frac{1}{N}\sum_i (y_i - \hat{y}_i)^2 N1∑i(yi−y^i)2
回归(异常值鲁棒) Huber Loss 小误差用 MSE,大误差用 MAE

为什么分类用 Cross-Entropy 而非 MSE?

MSE 配合 sigmoid 输出时,梯度在预测很错误的地方反而很小(sigmoid 饱和区梯度接近零)------训练会非常缓慢。Cross-Entropy 不存在这个问题,在预测越错的地方梯度越大。

7.2 优化器演进

#mermaid-svg-8zEK8C5S1HQPGRLr{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8zEK8C5S1HQPGRLr .error-icon{fill:#552222;}#mermaid-svg-8zEK8C5S1HQPGRLr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8zEK8C5S1HQPGRLr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8zEK8C5S1HQPGRLr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8zEK8C5S1HQPGRLr .marker.cross{stroke:#333333;}#mermaid-svg-8zEK8C5S1HQPGRLr svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8zEK8C5S1HQPGRLr p{margin:0;}#mermaid-svg-8zEK8C5S1HQPGRLr .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster-label text{fill:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster-label span{color:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster-label span p{background-color:transparent;}#mermaid-svg-8zEK8C5S1HQPGRLr .label text,#mermaid-svg-8zEK8C5S1HQPGRLr span{fill:#333;color:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr .node rect,#mermaid-svg-8zEK8C5S1HQPGRLr .node circle,#mermaid-svg-8zEK8C5S1HQPGRLr .node ellipse,#mermaid-svg-8zEK8C5S1HQPGRLr .node polygon,#mermaid-svg-8zEK8C5S1HQPGRLr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8zEK8C5S1HQPGRLr .rough-node .label text,#mermaid-svg-8zEK8C5S1HQPGRLr .node .label text,#mermaid-svg-8zEK8C5S1HQPGRLr .image-shape .label,#mermaid-svg-8zEK8C5S1HQPGRLr .icon-shape .label{text-anchor:middle;}#mermaid-svg-8zEK8C5S1HQPGRLr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8zEK8C5S1HQPGRLr .rough-node .label,#mermaid-svg-8zEK8C5S1HQPGRLr .node .label,#mermaid-svg-8zEK8C5S1HQPGRLr .image-shape .label,#mermaid-svg-8zEK8C5S1HQPGRLr .icon-shape .label{text-align:center;}#mermaid-svg-8zEK8C5S1HQPGRLr .node.clickable{cursor:pointer;}#mermaid-svg-8zEK8C5S1HQPGRLr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8zEK8C5S1HQPGRLr .arrowheadPath{fill:#333333;}#mermaid-svg-8zEK8C5S1HQPGRLr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8zEK8C5S1HQPGRLr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8zEK8C5S1HQPGRLr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8zEK8C5S1HQPGRLr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8zEK8C5S1HQPGRLr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8zEK8C5S1HQPGRLr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster text{fill:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr .cluster span{color:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8zEK8C5S1HQPGRLr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8zEK8C5S1HQPGRLr rect.text{fill:none;stroke-width:0;}#mermaid-svg-8zEK8C5S1HQPGRLr .icon-shape,#mermaid-svg-8zEK8C5S1HQPGRLr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8zEK8C5S1HQPGRLr .icon-shape p,#mermaid-svg-8zEK8C5S1HQPGRLr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8zEK8C5S1HQPGRLr .icon-shape .label rect,#mermaid-svg-8zEK8C5S1HQPGRLr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8zEK8C5S1HQPGRLr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8zEK8C5S1HQPGRLr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8zEK8C5S1HQPGRLr :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SGD

随机梯度下降

每次用一个样本估计梯度

噪声大,收敛不稳定
Mini-batch SGD

每次用一小批样本

噪声适中,GPU 友好

目前最常用的基础形式
Momentum

加入历史梯度的指数加权平均

加速收敛,减少震荡
Adam

自适应学习率

结合 Momentum 和 RMSProp

大多数任务的默认选择
AdamW

Adam + 权重衰减解耦

Transformer 训练标准配置

Adam 的核心思想:为每个参数维护自适应学习率,梯度大的参数学习率小,梯度小的参数学习率大。

7.3 正则化

Dropout(Srivastava, 2014):训练时随机将一定比例的神经元置零,测试时全部激活但乘以保留概率。

直觉:防止网络过度依赖某几个神经元,强制学习冗余特征表示------类似于训练多个子网络然后集成。

python 复制代码
from sklearn.neural_network import MLPClassifier

# sklearn 的 MLP 支持正则化
mlp = MLPClassifier(
    hidden_layer_sizes=(256, 128, 64),
    activation='relu',
    solver='adam',
    alpha=1e-4,         # L2 正则化系数(weight decay)
    batch_size=64,
    learning_rate_init=1e-3,
    max_iter=500,
    random_state=42
)
# 注意:sklearn MLPClassifier 不支持 Dropout,需要 PyTorch 才能用

Weight Decay(L2 正则) :在损失函数中加入 λ ∥ w ∥ 2 2 \lambda \|\mathbf{w}\|_2^2 λ∥w∥22,让参数趋向小值,防止过拟合。


八、sklearn MLPClassifier 实战调参

sklearn 的 MLPClassifier 无需 GPU 和框架知识,适合快速验证 MLP 是否适合当前任务。

python 复制代码
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.datasets import make_classification

# 生成测试数据
X, y = make_classification(n_samples=5000, n_features=20,
                           n_informative=15, random_state=42)

# MLP 对特征缩放非常敏感,必须标准化
pipe = Pipeline([
    ('scaler', StandardScaler()),
    ('mlp', MLPClassifier(
        hidden_layer_sizes=(256, 128),   # 两个隐藏层
        activation='relu',               # 激活函数
        solver='adam',                   # 优化器
        alpha=1e-4,                      # L2 正则化
        learning_rate='adaptive',        # 自适应学习率(loss 不降则缩小)
        max_iter=300,
        early_stopping=True,             # 自动早停,防止过拟合
        validation_fraction=0.1,         # 10% 数据用于早停验证
        n_iter_no_change=15,             # 15 轮无改善则停止
        random_state=42
    ))
])

scores = cross_val_score(pipe, X, y, cv=5, scoring='f1')
print(f"MLP 5-fold F1: {scores.mean():.3f} ± {scores.std():.3f}")

8.1 关键超参调优指南

超参 默认 调优方向 说明
hidden_layer_sizes (100,) 先宽后窄,如 (256, 128, 64) 结构设计比单层大更有效
activation 'relu' 保持 relu,特殊场景尝试 tanh 隐藏层首选 ReLU
solver 'adam' 小数据用 'lbfgs',大数据用 'adam' lbfgs 是二阶方法,小数据收敛快
alpha 0.0001 过拟合时增大(1e-3, 1e-2) L2 正则强度
learning_rate_init 0.001 通常不需要大幅调整 Adam 的初始学习率
max_iter 200 配合 early_stopping=True 设 500-1000 防止截断训练

九、MLP vs 传统 ML:选型边界

这是实战中最常遇到的选择题。
#mermaid-svg-XmQgjJGprwkRcsK1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XmQgjJGprwkRcsK1 .error-icon{fill:#552222;}#mermaid-svg-XmQgjJGprwkRcsK1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XmQgjJGprwkRcsK1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XmQgjJGprwkRcsK1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XmQgjJGprwkRcsK1 .marker.cross{stroke:#333333;}#mermaid-svg-XmQgjJGprwkRcsK1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XmQgjJGprwkRcsK1 p{margin:0;}#mermaid-svg-XmQgjJGprwkRcsK1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster-label text{fill:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster-label span{color:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster-label span p{background-color:transparent;}#mermaid-svg-XmQgjJGprwkRcsK1 .label text,#mermaid-svg-XmQgjJGprwkRcsK1 span{fill:#333;color:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 .node rect,#mermaid-svg-XmQgjJGprwkRcsK1 .node circle,#mermaid-svg-XmQgjJGprwkRcsK1 .node ellipse,#mermaid-svg-XmQgjJGprwkRcsK1 .node polygon,#mermaid-svg-XmQgjJGprwkRcsK1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XmQgjJGprwkRcsK1 .rough-node .label text,#mermaid-svg-XmQgjJGprwkRcsK1 .node .label text,#mermaid-svg-XmQgjJGprwkRcsK1 .image-shape .label,#mermaid-svg-XmQgjJGprwkRcsK1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-XmQgjJGprwkRcsK1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XmQgjJGprwkRcsK1 .rough-node .label,#mermaid-svg-XmQgjJGprwkRcsK1 .node .label,#mermaid-svg-XmQgjJGprwkRcsK1 .image-shape .label,#mermaid-svg-XmQgjJGprwkRcsK1 .icon-shape .label{text-align:center;}#mermaid-svg-XmQgjJGprwkRcsK1 .node.clickable{cursor:pointer;}#mermaid-svg-XmQgjJGprwkRcsK1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XmQgjJGprwkRcsK1 .arrowheadPath{fill:#333333;}#mermaid-svg-XmQgjJGprwkRcsK1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XmQgjJGprwkRcsK1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XmQgjJGprwkRcsK1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XmQgjJGprwkRcsK1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XmQgjJGprwkRcsK1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XmQgjJGprwkRcsK1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster text{fill:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 .cluster span{color:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XmQgjJGprwkRcsK1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XmQgjJGprwkRcsK1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-XmQgjJGprwkRcsK1 .icon-shape,#mermaid-svg-XmQgjJGprwkRcsK1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XmQgjJGprwkRcsK1 .icon-shape p,#mermaid-svg-XmQgjJGprwkRcsK1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XmQgjJGprwkRcsK1 .icon-shape .label rect,#mermaid-svg-XmQgjJGprwkRcsK1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XmQgjJGprwkRcsK1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XmQgjJGprwkRcsK1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XmQgjJGprwkRcsK1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 图像 / 语音 / 文本
结构化表格数据
< 1000 行
1000 - 100000 行
> 100000 行
需要解释(医疗/金融)
不强要求解释
任务类型?
深度学习专用架构

CNN / Transformer / RNN

不是 sklearn MLP 的范畴
数据量?
传统 ML 更稳

Logistic / 树模型

数据太少难以训练 MLP
可解释性要求?
MLP 有竞争力

尤其是高维、复杂交互场景
树模型 + SHAP

更容易合规解释
对比测试

XGBoost vs MLP

选最优的

MLP 的真实劣势(经常被忽视)

  1. 对特征缩放极度敏感:树模型不需要缩放,MLP 必须标准化
  2. 调参难度高:层数、宽度、激活函数、学习率......搜索空间比 XGBoost 大得多
  3. 结构化表格数据上不占优:2022 年 NeurIPS 的研究表明,经过调优的梯度提升树在绝大多数中小型表格数据集上优于 MLP
  4. 训练时间长:相比 sklearn 的逻辑回归或树模型,MLP 训练慢 10-100 倍

MLP 的真实优势

  • 高维稠密特征(嵌入向量、文本特征)
  • 超大规模数据(百万级以上)
  • 可以集成到深度学习管线中

十、实战对比:MLP vs 随机森林 vs XGBoost

用同一个数据集,测三个模型的精度、训练时间和调参难度:

python 复制代码
import time
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import StratifiedKFold, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.neural_network import MLPClassifier
from sklearn.ensemble import RandomForestClassifier
from xgboost import XGBClassifier

X, y = load_breast_cancer(return_X_y=True)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

models = {
    'MLP': Pipeline([
        ('scaler', StandardScaler()),
        ('clf', MLPClassifier(
            hidden_layer_sizes=(256, 128),
            activation='relu',
            solver='adam',
            alpha=1e-3,
            early_stopping=True,
            max_iter=500,
            random_state=42
        ))
    ]),
    'Random Forest': RandomForestClassifier(
        n_estimators=200, max_depth=None,
        random_state=42, n_jobs=-1
    ),
    'XGBoost': XGBClassifier(
        n_estimators=200, learning_rate=0.1,
        max_depth=4, subsample=0.8,
        random_state=42, eval_metric='logloss',
        verbosity=0
    )
}

results = {}
for name, model in models.items():
    t0 = time.time()
    scores = cross_val_score(model, X, y, cv=cv, scoring='f1')
    elapsed = time.time() - t0
    results[name] = {'F1 均值': scores.mean(), 'F1 标准差': scores.std(), '耗时(s)': elapsed}
    print(f"{name}: F1={scores.mean():.3f}±{scores.std():.3f}, 耗时={elapsed:.2f}s")

典型结果(breast_cancer 数据集):

模型 F1 均值 F1 标准差 训练耗时 调参难度
MLP 0.975 0.012 中(数秒)
随机森林 0.968 0.015 快(< 1s)
XGBoost 0.971 0.013 快(< 1s)

选型建议

  • 首选 XGBoost/LightGBM(调参文档成熟、速度快、效果稳定)
  • MLP 在大数据集或高维嵌入特征时值得尝试
  • 性能接近时,选择更容易解释和维护的模型

总结

神经网络的学习能力来自三个层次:

  1. 非线性:激活函数让多层组合不退化为线性变换
  2. 自动特征提取:深层网络从原始输入中逐层提炼抽象特征
  3. 端到端优化:反向传播用链式法则高效地把损失信号传递到每个参数

MLP 是所有深度学习架构的算法根基------CNN 是加了卷积约束的 MLP,Transformer 的 FFN 是两层 MLP,GNN 是图上的 MLP。理解感知机 → MLP → 反向传播这条线,就理解了深度学习的核心算法逻辑。

在结构化表格数据上,MLP 并非首选------梯度提升树通常更稳、更快、更易调参。但在图像、文本、序列等非结构化场景,以及超大规模数据上,MLP 及其深度变体是主力。

选择工具的标准永远是数据特点和任务需求,而不是哪个方法更"先进"。


相关阅读:

如果这篇文章对理解神经网络的算法根基有帮助,欢迎点赞、收藏、关注------你的支持是持续更新的最大动力。