当前位置: 首页 > article >正文

梯度下降与权重更新解析

文章目录

      • 1. 梯度下降的基本概念
      • 2. 权重更新的具体过程
        • 示例数据
        • 前向传播
        • 损失计算
        • 反向传播
        • 参数更新
      • 3. 使用 PyTorch 实现梯度下降
        • 手动更新参数
        • 使用优化器简化更新过程
      • 4. `requires_grad` 的重要性
      • 5. 总结
      • 参考内容

在机器学习和深度学习中,梯度下降是一种广泛使用的优化算法,用于最小化损失函数并优化模型参数。通过调整神经网络中的权重和偏置,梯度下降帮助模型逐渐逼近最优解。本文将详细介绍梯度下降的基本原理、权重更新的过程,并结合PyTorch代码展示其实际应用。


1. 梯度下降的基本概念

梯度下降的核心思想是通过计算损失函数关于模型参数的梯度,逐步调整这些参数以减小损失。具体来说,梯度下降法按照以下步骤进行:

  1. 初始化参数:为每个需要优化的参数(如权重 W W W 和偏置 b b b)设置初始值。
  2. 前向传播:使用当前参数计算预测输出,并根据真实标签计算损失。
  3. 反向传播:利用链式法则计算损失关于每个参数的梯度。
  4. 参数更新:根据计算出的梯度调整参数,通常采用简单的梯度下降公式:
    θ : = θ − η ∇ θ L \theta := \theta - \eta \nabla_\theta L θ:=θηθL
    其中 θ \theta θ 是参数, η \eta η 是学习率, ∇ θ L \nabla_\theta L θL 是损失函数关于参数的梯度。

2. 权重更新的具体过程

为了更直观地理解权重更新的过程,我们可以通过一个具体的数值例子来说明。假设我们有一个简单的单层神经网络,该层包含一个神经元,并使用Sigmoid激活函数 σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1 和均方误差损失函数(MSE)。

示例数据
  • 输入特征 x = 2 x = 2 x=2
  • 初始权重 W = 0.5 W = 0.5 W=0.5
  • 初始偏置 b = 0.3 b = 0.3 b=0.3
  • 真实标签 y = 1 y = 1 y=1
前向传播

首先进行前向传播,计算加权输入 z z z 和激活输出 a a a

z = W x + b = 0.5 × 2 + 0.3 = 1.3 z = Wx + b = 0.5 \times 2 + 0.3 = 1.3 z=Wx+b=0.5×2+0.3=1.3
a = σ ( z ) = 1 1 + e − 1.3 ≈ 0.7858 a = \sigma(z) = \frac{1}{1 + e^{-1.3}} \approx 0.7858 a=σ(z)=1+e1.310.7858

损失计算

使用均方误差损失函数 L L L 来衡量预测值 a a a 与真实标签 y y y 之间的差异:

L = ( a − y ) 2 = ( 0.7858 − 1 ) 2 ≈ 0.0459 L = (a - y)^2 = (0.7858 - 1)^2 \approx 0.0459 L=(ay)2=(0.78581)20.0459

反向传播

接下来,我们需要计算参数的梯度。对于均方误差损失函数,梯度计算如下:

∂ L ∂ a = 2 × ( a − y ) = 2 × ( 0.7858 − 1 ) = − 0.4284 \frac{\partial L}{\partial a} = 2 \times (a - y) = 2 \times (0.7858 - 1) = -0.4284 aL=2×(ay)=2×(0.78581)=0.4284
∂ a ∂ z = σ ( z ) ( 1 − σ ( z ) ) = 0.7858 × ( 1 − 0.7858 ) ≈ 0.1683 \frac{\partial a}{\partial z} = \sigma(z)(1 - \sigma(z)) = 0.7858 \times (1 - 0.7858) \approx 0.1683 za=σ(z)(1σ(z))=0.7858×(10.7858)0.1683
∂ L ∂ z = ∂ L ∂ a × ∂ a ∂ z ≈ − 0.4284 × 0.1683 ≈ − 0.07209 \frac{\partial L}{\partial z} = \frac{\partial L}{\partial a} \times \frac{\partial a}{\partial z} \approx -0.4284 \times 0.1683 \approx -0.07209 zL=aL×za0.4284×0.16830.07209
∂ L ∂ W = ∂ L ∂ z × ∂ z ∂ W = − 0.07209 × 2 = − 0.14418 \frac{\partial L}{\partial W} = \frac{\partial L}{\partial z} \times \frac{\partial z}{\partial W} = -0.07209 \times 2 = -0.14418 WL=zL×Wz=0.07209×2=0.14418
∂ L ∂ b = ∂ L ∂ z × ∂ z ∂ b = − 0.07209 × 1 = − 0.07209 \frac{\partial L}{\partial b} = \frac{\partial L}{\partial z} \times \frac{\partial z}{\partial b} = -0.07209 \times 1 = -0.07209 bL=zL×bz=0.07209×1=0.07209

