Lesson 12
人工神经网络:多层感知机
多层感知机(MLP)通过叠加非线性隐藏层,解决感知机无法处理的非线性问题。本章讲解前馈网络结构、激活函数、反向传播原理、以及 sklearn 的 MLPClassifier 实战。
本章细分学习地图
| 模块 | 拆细学习单元 | 完成后应产出 | 掌握标准 |
|---|---|---|---|
| 结构 | 层、神经元、权重矩阵。 | 手画网络图。 | 能说清输入/隐藏/输出层的作用。 |
| 激活函数 | ReLU/Sigmoid/Tanh 对比。 | 激活函数对比表。 | 能解释为什么需要非线性激活。 |
| 反向传播 | 链式法则、梯度更新。 | 反向传播直觉。 | 能说清"从输出层向前逐层计算梯度"。 |
| 实战 | MLPClassifier 训练与调参。 | 完整代码。 | 能调 hidden_layer_sizes 和 alpha。 |
学习目标
MLP 前向传播
1输入层
2隐藏层(激活)
3输出层
4损失 → 反向传播
本章完成度
已完成 0/4
网络结构
MLP 由多层神经元组成。每层的每个神经元接收上一层所有神经元的输出,加权求和后通过激活函数。
输入层
接收原始特征,神经元数 = 特征数。不做计算。
隐藏层
非线性变换的核心。层数和每层神经元数决定模型容量。
输出层
分类:神经元数 = 类别数(softmax)。回归:1 个神经元(线性)。
为什么需要隐藏层
没有隐藏层的 MLP 就是线性模型(等价于逻辑回归)。加上非线性激活的隐藏层后,MLP 理论上可以逼近任意连续函数(万能逼近定理)。
激活函数
激活函数引入非线性,是神经网络能学习复杂模式的关键。
| 激活函数 | 公式直觉 | 特点 |
|---|---|---|
| ReLU | max(0, z):正值不变,负值归零。 | 计算快,梯度不消失(正区)。sklearn 默认。 |
| Sigmoid | 1/(1+e⁻ᶻ):压缩到 (0,1)。 | 输出可解释为概率,但深层网络梯度消失。 |
| Tanh | (eᶻ−e⁻ᶻ)/(eᶻ+e⁻ᶻ):压缩到 (-1,1)。 | 零中心,比 Sigmoid 稍好。 |
ReLU(z) = max(0, z)
z > 0 时梯度为 1,z ≤ 0 时梯度为 0
反向传播
反向传播是训练神经网络的核心算法。它用链式法则从输出层向输入层逐层计算每个权重对损失的梯度,然后用梯度下降更新权重。
前向传播
输入数据逐层通过网络,计算预测值和损失。
计算输出层梯度
损失对输出层权重的偏导数。
逐层反向传播
用链式法则把梯度从输出层传到每一层。
更新权重
w ← w − η · ∂L/∂w(梯度下降)。
sklearn 的局限
sklearn 的 MLPClassifier 适合中小规模数据的快速实验。大规模深度学习任务应使用 PyTorch 或 TensorFlow,它们支持 GPU 加速和更灵活的网络结构。
sklearn 实战
from sklearn.datasets import load_digits
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split, GridSearchCV
X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
pipe = Pipeline([
("scaler", StandardScaler()),
("mlp", MLPClassifier(max_iter=500, random_state=42)),
])
param_grid = {
"mlp__hidden_layer_sizes": [(50,), (100,), (100, 50)],
"mlp__alpha": [0.0001, 0.001, 0.01],
"mlp__activation": ["relu", "tanh"],
}
grid = GridSearchCV(pipe, param_grid, cv=3, scoring="accuracy", n_jobs=-1)
grid.fit(X_train, y_train)
print(f"最佳参数: {grid.best_params_}")
print(f"CV 准确率: {grid.best_score_:.4f}")
print(f"测试准确率: {grid.score(X_test, y_test):.4f}")
| 参数 | 含义 | 调参建议 |
|---|---|---|
hidden_layer_sizes | 每层神经元数的元组。 | (100,) 或 (100,50) 是常见起点。 |
alpha | L2 正则化强度。 | 从 0.0001 到 0.01 搜索。 |
activation | 激活函数。 | 默认 relu,几乎总是最佳选择。 |
learning_rate_init | 初始学习率。 | 默认 0.001,一般不用改。 |
练习题
第 1 题:如果 MLP 没有激活函数,它等价于什么模型?
参考思路:等价于线性模型。多层线性变换的组合仍然是线性变换,无法学习非线性关系。
第 2 题:hidden_layer_sizes=(100, 50, 25) 表示什么结构?一共有几层?
参考思路:3 个隐藏层,分别有 100、50、25 个神经元。加上输入层和输出层,一共 5 层。
检查点
离开本章前,请确认:
- 能画出 MLP 的层结构(输入 → 隐藏 → 输出)。
- 能解释激活函数(尤其 ReLU)为什么是必要的。
- 能说清反向传播的核心:链式法则 + 梯度下降。
- 能用 MLPClassifier + GridSearchCV 完成分类实战。