Indices should be either on cpu or on the same device as the indexed tensor
我下载了一个为YoloV7准备的数据集。我还克隆了yoloV7 Repo。
我想用这个下载的数据集来训练一个模型,为此我使用了这个命令。
python train.py --workers 8 --device 0 --batch-size 16 --data data.yaml --img 640 640 --cfg cfg/training/yolov7.yaml --weights yolov7x.pt --name yolov7 --hyp data/hyp.scratch.p5.yaml
我得到了这样的RuntimeError
autoanchor: Analyzing anchors... anchors/target = 5.50, Best Possible Recall (BPR) = 1.0000
Image sizes 640 train, 640 test
Using 8 dataloader workers
Logging results to runs\train\yolov74
Starting training for 300 epochs...
Epoch gpu_mem box obj cls total labels img_size
0%| | 0/372 [00:03<?, ?it/s]
Traceback (most recent call last):
File "D:\projects\yolov7\train.py", line 618, in <module>
train(hyp, opt, device, tb_writer)
File "D:\projects\yolov7\train.py", line 363, in train
loss, loss_items = compute_loss_ota(pred, targets.to(device), imgs) # loss scaled by batch_size
File "D:\projects\yolov7\utils\loss.py", line 585, in __call__
bs, as_, gjs, gis, targets, anchors = self.build_targets(p, targets, imgs)
File "D:\projects\yolov7\utils\loss.py", line 759, in build_targets
from_which_layer = from_which_layer[fg_mask_inboxes]
RuntimeError: indices should be either on cpu or on the same device as the indexed tensor (cpu)
我的系统包含1xCpu,1xCuda GPU(它是一个默认的游戏电脑)。
我相信这是当前实现中的一个错误。你可以通过修改utils/loss.py
第685行来解决这个问题。
from_which_layer.append((torch.ones(size=(len(b),)) * i).to('cuda'))
并在756后面加一行,把fg_mask_inboxes
放在你的cuda设备上。
fg_mask_inboxes = fg_mask_inboxes.to(torch.device('cuda'))
"cpu"
改成'cuda'
,在utils/loss.py
中改。
- Cubimon 2022-12-31
如果你要用yolov7使用p6模型,你需要使用train_aux.py,而不是train.py,而且你还需要修改几行。
1336 -- from_which_layer.append((torch.ones(size=(len(b),)) * i).to('cuda'))
1407 -- fg_mask_inboxes = fg_mask_inboxes.to(torch.device('cuda'))
https://github.com/WongKinYiu/yolov7/blob/main/utils/loss.py
试着将第742行改为
matching_matrix = torch.zeros_like(cost, device="cpu")
这对我来说是有效的。
你可以通过修改utils/loss.py
来解决这个问题。替换utils/loss.py
的第759行,即
from_which_layer = from_which_layer[fg_mask_inboxes]
改为
from_which_layer = from_which_layer.to(fg_mask_inboxes.device)[fg_mask_inboxes]
这种修改的主要思路是将两个变量from_which_layer
和fg_mask_inboxes
放在同一个设备中。