参数更新

假设学习率 η = 0.1 \eta = 0.1 η=0.1,我们可以根据计算出的梯度来更新参数:

W : = W − η ⋅ ∂ L ∂ W = 0.5 − 0.1 × ( − 0.14418 ) = 0.5 + 0.014418 ≈ 0.514418 W := W - \eta \cdot \frac{\partial L}{\partial W} = 0.5 - 0.1 \times (-0.14418) = 0.5 + 0.014418 \approx 0.514418 W:=WηWL=0.50.1×(0.14418)=0.5+0.0144180.514418
b : = b − η ⋅ ∂ L ∂ b = 0.3 − 0.1 × ( − 0.07209 ) = 0.3 + 0.007209 ≈ 0.307209 b := b - \eta \cdot \frac{\partial L}{\partial b} = 0.3 - 0.1 \times (-0.07209) = 0.3 + 0.007209 \approx 0.307209 b:=bηbL=0.30.1×(0.07209)=0.3+0.0072090.307209

通过不断重复上述过程,模型的参数会逐渐优化,从而使损失函数趋于最小。

3. 使用 PyTorch 实现梯度下降

为了更好地理解梯度下降和权重更新的实际操作,我们可以使用PyTorch进行实现。以下是完整的代码示例,展示了手动更新参数和使用优化器简化更新过程两种方式。

手动更新参数
import torch
import torch.nn.functional as F

# 设置随机种子以保证结果可复现
torch.manual_seed(1)

# 定义输入、权重、偏置和真实标签
x = torch.tensor([2.0], requires_grad=False)  # 输入特征
W = torch.tensor([0.5], requires_grad=True)   # 权重
b = torch.tensor([0.3], requires_grad=True)   # 偏置
y_true = torch.tensor([1.0], requires_grad=False)  # 真实标签

# 前向传播:计算预测值
z = W * x + b  # 加权输入
a = torch.sigmoid(z)  # 激活输出

# 计算损失(均方误差)
loss = F.mse_loss(a, y_true)

print(f"前向传播: z = {z.item():.4f}, a = {a.item():.4f}, loss = {loss.item():.4f}")

# 反向传播:计算梯度
loss.backward()

# 查看梯度
print(f"反向传播后,W的梯度: {W.grad.item():.4f}")
print(f"反向传播后,b的梯度: {b.grad.item():.4f}")

# 更新参数(简单梯度下降法)
learning_rate = 0.1
with torch.no_grad():
    W -= learning_rate * W.grad
    b -= learning_rate * b.grad

# 清除梯度,以便下一次迭代可以重新计算
W.grad.zero_()
b.grad.zero_()

print(f"更新后的权重 W: {W.item():.5f}, 更新后的偏置 b: {b.item():.5f}")

输出示例:

前向传播: z = 1.3000, a = 0.7858, loss = 0.0459
反向传播后,W的梯度: -0.1442
反向传播后,b的梯度: -0.0721
更新后的权重 W: 0.51442, 更新后的偏置 b: 0.30721
使用优化器简化更新过程
import torch
import torch.nn.functional as F
from torch import optim

# 设置随机种子以保证结果可复现
torch.manual_seed(1)

# 定义输入、权重、偏置和真实标签
x = torch.tensor([2.0], requires_grad=False)  # 输入特征
W = torch.tensor([0.5], requires_grad=True)   # 权重
b = torch.tensor([0.3], requires_grad=True)   # 偏置
y_true = torch.tensor([1.0], requires_grad=False)  # 真实标签

# 将参数放入列表中,传递给优化器
params = [W, b]
optimizer = optim.SGD(params, lr=0.1)

# 前向传播:计算预测值
z = W * x + b  # 加权输入
a = torch.sigmoid(z)  # 激活输出

