torch关于训练:零梯度zero_grad()、分离detach、更新step

发布于:2024-12-06 ⋅ 阅读:(162) ⋅ 点赞:(0)

零梯度

在PyTorch中,opt.zero_grad()是一个用于优化器(optimizer)的方法,它的作用是将模型中所有参数的梯度清零。

在训练神经网络的过程中,每次前向传播之后,网络参数会产生梯度,这些梯度在反向传播过程中会被用来更新网络的参数。然而,如果不将之前的梯度清零,那么在下次迭代时,这些旧的梯度会与新的梯度累加,这会导致参数更新不正确。

因此,在每次反向传播和参数更新之前,都需要调用opt.zero_grad()来确保所有的参数梯度都是从头开始计算,这样可以保证训练过程的正确性。

以下是一个使用优化器的简单示例:

零梯度是作用在优化器opt上的方法

# 假设model是一个神经网络模型,loss_function是一个损失函数,opt是一个优化器
for data, target in dataset:
    # 前向传播
    output = model(data)
    loss = loss_function(output, target)

    # 反向传播之前清零梯度
    opt.zero_grad()

    # 反向传播
    loss.backward()

    # 更新参数
    opt.step()

在这个例子中,opt.zero_grad()在每次迭代开始时被调用,确保了每次计算梯度时都是从干净的起点开始。

detach

在PyTorch中,loss.detach().numpy()是两个不同的操作,它们通常结合使用来获取损失值的NumPy表示。

在深度学习和编程的上下文中,“detach” 这个英文单词的中文翻译通常是“分离”。具体到PyTorch这样的深度学习框架中,detach 通常用来从一个计算图中分离出一个张量(tensor),这样这个张量就不会再参与到后续的计算图中,也就是说它的梯度不会被计算和更新。

例如,在PyTorch中,如果你有一个需要梯度回传的张量tensor,但是你想使用它的值进行一些计算而不希望这些计算参与到梯度计算中,你可以使用tensor.detach()来得到一个与原张量值相同但不需要梯度的新张量。这个新张量与原计算图分离了。

  1. loss.detach():

    • detach()是一个在PyTorch张量上的方法,它的作用是从计算图中分离出一个张量,从而停止跟踪它之上的历史记录。这意味着对loss.detach()返回的张量所做的任何操作都不会影响到原始计算图中的参数梯度。
    • 当你想要执行一些计算,但是又不希望这些计算影响梯度下降过程时,detach()非常有用。
  2. .numpy():

    • .numpy()是PyTorch张量的一个方法,它将PyTorch张量转换为NumPy数组。NumPy是一个广泛使用的Python库,专门用于进行数值计算。
    • 使用.numpy()方法通常是为了利用NumPy提供的丰富函数库,或者是为了将PyTorch张量输出到不支持PyTorch的环境中。

将这两个操作结合起来,loss.detach().numpy(),通常用于以下场景:

  • 在训练过程中,你想要记录下每个批次或每个epoch的损失值,但是又不希望这些记录操作影响到梯度计算。
  • 你可能想要使用NumPy库对损失值进行进一步的分析或可视化。

下面是一个简单的例子:

 

import torch
import numpy as np

# 假设有一个模型输出和目标
output = torch.randn(3, 5, requires_grad=True)
target = torch.randint(0, 5, (3,))

# 计算损失
loss = torch.nn.functional.cross_entropy(output, target)

# 获取损失值的NumPy表示,同时停止梯度跟踪
loss_value = loss.detach().numpy()

# 现在 loss_value 是一个NumPy数组,可以用于打印、保存或进一步分析
print(loss_value)

# 获取损失值的NumPy表示,同时停止梯度跟踪
loss_value = loss.detach().numpy()

# 现在 loss_value 是一个NumPy数组,可以用于打印、保存或进一步分析
print(loss_value)
实例

在这个例子中,loss_value将是一个NumPy数组,包含了当前的损失值,而且这个操作不会影响output参数的梯度。

opt.step()

在PyTorch中,opt.step()是优化器(optimizer)的一个方法,它在神经网络训练过程中用于更新模型的参数。

这里是一个简化的训练循环,可以帮助理解opt.step()的作用:

 

for data, target in dataset:
    # 前向传播
    output = model(data)
    loss = loss_function(output, target)

    # 反向传播之前清零梯度
    optimizer.zero_grad()

    # 反向传播
    loss.backward()

    # 更新参数
    optimizer.step()

在这个循环中,optimizer.step()的作用如下:

  1. 根据梯度更新参数:在调用loss.backward()之后,所有具有requires_grad=True的模型参数都会累积梯度。optimizer.step()会根据这些累积的梯度以及优化器的策略(比如SGD, Adam等)来更新模型的参数。。不一定直接梯度下降,会按照优化器种类自适应

  2. 执行参数更新:在优化器的内部,step()方法会遍历模型的所有参数,并使用适当的更新规则来调整这些参数的值,以最小化损失函数。

  3. 准备下一次迭代:在step()方法执行后,梯度不会被自动清零。因此,在下一个训练步骤开始之前,通常需要再次调用optimizer.zero_grad()来清零梯度,确保不会影响下一次迭代的梯度计算。

总结来说,opt.step()是训练过程中一个关键步骤,它确保了模型根据计算出的梯度不断进化,从而在训练数据上学习到更好的参数值。


网站公告

今日签到

点亮在社区的每一天
去签到