共计 2030 个字符,预计需要花费 6 分钟才能阅读完成。
异或问题的线性不可分性
异或(XOR)运算的真值表如下:

| $x_1$ | $x_2$ | $y$ |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
其决策边界需要满足:
$\begin{cases}
w_1x_1 + w_2x_2 + b \leq 0 & \text{当} y=0 \
w_1x_1 + w_2x_2 + b > 0 & \text{当} y=1
\end{cases}$
通过代数证明可知,不存在直线能完美分割这四个点。几何直观如下图所示(此处可插入二维坐标图示)。
网络结构对比分析
- 单层感知机局限
- 仅含输入层和输出层
- 决策函数为 $f(\mathbf{w}^T\mathbf{x} + b)$
-
只能学习线性决策边界
-
BP 网络优势
- 引入隐藏层实现特征变换
- 典型结构:2-2-1(输入 - 隐藏 - 输出)
- 通过非线性激活函数实现空间扭曲
核心数学推导
Sigmoid 函数及其导数
$\sigma(z) = \frac{1}{1+e^{-z}}$
导数计算过程:
$\begin{aligned}
\sigma'(z) &= \frac{d}{dz}\left(1 + e^{-z}\right)^{-1} \
&= -1 \cdot (1 + e^{-z})^{-2} \cdot (-e^{-z}) \
&= \frac{e^{-z}}{(1 + e^{-z})^2} = \sigma(z)(1 – \sigma(z))
\end{aligned}$
反向传播公式
对于三层网络,定义:
– 隐藏层输出:$\mathbf{h} = \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)$
– 最终输出:$\hat{y} = \sigma(\mathbf{W}_2 \mathbf{h} + \mathbf{b}_2)$
误差反向传播时:
$\begin{aligned}
\delta_2 &= (\hat{y} – y) \odot \sigma'(\mathbf{z}_2) \
\delta_1 &= (\mathbf{W}_2^T \delta_2) \odot \sigma'(\mathbf{z}_1)
\end{aligned}$
Python 实现代码
import numpy as np
class BPNeuralNetwork:
def __init__(self, input_size, hidden_size):
# 使用 He 初始化策略
self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(2./input_size)
self.b1 = np.zeros(hidden_size)
self.W2 = np.random.randn(hidden_size, 1) * np.sqrt(2./hidden_size)
self.b2 = np.zeros(1)
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 backward(self, X, y, lr):
m = X.shape[0]
# 输出层误差
dZ2 = self.y_pred - y
dW2 = np.dot(self.h.T, dZ2) / m
db2 = np.sum(dZ2, axis=0) / m
# 隐藏层误差
dH = np.dot(dZ2, self.W2.T)
dZ1 = dH * self.h * (1 - self.h)
dW1 = np.dot(X.T, dZ1) / m
db1 = np.sum(dZ1, axis=0) / m
# 参数更新
self.W2 -= lr * dW2
self.b2 -= lr * db2
self.W1 -= lr * dW1
self.b1 -= lr * db1
# 训练示例
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [1], [1], [0]])
model = BPNeuralNetwork(input_size=2, hidden_size=2)
for epoch in range(10000):
y_pred = model.forward(X)
model.backward(X, y, lr=0.1)
实验分析
- 学习率影响
- 过大(>0.5):损失震荡发散
- 过小(<0.01):收敛速度极慢
-
推荐范围:0.05-0.2
-
隐藏层规模
- 2 个神经元:基本满足需求
- 4 个神经元:更快收敛但可能过拟合
- 实验记录(建议插入训练曲线对比图)
避坑指南
- 梯度消失对策
- 改用 ReLU 激活函数
- 添加 BatchNorm 层
-
残差连接设计
-
权重初始化
- 输入层:Xavier 初始化
- 隐藏层:He 初始化
-
输出层:小随机数
-
学习率调整
- 余弦退火策略
- 验证集监控早停
- 自适应优化器(Adam)
扩展思考
如何改造当前网络实现三分类任务?考虑以下方向:
– 输出层改用 Softmax
– 损失函数改为交叉熵
– 隐藏层增加 Dropout 正则化