# 计算损失(均方误差)
loss = F.mse_loss(a, y_true)

print(f"前向传播: z = {z.item():.4f}, a = {a.item():.4f}, loss = {loss.item():.4f}")

# 反向传播:计算梯度
loss.backward()

# 查看梯度
print(f"反向传播后,W的梯度: {W.grad.item():.4f}")
print(f"反向传播后,b的梯度: {b.grad.item():.4f}")

# 更新参数(使用优化器)
optimizer.step()

# 清除梯度
optimizer.zero_grad()

print(f"更新后的权重 W: {W.item():.5f}, 更新后的偏置 b: {b.item():.5f}")

输出示例:

前向传播: z = 1.3000, a = 0.7858, loss = 0.0459
反向传播后,W的梯度: -0.1442
反向传播后,b的梯度: -0.0721
更新后的权重 W: 0.51442, 更新后的偏置 b: 0.30721

4. requires_grad 的重要性

在PyTorch中,requires_grad是一个非常重要的属性,它决定了是否为某个Tensor计算和跟踪梯度。理解何时设置requires_grad=TrueFalse对于正确构建和训练神经网络至关重要。

  • 可学习参数:如果一个Tensor是模型的参数(如权重或偏置),并且你希望在训练过程中通过反向传播更新这些参数,则必须将其requires_grad设置为True

    W = torch.tensor([0.5], requires_grad=True)  # 可学习参数
    
  • 输入数据和标签:输入数据和标签通常是固定的,不参与梯度计算,因此它们的requires_grad应该设置为False。实际上,默认情况下,用torch.tensor()创建的Tensor的requires_gradFalse,所以你通常不需要显式设置。

    x = torch.tensor([2.0])  # 默认 requires_grad=False
    y_true = torch.tensor([1.0])  # 默认 requires_grad=False
    
  • 自定义层或操作:如果你创建了自定义的层或操作,并且涉及到需要优化的参数,那么你需要确保这些参数的requires_grad被正确设置。

  • 冻结部分网络:在微调预训练模型时,有时你可能只想更新某些层的参数,而保持其他层不变。这时你可以选择性地将某些层的参数的requires_grad设置为False,以冻结它们。

    for param in model.parameters():
        param.requires_grad = False  # 冻结所有参数
    

5. 总结

梯度下降是机器学习和深度学习中不可或缺的优化算法,通过不断调整模型参数以最小化损失函数,使得模型能够更好地拟合数据。


参考内容

梯度下降法视频讲解
误差反向传播
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


http://www.kler.cn/a/508705.html

相关文章:

  • 什么是长连接?Netty如何设置进行长连接?
  • Git在码云上的使用指南:从安装到推送远程仓库
  • 进阶——十六届蓝桥杯嵌入式熟练度练习(按键+LCD)
  • Kotlin语言的数据库交互
  • 镭速大文件传输视频文件预览实现原理
  • flutter在使用gradle时的加速
  • 有限元分析学习——Anasys Workbanch第一阶段笔记(12)静力学分析基本参数及重力对计算结果的影响
  • 基于Android 位置定位的考勤 APP 设计与实现
  • 虚幻基础2:gameplay框架
  • 鸿蒙中选择地区
  • 归子莫的科技周刊#1:一周是一年的2%
  • 4.Spring AI Prompt:与大模型进行有效沟通
  • 利用Ai,帮我完善了UsbCamera App的几个界面和设置功能
  • 【蓝桥杯选拔赛真题63】C++奇数 第十四届蓝桥杯青少年创意编程大赛 算法思维 C++编程选拔赛真题解
  • 位运算练习
  • 光谱相机如何还原色彩
  • Axios封装一款前端项目网络请求实用插件
  • 2024年博客之星年度评选—创作影响力评审入围名单公布
  • WINFORM - DevExpress -> alertControl1提示信息框
  • T-SQL语言的计算机基础
  • git 常用命令 git revert
  • 音频可视化小工具
  • 网络安全 | 什么是正向代理和反向代理?
  • Ubuntu20.4和docker终端指令、安装Go环境、安装搜狗输入法、安装WPS2019:保姆级图文详解
  • 开源AI智能名片2+1链动模式S2B2C商城小程序在ABM漏斗中的应用探索
  • Open3D计算点云粗糙度(方法一)【2025最新版】