yolov3学习笔记

一、dataloder部分
数据的输入是图片加上图片对应的targets,这个targets是一张图片中所拥有的全部真实框的中心位置x,y和宽高w,h和类别,共5个参数。如一张图片有3个框,那么这张图片的输入就是
img ,target :(3, 5(x,y,w,h,class)) 这里x,y w ,h都是归一化之后的。

注意:这里有一个问题,如果一个batch_size中有多张图片,每个图片的框的数目不一致,那么这个targets的size是什么样的呢?
代码中的处理是将target放入一个列表中,通过列表的索引来找到对应的图片:

  for iteration, batch in enumerate(gen):
        images, targets = batch[0], batch[1]
        with torch.no_grad():
            if cuda:
                images  = torch.from_numpy(images).type(torch.FloatTensor).cuda()
                targets = [torch.from_numpy(ann).type(torch.FloatTensor).cuda() for ann in targets]
            else:
                images  = torch.from_numpy(images).type(torch.FloatTensor)
                targets = [torch.from_numpy(ann).type(torch.FloatTensor) for ann in targets]

比如一个targets里面的数据形式是:[tensor(1,5),tensor(3,5),tensor(6,5)]

二、loss部分

首先要区分的是正负样本
正样本:与GT的IOU最大的为正样本
忽略样本: 除了正样本后与GT的IOU>0.5的anchor
负样本: 除了正样本后与GT的IOU<0.5的anchor
注意的是:论文中提到的:置信度的标签不再像yolov1 v2中使用iou来设定,而是找到iou最大的先验框后,直接将这个框的置信度标签设置为1. 因为很多先验框与GT的IOU最高只能有0.7左右,如果将iou作为标签,会导致训练效果不好。
在这里插入图片描述
损失函数:(引用同济子豪兄的教程)
在这里插入图片描述

主要代码:

loss_x      = torch.mean(self.BCELoss(x[obj_mask], y_true[..., 0][obj_mask])*box_loss_scale )
#这里的BCELoss返回的是一个1维度的tensor,就是每一个的交叉熵之和
loss_y      = torch.mean(self.BCELoss(y[obj_mask], y_true[..., 1][obj_mask])*box_loss_scale )
loss_h      = torch.mean(self.MSELoss(h[obj_mask], y_true[..., 3][obj_mask])*box_loss_scale)
loss_loc    = (loss_x + loss_y + loss_h + loss_w) * 0.1
loss_cls    = torch.mean(self.BCELoss(pred_cls[obj_mask], y_true[..., 5:][obj_mask]))
loss        += loss_loc * self.box_ratio + loss_cls * self.cls_ratio
loss_conf   = torch.mean(self.BCELoss(conf, y_true[...,4])*y_true[...,4]) +torch.mean(self.BCELoss(conf, y_true[...,4])*noobj_mask)
loss        += loss_conf * self.balance[l] * self.obj_ratio

y_true和obj_mask还没有完全理解是什么意思。
obj_mask = y_true[…, 4] == 1

发现的问题:

targets中,16张图片共有48个框的信息,
但是1313的feature map中的obj_mask的sum值为26,这是说明有物体的特征点有19个吗?
26
26的feature map中的obj_mask的sum值为19
52*52的feature map中的obj_mask的sum值为3

理解: 这48个框,有26个框需要由2626尺寸的feature map来检测,有19个框需要由2626的feature map来检测,有3个框需要由52*52的feature map 来检测

语法记录:
1.在设置noobj_mask的时候看到一个操作:

noobj_mask[b][anch_ious_max > self.ignore_threshold] = 0

这里anch_ious_max.size是torch.Size([3, 13, 13]) noobj_mask尺寸大小是[bs,3,13,13]
这行代码的意思就是noobj_mask的第[b]个特征中,anch_ious_max对应位置>self.ignore_threshold的值就设置为0

2.y_true[…, 2][obj_mask],通过mask来得到对应位置的值
这里的mask是bool值,如果通过.dtype查看会得到uint8数据类型,在torch中使用.byte()得到

a = torch.tensor([[[1,2],[6,7],[4,5]],[[1,2],[6,7],[4,5]]])
b = torch.tensor([[[1,0],[1,1],[0,0]],[[0,1],[0,1],[0,0]]]).byte()
print(a[b],a[b].size())
>>>tensor([1, 6, 7, 2, 7]) torch.Size([5])

3.如何快速获得一个tensor的mask

obj_mask    = y_true[..., 4] == 1  
#obj_mask表示当前这个特征点有物体为1,否则为0

4,对于torch.cat()函数的理解:

a = torch.rand(2,2,2)
b = torch.rand(2,2,2)
#cat(xxx,dim)函数的参数有两个,xxx是一个tensor列表或者元组。dim是指在哪个维度上进行连接
#要把a,b连接起来有两种方式,
#1.使用列表
ki = torch.cat([a,b],-1)
#2.直接用到a,b组成的元组
ki = torch.cat((a,b),-1)
#dim的常用方式写法:dim = -1 这种就是把一堆尺寸一致的数据在列的维度上进行连接。

5.torch如何生成网格坐标的矩阵:

#repeat函数:当参数只有两个时:(行的重复倍数,列的重复倍数)。1表示不重复
#			当参数有三个时:(通道数的重复倍数,行的重复倍数,列的重复倍数)。
#注意:repeat函数只能重复到3维。要变成4维或者更高需要用到view函数

#linspace函数:三个参数:起始,终止,期间有多少个点,最后取的是平均值
a =  torch.linspace(0, 12 , 13)
b = a.repeat(48,13,1).view([16,3,13,13])
print(b.size())
>>>torch.Size([16, 3, 13, 13])

在这里插入图片描述
在这里插入图片描述
三、非极大抑制:
基本思想:一张图片中同一个物体可能有多个预测框,但是我们通常只需要最好的那一个,这个时候就需要用非极大抑制去掉那些不好的,但是同时要注意的是,当两个同类物体位置接近时,这两个物体的框会有重叠的部分,因此非极大抑制中有对这个部分的处理。
网络的输出是(bs,boxes,(4+1+classes)) 后面要对单张图片处理,使用for output in outputs: 这是对单张图片进行处理,此时的output的size为(boxes,(4+1+classes))即一张图片中有多个种类的多个框。
基本步骤:
1.先按照(4+1+classes)中的1(框框中包含物体的置信度),按照设定的阈值,挑选出我们认为存在物体的N个box.
2.然后将这些box的类别置信度以及类别计算出来,得到一个(N,5+class_conf+class)的box矩阵。
3.按照我们设定好的类,将各个类别的box取出来。
4.对于某一类别的boxes: 将它们按照类别置信度class_conf进行从大到小排序,将最大的那一个box认为是一个物体的预测框best_box,并将当前的best_box加入到best_boxes列表中。
5.对于剩下的boxes,与当前的best_box进行iou计算,将iou小于阈值的保留下来作为下次循环的输入,这是因为iou小于某个阈值,说明这可能是另一个物体的预测框。
6.重复4,5,知道所有预测物体都只有一个框。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值