繁体   English   中英

评估 pytorch 模型:`with torch.no_grad` 与 `model.eval()`

[英]Evaluating pytorch models: `with torch.no_grad` vs `model.eval()`

当我想评估我的模型在验证集上的性能时,是首选with torch.no_grad:还是model.eval()

TL; DR:

使用两者 他们做不同的事情,并有不同的范围。

  • with torch.no_grad - 禁用跟踪autograd的渐变。
  • model.eval()更改调用它的模块的forward()行为
    • 例如,它禁用了丢失并且批量规范使用整个人口统计数据

with torch.no_grad

torch.autograd.no_grad文档说:

禁用[原文如此]梯度计算的上下文管理器。

当您确定不会调用Tensor.backward()时,禁用渐变计算对于推理非常有用。 它将减少计算的内存消耗,否则会有requires_grad=True 在此模式下,即使输入的requires_grad=True ,每次计算的结果都会包含requires_grad=False

model.eval()

nn.Module.eval文档说:

将模块设置为评估模式。

这仅对某些模块有任何影响。 有关其在培训/评估模式下的行为的详细信息,请参阅特定模块的文档,如果它们受到影响,例如DropoutBatchNorm等。


pytorch的创建者表示应该更新文档以建议两者的用法

with torch.no_grad:禁用向后传递的梯度计算。 由于这些计算在推理过程中是不必要的,并且会增加非平凡的计算开销,因此如果评估模型的速度,则必须使用此上下文。 不过不会影响结果。

model.eval()确保某些在训练与推理中表现不同的模块(例如 Dropout 和 BatchNorm)在推理的前向传递期间被适当地定义。 因此,如果您的模型包含此类模块,则必须启用此功能。

由于上述原因,在推理过程中同时使用两者是一种很好的做法。

如果您正在阅读这篇文章是因为您遇到了RuntimeError: CUDA out of memory ,那么with torch.no grad():可能有助于节省内存。 仅使用model.eval()不太可能有助于解决 OOM 错误。

这样做的原因是torch.no grad()完全禁用了 autograd(您不能再进行反向传播),从而减少内存消耗并加快计算速度。

但是,您仍然可以在使用model.eval()时调用 gardients。 就个人而言,我觉得这个设计决定很有趣。 那么, .eval()的目的是什么? 它的主要功能似乎是在评估期间停用 Dropout。

总而言之,如果您使用torch.no grad() ,则不会保存中间张量,并且您可能会在推理中增加批量大小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM