Pytorch 训练过程中出现的问题

each element in list of batch should be of equal size

  File "/home/vase/software/miniconda3/envs/d2l/lib/python3.8/site-packages/torch/utils/data/_utils/collate.py", line 83, in <listcomp>
    return [default_collate(samples) for samples in transposed]
  File "/home/vase/software/miniconda3/envs/d2l/lib/python3.8/site-packages/torch/utils/data/_utils/collate.py", line 81, in default_collate
    raise RuntimeError('each element in list of batch should be of equal size')
RuntimeError: each element in list of batch should be of equal size

代码中这部分表示自定义DataLoader的时候再__getitem__() 的时候输出的list长度不一致,

这里如果是bbox本来就输出多个不同数量的结果可以尝试自己自定义collate() 这个方法

pytorch关于collate的源代码可以在这里找到
collate是输入一个batch,之后对batch进行处理,这要保证batch中的元素都是相同长度的(list的长度)
如果不同的话就需要自己进行处理

# 示例
# 将不同长度的batch 都统一放入一个list中,这样batch输出的就为1个list 而不是多个结果
def collate_fn(batchs):
    result = []
    for i in range(len(batch[0])):
        result.append([batch[i] for batch in batchs])
    return result

我的问题是__getitem__() 输出的是map 中有个元素长度不一, 网上给的简单的解决方法是在 DataLoader 处添加 collate_fn 这会直接输出list形式的数据(tensor等元素不会自己合并, 具体调用则是在自己调用到数据时自己考虑)

  1.      data_loader = DataLoader(
             datasets, 
             batch_size = dataset_cfg.batch_size, 
             collate_fn=lambda x:x,
         )
    

解决方法来源:https://github.com/pytorch/pytorch/issues/42654
batchs['key'] = pad_sequence(batch_key_in_one_list, batch_first=True)

但是这种方式治标不治本,每个batch是独立的,显然无法按batch输入网络进行训练(当然你可以在输入网络前将需要输入的内容手动合并成一个batch,但是这就没什么意思了.)

我的解决方法

# 因为我的数据集采出来只有map['lanes']的长度不一样,
# 所以我直接先将不能自动生成的pop保存起来,
# 之后组合起来后与可以合并的batchs合并即可
def collate_fn(batchs):
    from torch.utils.data.dataloader import default_collate
    lanes = []
    for i in range(len(batchs)):
        lanes.append(batchs[i].pop('lanes'))
    batchs = default_collate(batchs)
    batchs['lans'] = lanes
    return batchs
posted @ 2021-09-29 20:20  kenvision  阅读(1858)  评论(0编辑  收藏  举报