当尝试训练CNN模型时,我遇到了如下所示的代码:
def train(n_epochs, loaders, model, optimizer, criterion):
for epoch in range(1,n_epochs):
train_loss = 0
valid_loss = 0
model.train()
for i, (data,target) in enumerate(loaders['train']):
# zero the parameter (weight) gradients
optimizer.zero_grad()
# forward pass to get outputs
output = model(data)
# calculate the loss
loss = criterion(output, target)
# backward pass to calculate the parameter gradients
loss.backward()
# update the parameters
optimizer.step()
有人可以告诉我为什么使用第二个for循环吗?
即for i, (data,target) in enumerate(loaders['train']):
为什么使用optimizer.zero_grad()
和optimizer.step()
?
答案 0 :(得分:1)
首先使用Optimizer加载这样的参数(代码中缺少):
optimizer = optim.Adam(model.parameters(), lr=0.001, momentum=0.9)
此代码
loss = criterion(output, target)
用于计算单个批次的损失,其中目标是您从元组(data,target)
获得的数据,数据用作模型的输入,而我们获得了output
。
此步骤:
optimizer.zero_grad()
将优化器中找到的所有梯度归零,这对于初始化非常重要。
零件
loss.backward()
计算梯度,optimizer.step()
更新我们的模型权重和偏差(参数)。
在PyTorch中,您通常使用DataLoader
类来加载训练和验证集。
loaders['train']
可能是完整的火车,代表一个时期。
答案 1 :(得分:1)
torch.utils.data.DataLoader
在您需要准备数据批处理(可能在每次运行之前将它们洗牌)时派上用场。
data_train_loader = DataLoader(data_train, batch_size=64, shuffle=True)
在上面的代码中,第一个for-loop
遍历历元数,而第二个循环遍历通过上述代码转换为批次的训练数据集。例如:
for batch_idx, samples in enumerate(data_train_loader):
# samples will be a 64 x D dimensional tensor
# batch_idx is each batch index
从here了解有关torch.utils.data.DataLoader
的更多信息。
Optimizer.zero_gradient()
:在向后传递之前,请使用优化程序对象将要更新的张量的所有梯度都归零(这是模型的可学习权重)
optimizer.step()
:我们通常使用optimizer.step()
进行梯度下降步骤。在优化器上调用step函数可对其参数进行更新。
从here了解有关这些内容的更多信息。