- https://blog.csdn.net/u014380165/article/details/72616238
- https://blog.csdn.net/m0_37192554/article/details/81092514
- PennFudanPed数据集
文章目录
网络结构
假设输入图像 [1,3,448,448]–>backbone Net–>[1,2048,7,7]–>[1,B(1+4)+C,7,7]
则有 S=7, 取B=2,以PASCAL VOC数据为例有20个类别,则C=20
[[1,B(1+4)+C,7,7]]=[1,30,7,7]
这30列的具体意义,如下图所示
也可以按这种方式解析,只需保证训练与推理时使用同一种解析方式
算法流程解析
算法首先把输入图像划分成S*S
的格子,然后对每个格子都预测B个bounding boxes,每个bounding box都包含5个预测值:x,y,w,h和confidence。x,y就是ground truth的中心坐标,与grid cell左上角的偏差/
格网大小使得范围变成0到1;w和h进行归一化(分别除以图像的w和h,这样最后的w和h就在0到1范围)。
输入图像大小 h=448,w=448
每个grid cell大小为 h_gc=w_gc=448//S=448//7=64
假设ground truth 的boxes为 [100,200,300,400] x1,y1,x2,y2的格式,
-
1.转成x0,y0,w,h格式为[(x1+x2)/2,(y1+y2)/2,(x2-x1),(y2-y1)]=[200.,300.,200,200],
-
2.计算其中心点落在哪个grid cell里
$200/64 \approx 3.125$
,$300/64\approx 4.6875$
,则对应的grid cell 为(3,4)-(4,5)
,也就是由该grid cell负责预测该ground truth -
3.将
x0,y0,w_gt,h_gt
归一化到0~1范围,(x0-3*64)/w_gc,(y0-4*64)/h_gc,w_gt/w,h_gt/h
得到为0.125,0.6875,0.4464,0.4464
-
4.如何得到对应的预测box
- 先解析
feature:[1,30,7,7]
这些列的含义,按方式一来解析 - pred_box1=feature[1,0:5,:,:]=[5,7,7]=reshape [7,7,5],
- pred_box2=feature[1,5:10,:,:]=[5,7,7]=reshape [7,7,5],
- pred_cls=feature[1,10:,:,:]=[20,7,7]=reshape [7,7,20]
- 先解析
-
5.该ground truth对应的预测2个框为
- pred_box1=pred_box1[3:4,4:5,5]
- pred_box2=pred_box2[3:4,4:5,5]
- 按3说的重新反转成x1,y1,x2,y2的格式在与ground truth计算IOU值分别为IOU_1,IOU_2
- 如果IOU_1>IOU_2,则取pred_box1为预测的box(其置信度为其与对应的gt_box的IOU值),pred_box2也当做没目标处理(其置信度为0)
-
推理时做
:每个bounding box的confidence和每个类别的score相乘,得到每个bounding box属于哪一类的confidence score ;pred_cls=pred_cls*pred_box1[:,:,-1]
(最后一个为 box的confidence)
来看看 S×S×30
的数据块的具体含义。
-
S×S是图像位置,比如第一行第二列的网格,回到原图的位置也是如此。(有全连接层的时候,其实随意,只要你预测时每个位置的网格对应你编码时的网格就可以。全卷积层由于每个点的感受野的问题,最好是一一对应,否则原理上说不通,效果应该会差很多)
-
30的通道上分别是两个box的
cx,cy,w,h,confidence
,这就占了10个,再加上20个类别正好是30 -
cxcy表示物体的中心点坐标与对应网格左上角的偏差,注意归一化到0-1,需要除以网格大小;wh是物体相对于图片的大小,也在0-1之间;confidence是
P(object)×IOUpredtruth
,其中IOU在训练过程中是在线计算的 -
首先要明确两个概念,一是网格中有无目标,二是网格中的一个目标只有一个box负责(responsible)另一个box也算没有目标,根据在线计算IOU的大小确定哪一个负责。
-
含有目标的confidence先设置为1∗IOUtarget,用于区别不含目标的(没有目标和iou阈值小的都是0),IOU target在线计算)。
loss 计算
第三、四行表示bounding box的confidence损失,就像前面所说的,分成grid cell包含与不包含object两种情况。这里注意下因为每个grid cell包含两个bounding box,所以只有当ground truth 和该网格中的某个bounding box的IOU值最大的时候,才计算这项。
因为很多grid cell是不包含物体的,这样的话很多grid cell的confidence score为0。所以采用设置不同权重方式来解决,一方面提高localization error的权重,另一方面降低没有object的box的confidence loss权值,loss权重分别是5和0.5。而对于包含object的box的confidence loss权值还是原来的1。
需要注意的
-
1.yolo不需要像fasterrcnn那样事先生成anchor,而是自己生成
-
2.
推理时做
:每个bounding box的confidence和每个类别的score相乘,得到每个bounding box属于哪一类的confidence score。 -
3.一个grid cell中是否有object怎么界定?
首先要明白grid cell的含义,以文中7*7
为例,这个size其实就是对输入图像(假设是224*224
)不断提取特征然后sample得到的(缩小了32倍),然后就是把输入图像划分成7*7
个grid cell,这样输入图像中的32个像素点就对应一个grid cell。回归正题,那么我们有每个object的标注信息,也就是知道每个object的中心点坐标在输入图像的哪个位置,那么不就相当于知道了每个object的中心点坐标属于哪个grid cell了吗,而只要object的中心点坐标落在哪个grid cell中,这个object就由哪个grid cell负责预测,也就是该grid cell包含这个object。另外由于一个grid cell会预测两个bounding box,实际上只有一个bounding box是用来预测属于该grid cell的object的,因为这两个bounding box到底哪个来预测呢?答案是:和该object的ground truth的IOU值最大的bounding box。 -
4.假设预测的值为
pred[m,30]
, target为boxes[n,4]
,labels[n,20]
不包括背景(转成one-hot)- 反算出boxes中心点落在grid ceil的网格,有目标的
mask[n,]
没有目标no_mask[m-n,]
- loss_conf:
mse(pred[n,4],1)+mse(pred[m-n,4],0)*0.5
- loss_boxes:
loss_boxes=mes(pred[n,0],boxes[n,0)+mes(pred[n,1],boxes[n,1])+mse(sqrt(pred[n,2]),sqrt(boxes[n,2]))+mse(sqrt(pred[n,3]),sqrt(boxes[n,3]))
loss_boxes=loss_boxes*5
- loss_cls:
mse(pred[n,-20:],labels[n,20])
loss=loss_conf+loss_boxes+loss_cls
- 反算出boxes中心点落在grid ceil的网格,有目标的
-
5.推理时
score=pred[:,4]*pred[:,-20:]
代码实现
完整代码在这里:here
数据集
数据描述: 只有170
张,随机取出150
张做训练,剩下的20
张做验证
模型
查看训练过程loss
变化:tensorboard --logdir=./yolov1_resnet50_416 --host 0.0.0.0
选择resnet50-416
(输入大小统一resize为416x416
)
在验证集上的结果:
后续改进
- 1、上面使用的数据集太小,只能做算法模型验证,没法用于实际生产,后续在
Pascal Voc
数据集,MS COCO
数据集上训练,进一步验证算法模型 - 2、加入很多的数据增强方法(
Data Augmentation
) - 3、多尺度训练 size 可以取
np.arange(10,30)*32
,上述模型固定输入大小为416x416
- 4、更换
backbone
网络,上述模型是使用resnet50
- 5、加入
FPN
网络 (yolov3
) - 6、加入先验anchor机制(
yolov2
,yolov3
)(其实yolov1也使用到先验anchor,它的两个anchor大小都是每个ceil的大小,如:图像大小为:416x416,featureMap:7x7,则每个ceil的大小为32x32
,而这个其实也是其先验anchor 的大小)