Pytorch反向传播——optimizer.zero_grad(), loss.backward(), optimizer.step() 作用

1. optimizer.zero_grad()

在 PyTorch 中,optimizer.zero_grad() 用于清空优化器中的梯度。通常,在进行一次反向传播计算之前,我们需要先清空优化器中的梯度。这是因为 PyTorch 默认会在反向传播时累加梯度,而不是覆盖之前的梯度,因此我们需要先清空梯度,再进行反向传播计算。

具体来说,optimizer.zero_grad() 会将优化器中所有可学习参数的梯度设为 0。这样,在下一次前向传递计算和反向传播计算时,之前的梯度就不会对当前的梯度产生影响。

2. loss.backward()

loss.backward() 是 PyTorch 中用于自动求导的函数,它的主要作用是计算损失函数对模型参数的梯度,从而实现反向传播算法。

在深度学习中,我们通常使用梯度下降算法来更新模型参数,使得模型能够逐步逼近最优解。在梯度下降算法中,我们需要计算损失函数关于模型参数的梯度,以便确定参数更新的方向和大小。这个计算过程就是反向传播算法,而 loss.backward() 就是反向传播算法的实现。

具体来说,loss.backward() 的作用是对损失函数进行求导,得到每个模型参数关于损失函数的梯度。这个梯度可以表示模型参数在当前状态下对损失函数的贡献大小和方向,即参数更新的方向和大小。通过梯度下降算法,我们可以根据这个梯度调整模型参数,使得损失函数逐渐减小,模型性能逐渐提升。

需要注意的是,loss.backward() 仅计算当前批次中的梯度,并不修改模型参数。如果需要更新模型参数,还需要调用优化器的 step() 方法,根据计算得到的梯度更新模型参数。

3. optimizer.step()

在 PyTorch 中,optimizer.step() 是用于更新梯度的函数。当我们使用 backward() 计算网络参数的梯度后,我们需要使用 optimizer.step() 来根据梯度更新网络参数的值。

具体来说,optimizer.step() 根据优化算法的规则,将梯度应用于网络参数。例如,常用的优化算法如 Adam、SGD 等,都有自己的更新规则,optimizer.step() 会按照相应的规则更新网络参数的值。更新后的参数将被用于下一次的前向传递计算和反向传播计算。

示例代码:

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

# 创建一个简单的网络
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(10, 5)
        self.fc2 = nn.Linear(5, 1)
        
    def forward(self, x):
        x = self.fc1(x)
        x = nn.functional.relu(x)
        x = self.fc2(x)
        return x

# 创建输入和标签
inputs = torch.randn(3, 10)
labels = torch.tensor([[1.0], [0.0], [1.0]])

# 创建网络和优化器
net = Net()
optimizer = optim.SGD(net.parameters(), lr=0.01)


# 前向传递计算和反向传播计算
for i in range(epoch):
	model.train() # 打开 dropout 和 batch nomalization 第一步
	for inputs,labels in emunerate(trainloader):
		inputs, labels = inputs.to(device), labels.to(device)
		optimizer.zero_grad()  # 梯度清零 第二步
		outputs = net(inputs)
		loss = nn.functional.binary_cross_entropy_with_logits(outputs, labels)
		# 计算导数
		loss.backward() # 第三步

		# 更新网络参数
		optimizer.step() # 第四步


# 推理阶段
def infer(image_tensor):
    model.eval() # 关闭 dropout 和 batch nomalization
    with torch.no_grad():    # 关闭自动求导
        image_tensor = image_tensor.unsqueeze(0).to(device)  # 增加批次维度
        output = model(image_tensor)
        predicted_class = torch.argmax(output, dim=1).item()
    return predicted_class

# 输出更新后的参数值
for name, param in net.named_parameters():
    if param.requires_grad:
        print(name, param.data)

先使用 optimizer.zero_grad() 用于清空优化器中的梯度,再前向传播,计算loss,再loss.backward()计算梯度,再用optimizer.step()更新梯度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值