【yolov3】【3】yolov3-spp网络训练踩坑纪实(pytorch0.4环境跑pytorch1.0代码)

yolov3-spp是yolov3的一个版本,在yolo官网中给出了cfg和weights。
本文调试源码为ultralytics/yolov3,源码的解析放在之前的一篇yolov3-spp结构详解与源码解析(pytorch),这篇博客只记录在训练过程中出现的一些问题。

文章目录

      • bug1: 'too many indices for tensor of dimension 1'
      • bug2: 多GPU训练 ''YOLOLayer' object has no attribute 'ng''
      • bug3: ‘too many indices for tensor of dimension 1’
      • 问题4: 程序一直停在self.was_killed.is_set()并报错RuntimeError: DataLoader worker is killed by signal
      • bug5: 'tensor' object has no attribute argsort

bug1: ‘too many indices for tensor of dimension 1’

bug描述:
问题出在dataset.py文件中,collate_fn函数中有一句:

l[:, 0] = i

bug原因:
这一句为1个batch中的每张image的每一个label,赋值一个idx,即为对应的image,使得最后的label可以和image相对应。但是,有的image是没有对应的label的,而pytorch0.4会出现维度的问题,是因为会将这种空的tensor的维度挤压为1:
torch.Size([0])
解决:

    def collate_fn(batch):
        img, label, path, hw = list(zip(*batch))  # transposed
        for i, l in enumerate(label):
            try:
                l[:, 0] = i  # add target image index for build_targets()
            except:
                pass
        return torch.stack(img, 0), torch.cat(label, 0), path, hw

补充:
build_target.py中,出现了类似的问题,这里是因为t是空的,即targets中没有标签,个人分析,原因是整个batch中所有image都没有对应的label。依旧用try-except粗暴解决:

        # Indices
        try:
            b, c = t[:, :2].long().t()  # target image, class
            gxy = t[:, 2:4] * ng  # grid x, y
        except:
            continue
        gi, gj = gxy.long().t()  # grid x, y indices
        indices.append((b, a, gj, gi))

bug2: 多GPU训练 ‘‘YOLOLayer’ object has no attribute ‘ng’’

bug描述:
为了使用多GPU进行运算,对train.py进行了如下修改:

# Run model
# pred = model(imgs)		# 原程序
pred = nn.parallel.data_parallel(model, imgs)		# 修改后

问题出在计算loss的过程中,在build_targets函数中,显示YOLOLayermodule没有ng这个参数。

bug原因:
对比单gpu和多gpu运算,会发现在前向运算之后,单gpu的model会被更新,拥有ng等几个新参数;但是在多gpu的情况下,model不会被更新,查了一下,原因如下:
【yolov3】【3】yolov3-spp网络训练踩坑纪实(pytorch0.4环境跑pytorch1.0代码)_第1张图片
解决:
我没有解决这个问题,我后来只用单gpu了
【yolov3】【3】yolov3-spp网络训练踩坑纪实(pytorch0.4环境跑pytorch1.0代码)_第2张图片

bug3: ‘too many indices for tensor of dimension 1’

bug描述:
这个和bug1是同一个问题,出现在了utils.py中的build_targets中:

b, c = t[:, :2].long().t()

bug原因:
build_targets是将label(即targets)进行转化,方便和之后的网络输出进行匹配。这里的t是对targets进行iou的筛选后得到的,有可能是空的,因此又出现了维度的问题。

bug解决:
对此段代码进行如下修改:

# 原代码:
		b, c = t[:, :2].long().t()  # target image, class
        gxy = t[:, 2:4] * ng  # grid x, y
# 修改后:
        try:
            b, c = t[:, :2].long().t()  # target image, class
            gxy = t[:, 2:4] * ng  # grid x, y
        except:
            tcls.append(None)
            tbox.append(None)
            indices.append(None)
            av.append(None)
            continue

此外,还需要修改compute_loss中的一个地方

# 原代码:
	for i, pi in enumerate(p):  # layer index, layer predictions
        b, a, gj, gi = indices[i]  # image, anchor, gridy, gridx
        tobj = torch.zeros_like(pi[..., 0])  # target obj
# 修改后:
    for i, pi in enumerate(p):  # layer index, layer predictions
        if not indices[i]:
            continue
        b, a, gj, gi = indices[i]  # image, anchor, gridy, gridx
        tobj = torch.zeros_like(pi[..., 0])  # target obj

问题4: 程序一直停在self.was_killed.is_set()并报错RuntimeError: DataLoader worker is killed by signal

在训练过程中,会突然停住(如下图),也不报错,但也不继续训练,就只是停住,仿佛时间静止了。
在这里插入图片描述
解决方法:程序一直停在self.was_killed.is_set()并报错RuntimeError: DataLoader worker is killed by signal

bug5: ‘tensor’ object has no attribute argsort

bug描述:
问题出在utils.py中的这一句:

		# Get detections sorted by decreasing confidence scores
        pred = pred[(-pred[:, 4]).argsort()]

以及:

        if len(det_max):
            det_max = torch.cat(det_max)  # concatenate
            output[image_i] = det_max[(-det_max[:, 4]).argsort()]  # sort

bug描述:
就是没有能咋地( ̄— ̄)

bug解决:
替换为:

		pred = pred[torch.sort(-pred[:, 4])[1]]

下面那个也是类似的


终于可以正常训练了,撒花✿✿ヽ(°▽°)ノ✿
在这里插入图片描述
晚上和npy一起去吃付小姐轻松一下嘻嘻嘻,这几天全场58折!

你可能感兴趣的:(目标检测系列,pytorch,#,yolov3)