共计 2167 个字符,预计需要花费 6 分钟才能阅读完成。
神经网络基础概念
BP 神经网络(Back Propagation Neural Network)是一种典型的前馈神经网络,由输入层、隐藏层(可以有多层)和输出层组成。每一层由若干个神经元(节点)构成,层与层之间通过权重连接。它的学习过程分为正向传播和反向传播两个阶段。

- 输入层:接收外部输入数据
- 隐藏层:对输入数据进行非线性变换
- 输出层:输出最终预测结果
正向传播的数学原理
正向传播是指数据从输入层经过隐藏层最终到达输出层的过程。在这个过程中,每个神经元都会对输入进行加权求和,然后通过激活函数进行非线性转换。
-
加权求和:
$$z_j = \sum_{i=1}^n w_{ji}x_i + b_j$$
其中,$w_{ji}$ 是连接输入 $x_i$ 和神经元 $j$ 的权重,$b_j$ 是偏置项。 -
激活函数计算:
$$a_j = \sigma(z_j)$$
常用的激活函数包括 Sigmoid、ReLU 和 tanh 等。 -
逐层计算直到输出层,得到预测值 $\hat{y}$
反向传播算法详解
反向传播是通过计算损失函数对权重的梯度,然后使用梯度下降法更新权重参数的过程。
-
计算损失函数(以均方误差为例):
$$L = \frac{1}{2}(y – \hat{y})^2$$ -
输出层误差计算:
$$\delta_j = (\hat{y}_j – y_j)\sigma'(z_j)$$ -
隐藏层误差反向传播(链式法则):
$$\delta_j = \sigma'(z_j)\sum_k w_{kj}\delta_k$$ -
权重更新(梯度下降):
$$\Delta w_{ji} = -\eta \delta_j a_i$$
$$w_{ji} = w_{ji} + \Delta w_{ji}$$
其中,$\eta$ 是学习率。
Python 代码实现
import numpy as np
# 定义 Sigmoid 激活函数及其导数
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return x * (1 - x)
# 神经网络类
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
# 初始化权重
self.weights1 = np.random.randn(input_size, hidden_size)
self.weights2 = np.random.randn(hidden_size, output_size)
def forward(self, X):
# 正向传播
self.hidden = sigmoid(np.dot(X, self.weights1))
self.output = sigmoid(np.dot(self.hidden, self.weights2))
return self.output
def backward(self, X, y, output, learning_rate):
# 反向传播
output_error = y - output
output_delta = output_error * sigmoid_derivative(output)
hidden_error = np.dot(output_delta, self.weights2.T)
hidden_delta = hidden_error * sigmoid_derivative(self.hidden)
# 更新权重
self.weights2 += learning_rate * np.dot(self.hidden.T, output_delta)
self.weights1 += learning_rate * np.dot(X.T, hidden_delta)
# 示例:XOR 问题
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# 创建神经网络
nn = NeuralNetwork(2, 4, 1)
# 训练
for i in range(10000):
output = nn.forward(X)
nn.backward(X, y, output, 0.1)
if i % 1000 == 0:
print(f"Epoch {i}, Loss: {np.mean(np.square(y - output))}")
# 测试
print("Final predictions:")
print(nn.forward(X))
避坑指南
- 梯度消失 / 爆炸问题:
- 使用 ReLU 等激活函数替代 Sigmoid
- 采用权重初始化方法(如 Xavier 初始化)
-
使用 Batch Normalization
-
学习率选择:
- 初始学习率通常设置在 0.01-0.1 之间
-
可以使用学习率衰减策略
-
激活函数选择:
- Sigmoid:输出范围(0,1),适合二分类
- tanh:输出范围(-1,1),中心对称
- ReLU:计算简单,缓解梯度消失
思考题
- 如何改进基础 BP 算法提高收敛速度?可以考虑动量法、自适应学习率等方法。
- 批量训练与在线训练各有何优劣?批量训练更稳定但需要更多内存,在线训练更灵活但可能不稳定。
- 不同优化器 (如 Adam) 的实现原理是什么?Adam 结合了动量法和 RMSProp 的优点。
通过本文的学习,你应该对 BP 神经网络的正向传播和反向传播有了基本的理解。建议读者尝试修改代码中的网络结构和参数,观察不同设置对模型性能的影响,这是掌握神经网络的最好方法。
