共计 1753 个字符,预计需要花费 5 分钟才能阅读完成。
前馈神经网络是图像识别、语音处理等领域的核心工具,它能自动学习输入数据的复杂特征。通过多层非线性变换,网络可以逼近任意函数关系,为现代 AI 系统提供基础支撑。理解其工作原理是掌握深度学习的关键第一步。

数学推导:从神经元到反向传播
1. 单神经元计算向量化
单个神经元的输出可表示为:
$$z = w^Tx + b$$
$$a = \sigma(z)$$
其中 $\sigma$ 是 Sigmoid 函数:
$$\sigma(z) = \frac{1}{1+e^{-z}}$$
当处理批量数据时,使用矩阵运算高效实现:
$$Z = XW + B$$
$$A = \sigma(Z)$$
这里 $X$ 是 $n\times m$ 输入矩阵,$W$ 是 $m\times k$ 权重矩阵。
2. 链式法则应用示例
以输出层神经元为例,损失函数 $L$ 对权重 $w_{ij}$ 的梯度:
$$\frac{\partial L}{\partial w_{ij}} = \frac{\partial L}{\partial a_j}\frac{\partial a_j}{\partial z_j}\frac{\partial z_j}{\partial w_{ij}}$$
具体展开为:
$$\delta_j = (a_j – y_j)\cdot a_j(1-a_j)\cdot x_i$$
3. 学习率与梯度下降
权重更新公式:
$$W_{new} = W_{old} – \eta \cdot \nabla_W$$
其中 $\eta$ 是学习率,直接影响收敛速度。建议初始值设为 0.01,根据损失曲线动态调整。
Python 实现核心代码
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_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, 1) * 0.01
self.b2 = np.zeros(1)
def sigmoid(self, z):
return 1/(1+np.exp(-z))
def forward(self, X):
# 输入层→隐藏层 (batch_size, hidden_size)
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
# 隐藏层→输出层 (batch_size, 1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
return self.sigmoid(self.z2)
def backward(self, X, y, output, lr=0.01):
# 输出层误差 (batch_size, 1)
dL_dz2 = (output - y) * output * (1 - output)
# 隐藏层误差 (batch_size, hidden_size)
dL_da1 = np.dot(dL_dz2, self.W2.T)
dL_dz1 = dL_da1 * self.a1 * (1 - self.a1)
# 参数更新
self.W2 -= lr * np.dot(self.a1.T, dL_dz2)
self.b2 -= lr * np.sum(dL_dz2, axis=0)
self.W1 -= lr * np.dot(X.T, dL_dz1)
self.b1 -= lr * np.sum(dL_dz1, axis=0)
避坑指南
-
梯度消失识别 :当连续层的梯度值小于 0.01 时,网络可能无法有效更新浅层参数。可通过梯度直方图监测。
-
学习率设置 :参考公式 $\eta = 0.1/\sqrt{\text{batch_size}}$,配合学习率衰减策略。
-
权重初始化 :隐藏层建议采用 He 初始化:$W \sim N(0, \sqrt{2/n_{in}})$,避免对称失效。
思考题
- 如何设计数值梯度检验来验证反向传播的正确性?
- 当网络深度增加时,为什么需要调整初始化方式和学习率?
- 使用 ReLU 激活函数时,反向传播公式需要做哪些修改?
理解 BP 算法的核心在于把握误差从输出层向输入层逐层传递的过程。通过代码实现与理论推导相互验证,能更深刻地认识神经网络的学习机制。建议读者尝试扩展网络结构,观察不同超参数对训练过程的影响。
