RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.

RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.

报错信息

报错信息:

RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates that your module has parameters that were not used in producing loss. You can enable unused parameter detection by (1) passing the keyword argument find_unused_parameters=True to torch.nn.parallel.DistributedDataParallel; (2) making sure all forward function outputs participate in calculating loss. If you already have done the above two steps, then the distributed data parallel module wasn’t able to locate the output tensors in the return value of your module’s forward function. Please include the loss function and the structure of the return value of forward of your module when reporting this issue (e.g. list, dict, iterable).

遇到这个报错的原因可能有很多,设置torch.nn.parallel.DistributedDataParallel的参数find_unused_parameters=True之类的方法就不提了,报错信息中给的很清楚,看不懂的话google翻译一下即可。

运行时错误:预计在开始新迭代之前已完成前一次迭代的减少。此错误表明您的模块具有未用于产生损耗的参数。您可以通过 (1) 将关键字参数 find_unused_parameters=True 传递给 torch.nn.parallel.DistributedDataParallel 来启用未使用的参数检测; (2) 确保所有 forward 函数输出都参与计算损失。如果您已经完成了上述两个步骤,那么分布式数据并行模块无法在模块的 forward 函数的返回值中定位输出张量。报告此问题时,请包括损失函数和模块 forward 返回值的结构(例如 list、dict、iterable)。

如果改个参数能够就能够解决你的问题的话,你也不会找到这篇博客了^^。

解决方法(之一)

这里其实报错的最后一句值得注意:

如果您已经完成了上述两个步骤,那么分布式数据并行模块无法在模块的 forward 函数的返回值中定位输出张量。报告此问题时,请包括损失函数和模块 forward 返回值的结构(例如 list、dict、iterable)。

但是第一次遇到这个问题只看官方的提示信息可能还是云里雾里,这里笔者将自己的理解和解决过程分享出来。

说的简单点,其实就一句话:确保你的所有的forward的函数的所有输出都被用于计算损失函数了

注意,不仅仅是你的模型的forward函数的输出,可能你的损失函数也是通过forward函数来计算的。也就是说,所有继承自nn.Module的模块(不只是模型本身)的forward函数的所有输出都要参与损失函数的计算

笔者本身遇到的问题就是,在多任务学习中,损失函数是通过一个整个继承自nn.Module的模块来计算的,但是在forward返回的loss中少加了一个任务的loss,导致这个报错。


class multi_task_loss(nn.Module):
    def __init__(self, device, batch_size):
        super().__init__()
        self.ce_loss_func = nn.CrossEntropyLoss()
        self.l1_loss_func = nn.L1Loss()
        self.contra_loss_func = ContrastiveLoss(batch_size, device)
    
    def forward(self, rot_p, rot_t, 
                pert_p, pert_t, 
                emb_o, emb_h, emb_p,
                original_imgs, rect_imgs):
        rot_loss = self.ce_loss_func(rot_p, rot_t)
        pert_loss = self.ce_loss_func(pert_p, pert_t)
        contra_loss = self.contra_loss_func(emb_o, emb_h) \
                        + self.contra_loss_func(emb_o, emb_p) \
                        + self.contra_loss_func(emb_p, emb_h)
        rect_loss = self.l1_loss_func(original_imgs, rect_imgs)


        # tol_loss = rot_loss + pert_loss + rect_loss 				# 少加了一个loss,但是所有loss都返回了
		tol_loss = rot_loss + pert_loss + contra_loss + rect_loss 		# 修改为此行后正常

        return tol_loss, (rot_loss, pert_loss, contra_loss, rect_loss)

读者可以检查一下自己整个的计算过程中(不只是模型本身),是否所有的forward的函数的所有输出都被用于计算损失函数了。

Ref:

https://discuss.pytorch.org/t/need-help-runtimeerror-expected-to-have-finished-reduction-in-the-prior-iteration-before-starting-a-new-one/119247

评论 1 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

Adenialzz

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值