训练五步走:前向传播、计算损失、清零梯度optimizer.zero_grad()、反向传播loss.backward()、更新参数optimizer.step()

用法 

1. 前向传播outputs = model(inputs)

步骤:定义模型函数 -> 实例化模型 -> 定义输入 -> 前向传播计算输出

import torch
import torch.nn as nn

# 定义一个简单的线性模型
class SimpleModel(nn.Module):
    def __init__(self):
        super(SimpleModel, self).__init__()
        self.linear = nn.Linear(10, 1)

    def forward(self, x):
        return self.linear(x)

# 创建模型实例
model = SimpleModel()

# 生成一些随机输入
inputs = torch.randn(32, 10)  # 32个样本,每个样本有10个特征

# 前向传播计算输出
outputs = model(inputs)

2. 计算损失loss = criterion(outputs, targets)

步骤:定义损失函数 -> 定义目标/标签 -> 计算损失

# 定义损失函数
criterion = nn.MSELoss()

# 生成一些目标数据
targets = torch.randn(32, 1)  # 32个样本,每个样本有1个目标值

# 计算损失
loss = criterion(outputs, targets)

3. 清零梯度optimizer.zero_grad()

在每个训练步骤中,需要进行以下几个步骤:

  1. 前向传播:计算损失函数,这一步将产生模型的预测值。
  2. 反向传播:计算损失函数相对于模型参数的梯度
  3. 参数更新:使用优化器更新模型参数。

每次调用 loss.backward() 时,计算得到的梯度会被累积到已经存在的梯度上。如果不在每个训练步骤开始时清除这些梯度,会导致梯度的累积,从而影响模型参数的更新。

optimizer.zero_grad() 就是在每个训练步骤开始时清除之前的梯度,确保每次更新时梯度只来自当前的反向传播。在每个训练步骤开始时调用,确保反向传播计算的梯度只来自当前批次的数据,避免梯度累积影响模型训练。

4. 反向传播loss.backward()

反向传播是计算神经网络梯度的一种方法。通过反向传播,神经网络可以基于损失函数的梯度来更新参数,使得模型的预测结果更加准确。

在PyTorch中,每次进行张量操作时,都会动态构建一个计算图,这个计算图跟踪所有操作以及它们之间的依赖关系。调用loss.backward()时,PyTorch会遍历这个计算图,从输出(损失)到输入(模型参数),计算每个参数的梯度,并将这些梯度存储在每个参数的.grad属性中。

5. 更新参数optimizer.step()

在调用loss.backward()之后,模型参数的.grad属性中已经存储了损失函数相对于这些参数的梯度。optimizer.step()则使用这些梯度来更新模型参数,这一步是通过优化器的算法(如随机梯度下降SGD、Adam、RMSprop等)来完成的,不同优化器在step()中使用不同的算法来更新参数。


例子

例1:定义一个训练函数

def train(epoch):

    RMSE = 0
    cost_all = 0

    for step, (batch_x, batch_mask_x, batch_y) in enumerate(loader):

        batch_x = batch_x.type(torch.FloatTensor).cuda()
        batch_mask_x = batch_mask_x.type(torch.FloatTensor).cuda()
        
        # rec为实例化的模型
        decoder = rec(batch_x)   # 前向传播,计算预测值,会自动执行模型定义函数里的forward
        loss, rmse = rec.loss(decoder=decoder, input=batch_x, optimizer=optimer, mask_input=batch_mask_x)   # 计算损失
        optimer.zero_grad()   # 清零梯度
        loss.backward()    # 反向传播计算梯度
        optimer.step()    # 更新参数
        cost_all += loss
        RMSE += rmse

    # detach()
    RMSE = np.sqrt(RMSE.detach().cpu().numpy() / (train_mask_r == 1).sum())
    print('epoch:', epoch, 'train RMSE:', RMSE)

可以看出训练五步走:前向传播 -> 计算损失 -> 清零梯度 -> 反向传播计算梯度 -> 更新参数 

例2:训练多个Epoch 

num_epochs = 10

for epoch in range(num_epochs):
    for inputs, targets in dataloader:
        # 前向传播
        outputs = model(inputs)
        # 计算损失
        loss = criterion(outputs, targets)
        # 清零梯度
        optimizer.zero_grad()
        # 反向传播计算梯度
        loss.backward()
        # 更新参数
        optimizer.step()

    print(f"Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}")
  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 这是一个关于深度学习模型训练的问题,我可以回答。model.forward()是模型的前向传播过程,将输入数据通过模型的各层进行计算,得到输出结果。loss_function是损失函数,用于计算模型输出结果与真实标签之间的差异。optimizer.zero_grad()用于清空模型参数梯度信息,以便进行下一次反向传播loss.backward()是反向传播过程,用于计算模型参数梯度信息。t.nn.utils.clip_grad_norm_()是用于对模型参数梯度进行裁剪,以防止梯度爆炸的问题。 ### 回答2: model.forward: 模型中的forward函数用于将输入数据传递给模型,进行前向计算并生成输出。在这个函数中,模型根据输入数据的特征进行一系列的计算,将输入映射到输出空间中。 loss_function: 损失函数用于衡量模型输出与实际标签之间的差异。通常,我们希望模型输出的预测值与实际标签尽可能接近,损失函数的作用就是计算这种差异的度量。常用的损失函数包括均方损失函数(MSE)、交叉熵损失函数等。 optimizer.zero_grad(): 在模型进行反向传播之前,我们需要将梯度清零。这是因为PyTorch在进行反向传播计算梯度时,会自动累加之前的梯度值。为了避免梯度值的累加影响到当前的反向传播,我们需要在每次反向传播之前将梯度清零loss.backward(): 反向传播是模型训练的关键步骤之一。在前向计算之后,调用loss.backward()函数可以根据损失函数求取对模型参数梯度。该函数会自动计算模型各个参数梯度信息,并将其存在参数对象的.grad属性中。 t.nn.utils.clip_grad_norm_: 该函数常用于梯度裁剪,用于解决训练过程中梯度爆炸的问题。梯度爆炸会导致优化算法不收敛的问题,通过调用该函数可以裁剪梯度值的范数,使其不超过指定阈值。这样可以避免梯度值过大,保证模型的稳定训练。 总结起来,通过model.forward函数将输入传递给模型进行前向计算,并根据损失函数计算模型输出与实际标签之间的差异。之后,使用optimizer.zero_grad()将梯度清零,调用loss.backward()进行反向传播计算参数梯度。最后,使用t.nn.utils.clip_grad_norm_进行梯度裁剪,防止梯度爆炸问题的发生。 ### 回答3: model.forward()是一个神经网络模型的前向传播函数,用于计算输入数据的预测值。 loss_function是一个损失函数,用来衡量模型的预测值和真实值之间的差异。 optimizer.zero_grad()是一个优化器对象的方法,用于将模型中的所有梯度归零,以便进行下一次的梯度更新计算loss.backward()是损失函数的反向传播过程,用来计算模型中各个参数梯度。 t.nn.utils.clip_grad_norm_是一个梯度裁剪函数,用于控制梯度的大小,避免出现梯度爆炸的情况。该函数会将模型的梯度按照指定的最大值进行缩放。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Cheeryang_ego

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

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

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

打赏作者

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

抵扣说明:

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

余额充值