Input type(torch.suda.FloatTensor) and weight type (torch.FloatTensor) should be same
自己搭建模型的时候,经常会遇到二者不匹配,以这种情况为例,是因为部分模型没有加载到CUDA上面造成的。
注意搭建模型的时候,所有层都应该在init函数中完成初始化
其次,对于List、Tuple这种类型,不建议直接用。
以下是错误代码,我搞了半天,不理解为什么总是不对,正确的应该是self.aspp = nn.ModuleList()
self.aspp = [] # 注意这里不能直接用list[]。类似元组,tuple[]也不能用,要不然会导致weight不在cuda上
for dilation in dilations:self.aspp.append(ConvModule(self.in_channels,self.channels,1 if dilation == 1 else 3,dilation=dilation,padding=0 if dilation == 1 else dilation,conv_cfg=self.conv_cfg,norm_cfg=self.norm_cfg,act_cfg=self.act_cfg))
搭建代码时,希望记住。没有系统教学,只能自己在网上摸索。
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 passing the keyword argument find_unused_parameters=True
to torch.nn.parallel.DistributedDataParallel
, and by making sure all forward
function outputs participate in calculating loss.
多GPU的坑,翻译为
- 在开始新的迭代之前,应已在上一次迭代中完成缩减。此错误表示您的模块具有未用于产生损失的参数。通过将关键字参数
find_unused_parameters=True
传递给torch.nn.parallel,可以启用未使用的参数检测。DistributedDataParallel
,和
确保所有“正向”函数输出都参与计算损失。
关键在于
This error indicates that your module has parameters that were not used in producing loss.
即有参数未参与到loss生成过程中,换句话说就是有参数在init中定义,但是未在forward中使用,就会造成这样的结果。原来为了不断调优模型,我将几个待选网络模块都写在了init函数中,然后这样只需要在forward中改变调用的模块就可以了。在单机运行中这样是可行的无错的,但是在DDP中由于需要多卡进行loss的reduce,为了防止出错,ddp就强行设置了这样的规则,但是可以通过如上错误提示里面的参数更改此设置,但是尽量不要修改。
解决方法:
可以通过 (1) 将关键字参数 find_unused_parameters=True 传递给 torch.nn.parallel.DistributedDataParallel 来启用未使用的参数检测;
(2) 确保所有 forward 函数的所有输出都参与计算损失。解决方法:将init函数中未使用到的模块注释掉即可。
一般推荐2,
因为我只修改了骨干网络,骨干网络是我自己创建的,仔细检查发现,复制粘贴的时候,有个地方忘记修改
x = self.aspp2(x[3]) # 此处是aspp2,之前是aspp3
修改之后,就可以跑通了
拓展:
也有推荐用如下代码检查,我试了一下,但是将所有的都输出来了,不知道是不是放的位置不对:
在mmseg/models/segmentors/encoder_decoder.py中的losses.update(loss_decode)语句下加入下段代码
for name, p in self.decode_head.named_parameters():# print(name)if p.grad is None:print(name)