前言
报错这个的可能就三种,我全踩过了,记录一下造福后人
原因
训练的时候,网络有bn层,但是输入的特征的第一个维度是1,例如:[1,2048]这样的就会报错,因为bn层要计算均值方差,一张图没法统计。
出现情况
- dataloader没有drop last,可能会出现最后一个batch的数量为1
- 评估的时候没有写model.eval()
- model的结构中用列表或者字典存了bn
解决
第一种很好解决,将DataLoader中drop_last设置为True即可
第二种更好解决,直接加一行model.eval()即可
第三种:
讲讲缘由…
做多数据集融合的同学应该会看到每个数据集过对应的bn层这样的操作,我在设计model的时候考虑想动态设置model中有n个bn,于是在DSBN(自己实现的nn.Module类的一个子类)写了一个self.bn_list = [],然后:
for i in range(dataset_num):
self.BN_list.append(nn.BatchNorm1d(planes).cuda())
还以为自己很聪明,结果给自己埋了个坑…
如果有这种写法,设置全局flag model.eval()的时候我的这个self.BN_list里面的bn是不会设成eval的,因此,你会发现他在eval的时候也疯狂报错…
解决办法也很简单:
train的时候设动再对应设一下flag
eval也是…
石坑!!!