1.8讲道理——什么是反向传播?

部署运行你感兴趣的模型镜像

一、反向传播基础概念

  1. 定义:反向传播是神经网络中用于计算参数梯度、进而通过优化器更新参数的核心算法,核心逻辑是“从输出层到输入层,沿前向传播的反方向传递误差,并计算各层参数对损失的梯度”。

  2. 核心作用:解决神经网络参数优化问题,通过梯度指引参数调整方向,使模型的损失函数值不断减小,最终提升模型预测精度。

  3. 前置知识

    • 链式法则:多变量函数求导的核心规则,反向传播中梯度的传递依赖链式法则逐层计算。

    • 损失函数:用于衡量模型预测值与真实值的差异,如均方误差(MSE)、交叉熵损失等,是反向传播的“误差源头”。

    • 神经网络基本结构:需明确输入层、隐藏层、输出层的神经元数量,以及各层使用的激活函数(如Sigmoid、ReLU)。

二、反向传播核心原理(三步法)

在这里插入图片描述

1. 第一步:前向传播(计算预测值与损失)

  • 按“输入层→隐藏层→输出层”的顺序,计算每一层的输出值。

  • 以单隐藏层网络为例,假设输入为 xxx ,隐藏层权重为 W1W_1W1 、偏置为 b1b_1b1 ,激活函数为 σ\sigmaσ ,输出层权重为 W2W_2W2 、偏置为 b2b_2b2 ,则:

    • 隐藏层输入: z1=W1x+b1z_1 = W_1x + b_1z1=W1x+b1

    • 隐藏层输出: a1=σ(z1)a_1 = \sigma(z_1)a1=σ(z1)

    • 输出层输入: z2=W2a1+b2z_2 = W_2a_1 + b_2z2=W2a1+b2

    • 模型预测值: ypred=σ(z2)y_{pred} = \sigma(z_2)ypred=σ(z2) (若为回归任务,输出层可无激活函数)

  • 计算损失:根据损失函数,对比 ypredy_{pred}ypred 与真实标签 ytruey_{true}ytrue ,得到损失值 LLL (如MSE损失 L=12(ypred−ytrue)2L = \frac{1}{2}(y_{pred} - y_{true})^2L=21(ypredytrue)2 )。

2. 第二步:反向传播(计算各参数梯度)

  • 从输出层开始,沿“输出层→隐藏层→输入层”的反方向,利用链式法则计算各参数( W2W_2W2b2b_2b2W1W_1W1b1b_1b1 )对损失 LLL 的梯度。

  • 关键梯度计算逻辑:

    • 输出层参数梯度:先求损失对输出层输入 z2z_2z2 的梯度(记为 δ2=∂L∂z2\delta_2 = \frac{\partial L}{\partial z_2}δ2=z2L ),再结合隐藏层输出 a1a_1a1 ,得到 ∂L∂W2=δ2⋅a1T\frac{\partial L}{\partial W_2} = \delta_2 \cdot a_1^TW2L=δ2a1T∂L∂b2=δ2\frac{\partial L}{\partial b_2} = \delta_2b2L=δ2

    • 隐藏层参数梯度:先将输出层的梯度 δ2\delta_2δ2 传递到隐藏层,得到损失对隐藏层输入 z1z_1z1 的梯度( δ1=W2T⋅δ2⋅σ′(z1)\delta_1 = W_2^T \cdot \delta_2 \cdot \sigma'(z_1)δ1=W2Tδ2σ(z1) ,其中 σ′(z1)\sigma'(z_1)σ(z1) 是激活函数的导数),再结合输入 xxx ,得到 ∂L∂W1=δ1⋅xT\frac{\partial L}{\partial W_1} = \delta_1 \cdot x^TW1L=δ1xT∂L∂b1=δ1\frac{\partial L}{\partial b_1} = \delta_1b1L=δ1

3. 第三步:参数更新(基于梯度优化)

  • 利用计算出的参数梯度,结合优化器(如随机梯度下降SGD)更新参数,更新公式为: Wnew=Wold−η⋅∂L∂WW_{new} = W_{old} - \eta \cdot \frac{\partial L}{\partial W}Wnew=WoldηWLbnew=bold−η⋅∂L∂bb_{new} = b_{old} - \eta \cdot \frac{\partial L}{\partial b}bnew=boldηbL ,其中 η\etaη 是学习率(控制每步参数更新的幅度)。

