11
神经网络基础与反向传播
Neural Network Basics & Backpropagation
从一个神经元讲到多层网络,把"反向传播"讲透。这一章是理解一切深度学习的地基。
感知机:最简单的神经元
论为什么解决不了异或
感知机 = 加权求和 + 阶跃函数,本质是线性分类器。异或问题不是线性可分的,单层感知机搞不定。加一层隐藏层,就能拟合任意非线性函数——这就是 MLP。
感知机为什么解决不了异或
# 异或真值表:(0,0)->0, (0,1)->1, (1,0)->1, (1,1)->0
# 一条直线分不开两类点(线性不可分)
import numpy as np
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([0, 1, 1, 0])
# 单层感知机(Linear)无法分开
# 加一个隐藏层:先把二维映射到更高维,再线性分开
# 这就是 MLP 万能逼近定理:1 个隐藏层能拟合任意连续函数
MLP:多层感知机
from sklearn.neural_network import MLPClassifier
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
digits = load_digits()
X, y = digits.data, digits.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train_s = StandardScaler().fit_transform(X_train)
X_test_s = StandardScaler().fit(X_train).transform(X_test)
# 两个隐藏层:128 + 64
mlp = MLPClassifier(hidden_layer_sizes=(128, 64),
activation="relu", solver="adam",
alpha=0.001, max_iter=500, random_state=42)
mlp.fit(X_train_s, y_train)
print("准确率:", mlp.score(X_test_s, y_test))
# 准确率:0.9722
激活函数对比
| 激活 | 公式 / 特点 | 什么时候用 |
|---|---|---|
| Sigmoid | 1/(1+e⁻ˣ),(0,1),两端饱和梯度小 | 二分类输出层;隐藏层少用。 |
| Tanh | (-1,1),零中心,仍饱和 | RNN 隐藏层。 |
| ReLU | max(0,x),计算快、不饱和 | 默认隐藏层激活。 |
| LeakyReLU | x>0 用 x,否则 ax(a=0.01) | 解决 ReLU 神经元死亡。 |
| GELU | 平滑版 ReLU | Transformer 默认。 |
| Softmax | 多分类输出,概率和为 1 | 多分类输出层。 |
反向传播:从结果倒推谁的错
论链式法则的工程化
前向传播:x → 每层激活 → 预测 → loss。反向传播:从 loss 出发,用链式法则逐层算 ∂L/∂W,存到每个参数的 .grad。优化器再用这些梯度更新参数。PyTorch 的 loss.backward() 一行搞定。
本章面试题
面试 · 神经网络基础
Q1. 为什么需要激活函数?
查看答案
没有非线性激活,多层网络叠加还是线性变换,等价于单层。激活函数让网络能拟合任意函数。
Q2. ReLU 比 Sigmoid 好在哪?
查看答案
不饱和(正区间梯度恒为 1,缓解梯度消失)、计算简单、稀疏激活。
Q3. 梯度消失和梯度爆炸?
查看答案
多层链式相乘,小于 1 的梯度连乘变 0(消失),大于 1 的连乘变 NaN(爆炸)。对策:ReLU、合理初始化(Xavier/He)、BatchNorm、残差连接、梯度裁剪。
Q4. 损失函数怎么选?
查看答案
回归 MSE/MAE;二分类 BCEWithLogitsLoss;多分类 CrossEntropyLoss(自带 Softmax)。