如何解决在PyTorch Lightning中使用ddp后端时,对整个验证集进行验证
我正在使用PyTorch Lightning训练图像分类模型,并在具有多个GPU的机器上运行,因此我使用推荐的分布式后端来获得最佳性能ddp
(DatadistributedParallel)。这自然会拆分数据集,因此每个GPU只会看到一部分数据。
但是,对于验证,我想在整个验证集中而不是仅在一部分上计算诸如准确性之类的指标。我该怎么办?我找到了some hints in the official documentation,但它们没有按预期运行,或者使我感到困惑。发生的情况是validation_epoch_end
被num_gpus
调用,每次1/num_gpus
个验证数据。我想汇总所有结果,并且只运行一次validation_epoch_end
。
他们在this section中指出,使用dp / ddp2时,您可以添加一个名为如下的附加功能
def validation_step(self,batch,batch_idx):
loss,x,y,y_hat = self.step(batch)
return {"val_loss": loss,'y': y,'y_hat': y_hat}
def validation_step_end(self,self,*args,**kwargs):
# do something here,I'm not sure what,# as it gets called in ddp directly after validation_step with the exact same values
return args[0]
但是,结果未汇总,validation_epoch_end
仍被调用num_gpu
次。 ddp
无法使用这种行为吗?还有其他方法可以实现这种聚合行为吗?
解决方法
training_epoch_end()
和 validation_epoch_end()
汇总来自特定过程的所有训练/验证批次的数据。他们只是为您在每个训练或验证步骤中返回的内容创建一个列表。
使用 DDP 后端时,每个 GPU 都会运行一个单独的进程。没有简单的方法来访问另一个进程正在处理的数据,但是有一种机制可以在进程之间同步特定的张量。最简单的方法是分块计算度量,然后例如通过取平均值来同步张量。当您使用 self.log()
时,sync_dist=True
调用将 automatically synchronize the value between GPUs。值的同步方式由 reduce_fx
参数决定,默认情况下为 torch.mean
。
如果您也对按批次平均指标感到满意,则无需覆盖 training_epoch_end()
或 validation_epoch_end()
— self.log()
将为您进行平均。
还可以在每一步更新一些状态变量,然后定义一个自定义指标,该指标将在每个时期后根据您保存的值进行计算。推荐的方法是创建一个派生自 Metric 类(现已移至 TorchMetrics 项目)的类。使用 add_state()
在构造函数中添加状态变量并覆盖 update()
和 compute()
方法。 API 将负责同步进程之间的状态变量。
TorchMetrics 中已经有一个准确度指标,source code 是如何使用 API 的一个很好的例子。
,我认为您正在寻找training_step_end
/ validation_step_end
。
...因此,当Lightning调用training_step,validation_step,test_step中的任何一个时,您将只对其中之一进行操作。 (...)对于大多数指标而言,这并不重要。但是,如果您想使用所有批处理零件在计算图中添加一些内容(例如softmax),则可以使用training_step_end步骤。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。