bubbliiiing / yolov4-pytorch

这是一个YoloV4-pytorch的源码,可以用于训练自己的模型。
MIT License
2.1k stars 615 forks source link

AttributeError: 'list' object has no attribute 'cuda' #357

Open Jie-Huangi opened 1 year ago

Jie-Huangi commented 1 year ago

B导,我将您yolov7中的YOLOLoss代码移植到了yolov4当中,形参和实参都对应上了,可是在获取原始数据的targets时出现了错误。我感觉是是targets被分成了不同的batch,而fit_one_epoch函数里面的targets = targets.cuda(local_rank)这行代码需要的是一个tensor。我不知道分析得对不对,也不知道怎么改了,搞了一下午加一晚上也没有弄明白,还请B导指导指导,感激不尽!!

Jie-Huangi commented 1 year ago

找到原因了,在dataloader 的最后一个函数yolo_dataset_collate里面,需要将传进来的参数使用enumerate去建立一个索引,之后再把bboxes的数据根据索引全部放入bboxes里面去。 附上代码:

def yolo_dataset_collate(batch):
    images  = []
    bboxes  = []
    for i, (img, box) in enumerate(batch):
        images.append(img)
        box[:, 0] = i 
        bboxes.append(box)

    images  = torch.from_numpy(np.array(images)).type(torch.FloatTensor)
    bboxes  = torch.from_numpy(np.concatenate(bboxes, 0)).type(torch.FloatTensor)
    return images, bboxes
Jie-Huangi commented 1 year ago

这是 yolov4 中的加载images 和bboxes的代码,我将yolov4 中的损失换成了yolov7的损失格式,罪魁祸首就是这里出了问题,当然还需要改动其它地方。 附上yolov4 中的 yolo_dataset_collate 代码:

def yolo_dataset_collate(batch):
    images = []
    bboxes = []
    for img, box in batch:
        images.append(img)
        bboxes.append(box)
    images = torch.from_numpy(np.array(images)).type(torch.FloatTensor)
    bboxes = [torch.from_numpy(ann).type(torch.FloatTensor) for ann in bboxes]
    return images, bboxes
Jie-Huangi commented 1 year ago

总结一下,这里关键还是拼接的问题。刚刚又去研究了一下,发现根本问题是yolov4的targets拼接到一起,附上代码加以区分:

# yolov7 中的代码
bboxes  = torch.from_numpy(np.concatenate(bboxes, 0)).type(torch.FloatTensor) # concatenate拼接某维度的参数

# yolov4 中的代码
bboxes = [torch.from_numpy(ann).type(torch.FloatTensor) for ann in bboxes] # 直接循环赋值给了ann,还是两个列表的形式
bubbliiiing commented 1 year ago

理解,yolov7和yolov4获取的东西貌似并不相同,一个获得的直接是目标的矩阵,一个获得的是真实框