我是pytorch的新手。请问添加"loss.item()"有什么区别?以下 2 部分代码:
for epoch in range(epochs):
trainingloss =0
for i in range(0,X.size()[1], batch_size):
indices = permutation[i:i+batch_size]
F = model.forward(X[n])
optimizer.zero_grad()
criterion = loss(X,n)
criterion.backward()
optimizer.step()
trainingloss += criterion.item()
而这个
for epoch in range(epochs):
for i in range(0,X.size()[1], batch_size):
indices = permutation[i:i+batch_size]
F = model.forward(X[n])
optimizer.zero_grad()
criterion = loss(X,n)
criterion.backward()
optimizer.step()
如果有人有任何想法,请帮忙。谢谢。
调用loss.item()
允许你获取一个从 PyTorch 创建的计算图中分离的loss
变量(这就是.item()
对 PyTorch 变量所做的)。
如果在每个"批处理循环"的末尾添加行trainingloss += criterion.item()
,这将通过增量添加训练集中每个小批处理的损失来跟踪整个迭代中的批处理损失。 这是必要的,因为您使用的是小批量 - 每个小批次的损失将不等于所有批次的损失。
注意:如果你在优化循环之外使用 PyTorch 变量,例如在不同的范围内,如果你调用类似return loss
的东西,这可能会发生,那么对作为计算图一部分的任何 PyTorch 变量调用.item()
是至关重要的(作为一般经验法则,任何与 PyTorch 方法交互的输出/损失/模型都可能是计算图的一部分)。否则,这可能会导致计算图无法从 Python 内存中取消分配/删除,并可能导致 CPU/GPU 内存泄漏。 不过,您上面的内容看起来是正确的!
此外,在未来,PyTorch 的DataLoader
类可以帮助您处理具有较少样板代码的小批量 - 它可以遍历您的数据集,以便您循环的每个项目都是一个训练批处理 - 即您在优化中不需要两个 for 循环。
我希望你喜欢学习/使用PyTorch!
在训练循环中,criterion.backward()
部分计算前馈路径的每个可训练参数的梯度,然后optimizer.step()
部分根据计算的梯度和优化技术更新参数。因此,在此步骤结束时,特定批次的模型训练已经完成,trainingloss += criterion.item()
部分仅用于跟踪和监视训练过程以及每个训练步骤的损失值。