共计 1500 个字符,预计需要花费 4 分钟才能阅读完成。
历史背景与算法重要性
1986 年是神经网络发展的关键转折点。当时单层感知机受限于线性可分问题,而 Rumelhart、Hinton 和 Williams 在《Nature》发表的论文首次完整描述了多层感知机(MLP)与反向传播(Backpropagation)算法,解决了非线性分类的核心难题。这一突破为现代深度学习奠定了基础,其核心思想至今仍是神经网络训练的基石。

数学原理分步解析
1. 多层感知机结构
典型的三层 MLP 包含:
– 输入层(n 个神经元)
– 隐藏层(m 个神经元,使用 Sigmoid 激活)
– 输出层(k 个神经元)
数学表达式:
h = σ(W₁x + b₁)
ŷ = σ(W₂h + b₂)
其中 σ 表示 Sigmoid 函数:σ(z)=1/(1+e⁻ᶻ)
2. 反向传播四步推导
- 前向计算 :逐层计算激活值
- 损失计算 :采用均方误差 L=½(y-ŷ)²
- 误差反向传播 :
- 输出层误差:δ₂ = (ŷ-y)⊙σ'(z₂)
- 隐藏层误差:δ₁ = (W₂ᵀδ₂)⊙σ'(z₁)
- 权重更新 :
- ΔW₂ = ηδ₂hᵀ
- ΔW₁ = ηδ₁xᵀ
(⊙表示逐元素乘法,η 为学习率)
Python 实现示例
import numpy as np
class MLP:
def __init__(self, input_size, hidden_size, output_size):
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros(hidden_size)
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros(output_size)
def sigmoid(self, z):
return 1/(1+np.exp(-z))
def forward(self, x):
self.z1 = np.dot(x, self.W1) + self.b1
self.h = self.sigmoid(self.z1)
self.z2 = np.dot(self.h, self.W2) + self.b2
return self.sigmoid(self.z2)
def train(self, x, y, lr=0.1):
y_pred = self.forward(x)
# 反向传播
dL_dz2 = (y_pred - y) * y_pred * (1 - y_pred)
dL_dW2 = np.dot(self.h.T, dL_dz2)
dL_db2 = np.sum(dL_dz2, axis=0)
dL_dh = np.dot(dL_dz2, self.W2.T)
dL_dz1 = dL_dh * self.h * (1 - self.h)
dL_dW1 = np.dot(x.T, dL_dz1)
dL_db1 = np.sum(dL_dz1, axis=0)
# 参数更新
self.W2 -= lr * dL_dW2
self.b2 -= lr * dL_db2
self.W1 -= lr * dL_dW1
self.b1 -= lr * dL_db1
常见陷阱与调试技巧
- 梯度消失问题 :
- 现象:深层网络训练停滞
-
解决方案:改用 ReLU 激活函数
-
初始化陷阱 :
- 错误做法:权重初始化为 0
-
正确方法:Xavier 初始化
-
学习率选择 :
- 推荐策略:先用 0.01 尝试,观察损失曲线
现代演进与应用
- 卷积神经网络中的 BP 改良
- LSTM 中的 BPTT 算法
- 自动微分框架(PyTorch/TensorFlow)的底层原理
延伸思考
- 如何设计动态学习率策略?
- 当训练集准确率高但测试集差时,可能是什么原因?
- 批量归一化如何帮助反向传播?
这个经典算法就像神经网络的『乘法口诀表』,理解它才能驾驭更复杂的模型。建议读者亲手实现代码并尝试不同的激活函数,这是掌握深度学习真正的起点。
正文完
发表至: 未分类
近一天内
