yolov3-spp是yolov3的一个版本,在yolo官网中给出了cfg和weights。
本文调试源码为ultralytics/yolov3,源码的解析放在之前的一篇yolov3-spp结构详解与源码解析(pytorch),这篇博客只记录在训练过程中出现的一些问题。
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))
bug描述:
为了使用多GPU进行运算,对train.py
进行了如下修改:
# Run model
# pred = model(imgs) # 原程序
pred = nn.parallel.data_parallel(model, imgs) # 修改后
问题出在计算loss的过程中,在build_targets
函数中,显示YOLOLayer
module没有ng
这个参数。
bug原因:
对比单gpu和多gpu运算,会发现在前向运算之后,单gpu的model会被更新,拥有ng等几个新参数;但是在多gpu的情况下,model不会被更新,查了一下,原因如下:
解决:
我没有解决这个问题,我后来只用单gpu了
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
在训练过程中,会突然停住(如下图),也不报错,但也不继续训练,就只是停住,仿佛时间静止了。
解决方法:程序一直停在self.was_killed.is_set()并报错RuntimeError: DataLoader worker is killed by signal
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]]
下面那个也是类似的