
下面是一个用 Python + NumPy 从零实现的 BP 神经网络(反向传播)脚本模型,包含前向传播、反向传播、训练和预测,并用 XOR 数据做示例。
```python
import numpy as np
class BPNeuralNetwork:
def __init__(self, input_size, hidden_size, output_size, lr=0.5):
"""
input_size: 输入维度
hidden_size: 隐藏层神经元数量
output_size: 输出维度
lr: 学习率
"""
np.random.seed(42)
# 初始化权重和偏置
self.W1 = np.random.randn(input_size, hidden_size) * np.sqrt(1 / input_size)
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * np.sqrt(1 / hidden_size)
self.b2 = np.zeros((1, output_size))
self.lr = lr
def sigmoid(self, z):
return 1.0 / (1.0 + np.exp(-z))
def sigmoid_derivative(self, z):
s = self.sigmoid(z)
return s * (1 – s)
def forward(self, X):
"""前向传播"""
self.z1 = X @ self.W1 + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = self.a1 @ self.W2 + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y):
"""反向传播 + 参数更新"""
m = X.shape[0]
# 输出层误差
delta2 = (self.a2 – y) * self.sigmoid_derivative(self.z2)
dW2 = self.a1.T @ delta2 / m
db2 = np.sum(delta2, axis=0, keepdims=True) / m
# 隐藏层误差
delta1 = (delta2 @ self.W2.T) * self.sigmoid_derivative(self.z1)
dW1 = X.T @ delta1 / m
db1 = np.sum(delta1, axis=0, keepdims=True) / m
# 梯度下降更新参数
self.W2 -= self.lr * dW2
self.b2 -= self.lr * db2
self.W1 -= self.lr * dW1
self.b1 -= self.lr * db1
def train(self, X, y, epochs=10000, verbose=True):
"""训练模型"""
for i in range(epochs):
self.forward(X)
self.backward(X, y)
if verbose and (i + 1) % 1000 == 0:
loss = np.mean((self.a2 – y) ** 2)
print(f"epoch {i + 1}, loss={loss:.6f}")
def predict(self, X, threshold=0.5):
"""预测类别"""
prob = self.forward(X)
return (prob >= threshold).astype(int)
if __name__ == "__main__":
# XOR 数据集
X = np.array([
[0, 0],
[0, 1],
[1, 0],
[1, 1]
], dtype=float)
y = np.array([
[0],
[1],
[1],
[0]
], dtype=float)
# 创建 BP 模型:2 输入,4 隐藏神经元,1 输出
bp = BPNeuralNetwork(
input_size=2,
hidden_size=4,
output_size=1,
lr=0.5
)
# 训练
bp.train(X, y, epochs=10000, verbose=True)
# 预测概率
print("\\n预测概率:")
print(bp.forward(X))
# 预测类别
print("\\n预测类别:")
print(bp.predict(X))
```
运行后会输出类似:
```text
epoch 1000, loss=0.250000
epoch 2000, loss=0.120000
…
预测概率:
[[0.01]
[0.98]
[0.98]
[0.02]]
预测类别:
[[0]
[1]
[1]
[0]]
```
这个模型的核心就是:
1. 前向传播:输入 → 隐藏层 → 输出层
2. 计算损失:这里使用均方误差 MSE
3. 反向传播:从输出层误差逐层往回计算梯度
4. 梯度下降:更新权重和偏置
5. 重复训练:直到损失收敛
此文章仅为学习参考用。


