梯度下降与反向传播算法详解
立即解锁
发布时间: 2025-09-01 01:46:36 阅读量: 4 订阅数: 11 AIGC 

### 梯度下降与反向传播算法详解
#### 1. 梯度下降与局部极小值
在优化问题中,梯度下降是一种常用的方法,它通过沿着梯度的反方向更新参数,以最快的速度接近损失函数的最小值。梯度的方向是函数增长最快的方向,因此沿着梯度的反方向可以使函数值下降最快。
然而,梯度下降存在一个问题,即它可能会陷入局部极小值。局部极小值是指在某个区域内,函数值达到最小,但不是全局最小。不同的起始点可能会导致梯度下降算法收敛到不同的极小值点,如图所示。
在早期,优化技术会尽力避免局部极小值,尝试收敛到全局极小值,例如模拟退火和隧道法等。但现代神经网络采取了不同的态度,有时局部极小值也可以是一个可接受的解决方案,如果不满意,还可以重新训练神经网络,因为重新训练会从随机位置开始,有可能找到更好的极小值。
#### 2. 简单网络上的反向传播算法
我们先从一个简单的多层感知器(MLP)开始研究反向传播算法,该网络每层只有一个神经元。这样的简化使得权重和偏置不需要下标,只需用上标表示层的编号。
##### 2.1 辅助变量定义
定义辅助变量 $\delta^{(l)} = \frac{\partial L}{\partial z^{(l)}}$,它表示损失函数 $L$ 相对于第 $l$ 层预激活输出 $z^{(l)}$ 的变化率。
##### 2.2 前向传播方程
对于任意层 $l \in \{0, L\}$,前向传播方程如下:
- $z^{(l)} = w^{(l)}a^{(l - 1)} + b^{(l)}$
- $a^{(l)} = \sigma(z^{(l)})$
其中,$z^{(l)}$ 是第 $l$ 层的加权和,$a^{(l)}$ 是第 $l$ 层的激活输出,$\sigma$ 是激活函数(这里使用的是 sigmoid 函数)。
##### 2.3 损失函数
对于单个训练数据实例 $(x_i, y_i)$,损失函数采用均方误差(MSE):
$L = \frac{1}{2}(a^{(L)} - \bar{y}_i)^2$
##### 2.4 偏导数计算
- **最后一层 $L$ 的权重和偏置的偏导数**:
- $\frac{\partial L}{\partial w^{(L)}} = \delta^{(L)} \cdot a^{(L - 1)}$
- $\frac{\partial L}{\partial b^{(L)}} = \delta^{(L)}$
- **任意层 $l$ 的权重和偏置的偏导数**:
- $\frac{\partial L}{\partial w^{(l)}} = \delta^{(l)} a^{(l - 1)}$
- $\frac{\partial L}{\partial b^{(l)}} = \delta^{(l)}$
- **最后一层 $L$ 的辅助变量**:
$\delta^{(L)} = (a^{(L)} - \bar{y}_i) a^{(L)} (1 - a^{(L)})$
- **任意层 $l$ 的辅助变量**:
$\delta^{(l)} = \delta^{(l + 1)} w^{(l + 1)} a^{(l)} (1 - a^{(l)})$
##### 2.5 前向传播和反向传播过程
前向传播过程是从输入层开始,依次计算每层的输出,直到输出层。具体步骤如下:
1. 初始化权重 $w^{(l)}$ 和偏置 $b^{(l)}$。
2. 计算 $z^{(0)}$ 和 $a^{(0)}$:$z^{(0)} = w^{(0)}x + b^{(0)}$,$a^{(0)} = \sigma(z^{(0)})$。
3. 利用前向传播方程依次计算后续层的输出,直到得到输出层的输出 $a^{(L)}$。
反向传播过程则是从输出层开始,反向计算每层的辅助变量 $\delta^{(l)}$,并更新权重和偏置。具体步骤如下:
1. 计算最后一层的辅助变量 $\delta^{(L)}$。
2. 利用 $\delta^{(L)}$ 计算 $\delta^{(L - 1)}$,依次类推,直到计算出 $\delta^{(0)}$。
3. 每次计算出 $\delta^{(l)}$ 后,同时计算该层权重和偏置的偏导数,并更新权重和偏置。
以下是 PyTorch 实现的前向传播和反向传播代码:
```python
def forward_backward(x, y, W, b):
L = len(W) - 1
a = []
for l in range(0, L + 1):
a_prev = x if l == 0 else a[l - 1]
# 前向传播
z_l = Z(a_prev, W[l], b[l])
a_l = A(z_l)
a.append(a_l)
loss = mse_loss(a[L], y)
# 计算 MSE 损失
deltas = [None for _ in range(L + 1)]
W_grads = [None for _ in range(L + 1)]
# 存储 δ(l), ∂L/∂w(l), ∂L/∂b(l) 的数组
b_grads = [None for _ in range(L + 1)]
a_L = a[L]
# 最后一层的激活输出
deltas[L] = (a_L - y) * a_L * (1 - a_L)
W_grads[L] = torch.matmul(deltas[L], a[L - 1].T)
# 计算第 L 层的 δ 和梯度
b_grads[L] = deltas[L]
for l in range(L - 1, -1, -
```
0
0
复制全文
相关推荐









