深度学习入门:手把手推导bf反向传播算法

1次阅读
没有评论

共计 1476 个字符,预计需要花费 4 分钟才能阅读完成。

image.webp

反向传播算法的重要性

反向传播(Backpropagation)是深度学习中最核心的算法之一,它的主要作用是通过计算损失函数对网络参数的梯度,来指导神经网络权重的更新。简单来说,就是告诉网络 ” 如何调整参数才能减少预测误差 ”。这种方法在图像识别、自然语言处理等任务中被广泛应用。

深度学习入门:手把手推导 bf 反向传播算法

数学推导过程

1. 前向传播计算

前向传播是指输入数据通过网络层层传递得到输出的过程。以一个简单的三层网络为例:

  • 输入层:x
  • 隐藏层:h = σ(W₁x + b₁)
  • 输出层:ŷ = W₂h + b₂

其中 σ 是激活函数,常用 Sigmoid 或 ReLU。

2. 损失函数

我们使用均方误差 (MSE) 作为损失函数:

L = 1/2(y – ŷ)²

3. 反向传播推导

核心是链式法则,我们从输出层开始反向计算梯度:

  1. 计算损失对输出 ŷ的偏导:∂L/∂ŷ = -(y – ŷ)
  2. 计算 ŷ对 W₂的偏导:∂ŷ/∂W₂ = h
  3. 所以 W₂的梯度:∂L/∂W₂ = ∂L/∂ŷ * ∂ŷ/∂W₂ = -(y – ŷ)h
  4. 同理计算 b₂的梯度:∂L/∂b₂ = -(y – ŷ)

继续反向传播到隐藏层:

  1. 计算 ŷ对 h 的偏导:∂ŷ/∂h = W₂
  2. h 对 z(W₁x + b₁)的偏导:∂h/∂z = σ'(z)
  3. 所以 W₁的梯度:∂L/∂W₁ = ∂L/∂ŷ * ∂ŷ/∂h * ∂h/∂z * ∂z/∂W₁ = -(y – ŷ)W₂σ'(z)x

Python 实现

import numpy as np

# 定义 Sigmoid 函数及其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

# 初始化参数
input_size = 2
hidden_size = 3
output_size = 1

# 随机初始化权重
W1 = np.random.randn(input_size, hidden_size)
W2 = np.random.randn(hidden_size, output_size)

# 前向传播
def forward(x):
    z1 = np.dot(x, W1)
    h = sigmoid(z1)
    z2 = np.dot(h, W2)
    y_hat = z2
    return y_hat, h

# 反向传播
def backward(x, y, y_hat, h, learning_rate=0.01):
    # 计算输出层梯度
    dL_dyhat = -(y - y_hat)
    dW2 = np.dot(h.T, dL_dyhat)

    # 计算隐藏层梯度
    dL_dh = np.dot(dL_dyhat, W2.T)
    dL_dz1 = dL_dh * sigmoid_derivative(h)
    dW1 = np.dot(x.T, dL_dz1)

    # 更新权重
    W1 -= learning_rate * dW1
    W2 -= learning_rate * dW2

常见错误分析

  1. 梯度消失:当使用 Sigmoid 激活函数时,其导数最大值为 0.25,经过多层传播后梯度会变得极小。解决方法:使用 ReLU 等激活函数。

  2. 初始化问题:权重初始化为 0 会导致所有神经元学习相同的内容。解决方法:使用随机初始化。

  3. 学习率过大:可能导致振荡或发散。解决方法:使用学习率衰减策略。

不同网络结构中的变体

  1. CNN 中的反向传播:需要考虑卷积核的局部连接和参数共享特性,梯度计算更复杂。

  2. RNN 中的反向传播:由于时间步的存在,需要使用 BPTT(Backpropagation Through Time)算法。

延伸思考

  1. 批量归一化如何影响反向传播过程?
  2. 为什么深度网络容易出现梯度消失或爆炸?
  3. 如何验证反向传播实现的正确性?

反向传播是深度学习的基石算法,理解其原理对掌握深度学习至关重要。希望这篇教程能帮助你建立起直观的理解,为后续学习打下坚实基础。

正文完
 0
评论(没有评论)