三、具体计算案例(单隐藏层神经网络)

1. 案例设定

  • 网络结构:输入层(1个神经元, x=1x=1x=1 )→ 隐藏层(2个神经元)→ 输出层(1个神经元)。

  • 激活函数:全层使用Sigmoid函数( σ(z)=11+e−z\sigma(z) = \frac{1}{1+e^{-z}}σ(z)=1+ez1 ,导数 σ′(z)=σ(z)(1−σ(z))\sigma'(z) = \sigma(z)(1-\sigma(z))σ(z)=σ(z)(1σ(z)) )。

  • 初始参数: W1=[0.10.20.30.4]W_1 = \begin{bmatrix} 0.1 & 0.2 \\ 0.3 & 0.4 \end{bmatrix}W1=[0.10.30.20.4]b1=[0.50.6]b_1 = \begin{bmatrix} 0.5 \\ 0.6 \end{bmatrix}b1=[0.50.6]W2=[0.70.8]W_2 = \begin{bmatrix} 0.7 & 0.8 \end{bmatrix}W2=[0.70.8]b2=0.9b_2 = 0.9b2=0.9

  • 真实标签: ytrue=0.5y_{true} = 0.5ytrue=0.5

2. 第一步:前向传播计算

  1. 隐藏层输入: z1=W1x+b1=[0.1×1+0.50.3×1+0.6]=[0.60.9]z_1 = W_1x + b_1 = \begin{bmatrix} 0.1×1 + 0.5 \\ 0.3×1 + 0.6 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 0.9 \end{bmatrix}z1=W1x+b1=[0.1×1+0.50.3×1+0.6]=[0.60.9]

  2. 隐藏层输出: a1=σ(z1)=[11+e−0.6≈0.645711+e−0.9≈0.7109]a_1 = \sigma(z_1) = \begin{bmatrix} \frac{1}{1+e^{-0.6}} ≈ 0.6457 \\ \frac{1}{1+e^{-0.9}} ≈ 0.7109 \end{bmatrix}a1=σ(z1)=[1+e0.610.64571+e0.910.7109]

  3. 输出层输入: z2=W2a1+b2=0.7×0.6457+0.8×0.7109+0.9≈0.452+0.5687+0.9≈1.9207z_2 = W_2a_1 + b_2 = 0.7×0.6457 + 0.8×0.7109 + 0.9 ≈ 0.452 + 0.5687 + 0.9 ≈ 1.9207z2=W2a1+b2=0.7×0.6457+0.8×0.7109+0.90.452+0.5687+0.91.9207

  4. 预测值: ypred=σ(z2)≈11+e−1.9207≈0.8707y_{pred} = \sigma(z_2) ≈ \frac{1}{1+e^{-1.9207}} ≈ 0.8707ypred=σ(z2)1+e1.920710.8707

  5. 损失值(MSE): L=12(0.8707−0.5)2≈12×0.1374≈0.0687L = \frac{1}{2}(0.8707 - 0.5)^2 ≈ \frac{1}{2}×0.1374 ≈ 0.0687L=21(0.87070.5)221×0.13740.0687

3. 第二步:反向传播计算梯度

  1. 计算输出层梯度( δ2\delta_2δ2 ):

    • δ2=∂L∂z2=(ypred−ytrue)⋅σ′(z2)\delta_2 = \frac{\partial L}{\partial z_2} = (y_{pred} - y_{true}) \cdot \sigma'(z_2)δ2=z2L=(ypredytrue)σ(z2)

    • σ′(z2)=0.8707×(1−0.8707)≈0.1126\sigma'(z_2) = 0.8707×(1-0.8707) ≈ 0.1126σ(z2)=0.8707×(10.8707)0.1126

    • δ2=(0.8707−0.5)×0.1126≈0.3707×0.1126≈0.0417\delta_2 = (0.8707 - 0.5)×0.1126 ≈ 0.3707×0.1126 ≈ 0.0417δ2=(0.87070.5)×0.11260.3707×0.11260.0417

  2. 计算输出层参数梯度:

    • ∂L∂W2=δ2⋅a1T≈0.0417×[0.64570.7109]≈[0.02690.0296]\frac{\partial L}{\partial W_2} = \delta_2 \cdot a_1^T ≈ 0.0417×\begin{bmatrix} 0.6457 & 0.7109 \end{bmatrix} ≈ \begin{bmatrix} 0.0269 & 0.0296 \end{bmatrix}W2L=δ2a1T0.0417×[0.64570.7109][0.02690.0296]

    • ∂L∂b2=δ2≈0.0417\frac{\partial L}{\partial b_2} = \delta_2 ≈ 0.0417b2L=δ20.0417

  3. 计算隐藏层梯度( δ1\delta_1δ1 ):

    • δ1=W2T⋅δ2⋅σ′(z1)\delta_1 = W_2^T \cdot \delta_2 \cdot \sigma'(z_1)δ1=W2Tδ2σ(z1)

    • σ′(z1)=[0.6457×(1−0.6457)≈0.22810.7109×(1−0.7109)≈0.2055]\sigma'(z_1) = \begin{bmatrix} 0.6457×(1-0.6457) ≈ 0.2281 \\ 0.7109×(1-0.7109) ≈ 0.2055 \end{bmatrix}σ(z1)=[0.6457×(10.6457)0.22810.7109×(10.7109)0.2055]

    • W2T⋅δ2=[0.7×0.04170.8×0.0417]≈[0.02920.0334]W_2^T \cdot \delta_2 = \begin{bmatrix} 0.7×0.0417 \\ 0.8×0.0417 \end{bmatrix} ≈ \begin{bmatrix} 0.0292 \\ 0.0334 \end{bmatrix}W2Tδ2=[0.7×0.04170.8×0.0417][0.02920.0334]

    • δ1=[0.0292×0.2281≈0.00670.0334×0.2055≈0.0069]\delta_1 = \begin{bmatrix} 0.0292×0.2281 ≈ 0.0067 \\ 0.0334×0.2055 ≈ 0.0069 \end{bmatrix}δ1=[0.0292×0.22810.00670.0334×0.20550.0069]

  4. 计算隐藏层参数梯度:

    • ∂L∂W1=δ1⋅xT≈[0.0067×10.0069×1]=[0.00670.0069]\frac{\partial L}{\partial W_1} = \delta_1 \cdot x^T ≈ \begin{bmatrix} 0.0067×1 \\ 0.0069×1 \end{bmatrix} = \begin{bmatrix} 0.0067 \\ 0.0069 \end{bmatrix}W1L=δ1xT[0.0067×10.0069×1]=[0.00670.0069] (因 xxx 为1维,结果维度与 W1W_1W1 一致)

    • ∂L∂b1=δ1≈[0.00670.0069]\frac{\partial L}{\partial b_1} = \delta_1 ≈ \begin{bmatrix} 0.0067 \\ 0.0069 \end{bmatrix}b1L=δ1[0.00670.0069]

4. 第三步:参数更新(学习率 η=0.1\eta=0.1η=0.1

  • W2new=W2−η⋅∂L∂W2≈[0.7−0.1×0.02690.8−0.1×0.0296]≈[0.69730.7970]W_2^{new} = W_2 - \eta \cdot \frac{\partial L}{\partial W_2} ≈ \begin{bmatrix} 0.7 - 0.1×0.0269 & 0.8 - 0.1×0.0296 \end{bmatrix} ≈ \begin{bmatrix} 0.6973 & 0.7970 \end{bmatrix}W2new=W2ηW2L[0.70.1×0.02690.80.1×0.0296][0.69730.7970]

  • b2new=0.9−0.1×0.0417≈0.8958b_2^{new} = 0.9 - 0.1×0.0417 ≈ 0.8958b2new=0.90.1×0.04170.8958

  • W1new=W1−η⋅∂L∂W1≈[0.1−0.1×0.00670.2−0.1×0.00670.3−0.1×0.00690.4−0.1×0.0069]≈[0.09930.19930.29930.3993]W_1^{new} = W_1 - \eta \cdot \frac{\partial L}{\partial W_1} ≈ \begin{bmatrix} 0.1 - 0.1×0.0067 & 0.2 - 0.1×0.0067 \\ 0.3 - 0.1×0.0069 & 0.4 - 0.1×0.0069 \end{bmatrix} ≈ \begin{bmatrix} 0.0993 & 0.1993 \\ 0.2993 & 0.3993 \end{bmatrix}W1new=W1ηW1L[0.10.1×0.00670.30.1×0.00690.20.1×0.00670.40.1×0.0069][0.09930.29930.19930.3993]

  • b1new=[0.5−0.1×0.00670.6−0.1×0.0069]≈[0.49930.5993]b_1^{new} = \begin{bmatrix} 0.5 - 0.1×0.0067 \\ 0.6 - 0.1×0.0069 \end{bmatrix} ≈ \begin{bmatrix} 0.4993 \\ 0.5993 \end{bmatrix}b1new=[0.50.1×0.00670.60.1×0.0069][0.49930.5993]

四、PyTorch框架下的反向传播实现(对应视频实战)

1. 核心逻辑

PyTorch通过“动态计算图”自动实现反向传播,无需手动计算梯度,只需定义网络结构、损失函数,调用loss.backward()即可自动求导。

2. 代码示例(对应案例网络)

import torch
import torch.nn as nn
import torch.optim as optim

# 1. 定义网络结构(单隐藏层)
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.hidden = nn.Linear(1, 2)  # 输入1维→隐藏层2维(W1, b1)
        self.output = nn.Linear(2, 1)  # 隐藏层2维→输出1维(W2, b2)
        self.sigmoid = nn.Sigmoid()    # Sigmoid激活函数

    def forward(self, x):
        # 前向传播:x → 隐藏层 → Sigmoid → 输出层 → Sigmoid
        x = self.hidden(x)
        x = self.sigmoid(x)
        x = self.output(x)
        x = self.sigmoid(x)
        return x

# 2. 初始化模型、损失函数、优化器
model = SimpleNN()
# 手动设置初始参数(与案例一致)
model.hidden.weight.data = torch.tensor([[0.1, 0.3], [0.2, 0.4]]).T  # PyTorch中Linear权重维度为(输出维,输入维)
model.hidden.bias.data = torch.tensor([0.5, 0.6])
model.output.weight.data = torch.tensor([[0.7, 0.8]])
model.output.bias.data = torch.tensor([0.9])

criterion = nn.MSELoss()  # 均方误差损失
optimizer = optim.SGD(model.parameters(), lr=0.1)  # SGD优化器,学习率0.1

# 3. 前向传播
x = torch.tensor([[1.0]])  # 输入(批量维度,1个样本)
y_true = torch.tensor([[0.5]])  # 真实标签
y_pred = model(x)  # 预测值
loss = criterion(y_pred, y_true)  # 计算损失

# 4. 反向传播与参数更新
optimizer.zero_grad()  # 清空之前的梯度(避免累积)
loss.backward()        # 自动计算所有参数的梯度(对应手动计算的梯度)
optimizer.step()       # 根据梯度更新参数(对应手动参数更新)

# 5. 打印结果
print("预测值:", y_pred.item())
print("损失值:", loss.item())
print("更新后输出层权重:", model.output.weight.data)

3. 框架优势对比

  • 手动计算:需逐层推导梯度公式,易出错,仅适用于简单网络。

  • PyTorch自动求导:无需关注梯度计算细节,支持复杂网络(如卷积神经网络),且梯度计算高效、准确。

五、常见问题与注意事项

  1. 梯度消失/爆炸

    • 原因:激活函数(如Sigmoid)在输入值过大/过小时导数接近0,导致梯度传递到浅层时趋近于0(梯度消失);或网络参数初始值过大,导致梯度逐层放大(梯度爆炸)。

    • 解决方法:使用ReLU等梯度不易消失的激活函数、采用 Xavier/He 等参数初始化方法、使用批量归一化(Batch Normalization)。

  2. 梯度累积:PyTorch中若未调用optimizer.zero_grad(),梯度会累积到上一次的梯度值上,导致参数更新错误,需每次反向传播前清空梯度。

  3. 学习率选择:学习率过大会导致参数震荡不收敛,过小则参数更新缓慢,需根据任务调整(如初始用0.1,后续逐步减小)。

您可能感兴趣的与本文相关的镜像

PyTorch 2.8

PyTorch 2.8

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter_Monster

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值