detectron2训练自己的数据集_Yolov3代码分析与训练自己数据集

30f4d8d13a16eedbc7f054cd07663938.png

现在要针对我们需求引入检测模型,只检测人物,然后是图像能侧立,这样人物在里面占比更多,也更清晰,也不需要检测人占比小的情况,如下是针对这个需求,用的yolov3-tiny模型训练后的效果。

5da7ba6ab958b14d40f07456e9dc4098.gif

Yolov3模型网上也讲烂了,但是总感觉不看代码,不清楚具体实现看讲解总是不清晰,在这分析下darknet的实现,给自己解惑,顺便也做个笔记。

首先查看打开yolov3.cfg,我们看下网络,可以用netron查看图形界面,可以发现网络主要以卷积层构成,shortcut(残差连接),route(通道组合)三种构成,首先用步长为2的卷积缩小图像一次,然后开始用shortcut(残差连接)连接一次再用步长为2的卷积缩小图像缩小二次,后面开始不断用卷积与残差组合,到开始分支,分出二个部分,每分出一个分支就把主支图像缩小次,最后加上主支部分一共三个分支,就是一共有3个yolo层,其中主支部分缩小了五次,第一次分支缩小三次,第二次分支缩小四次。

这里也解答了以前我的一个疑惑,从ResNet网络开始,开始隔层交流,不管是相加还是整合,我疑惑的是如何在文件这种列表形式下描述分支结构,原来很简单,一次描述一个分支,然后用route/shortcut记录分支层,继续向下描述。

回到网络部分,这三次分支可以用这图表示,网络上不知谁的,确实表达了很多要说的,不过有个问题,应该是版本更新了,我手上配置拿的是长宽是608*608,所以下图需要改一些,如13*13是19*19,大家明白就行,还有主支是32(2^5)倍那个,16与8是第二分支与第一分支,其中先算主支部分,算完主支然后上层卷积层upsample再与第二分支route一起算,第一分支同这逻辑。

f2311d513e579204167d43e0b56b216b.png

ec60eecbc2616cc2c3c8692c9715a858.png

这个yolo层就是主支部分,可以看如上分析,在这层特征图长宽只有19*19,对应如上 anchors中是根据k-means算法拿到对应图集K=9的分类簇框,其中mask=6,7,8指向最后三个大框,主支部分主要检测大物体,根据前面分析可以知道中框包含了大框的特征图结果,而小框包含中大的特征图结果,这应该yolov3相比v2针对小物体的识别提高的原因,而shortcut与route则保证网络能加深到一百多层。

darknet种各层的主要有三个函数,分别是make_xxx_layer, forward_xxx_layer, backward_xxx_layer, 这三个函数make_xxx_layer是初始各种参数,根据参数自动算一些参数,如卷积层,根据传入特征图的大小与核的参数,就能算出传出特征图的大小,以及申请内存或是显存,forward_xxx_layer表示根据当前层参数计算预测,而backward_xxx_layer根据上层的delta(如上层是yolo层,delta就表示期望输出-预测输出)与输入计算梯度,并更新下层需要的delta,以及还有个update_xxx_layer用于根据backward_xxx_layer计算的梯度来更新参数。而yolo,region,detection,softmax这几种检测层相对卷积层来说,没有参数weight,主要用来计算delta(期望输出-预测输出).而反向传播就是从这个yolo的delta开始的,在yolo的反向传播中,先把这个delta给卷积层的delta,然后结合前一层的输出,求得当前层的梯度,并把delta结合当前层的weights求得新的delta,然后下一层卷积层根据这个delta梯度,循环下去更新所有参数。

下面根据代码来分析yolov层,先看下make_yolo_layer的实现。

//在yolov3中,n=3 total=9(mask在yolov3中分三组,分别是[0,1,2/3,4,5/6,7,8],n表示分组里几个数据,n*3=total)

以主支来做分析,每张特征图有19*19个元素,c表示特征图个数,结合上图,一共有3*(80+4+1)=255,简单来说,分别对应116,90, 156,198, 373,326这三个聚类簇,其中前85个就是116,90这框的结果,85个特征图中前4个是边框坐标,1个置信度,80个类别概率,一共三个这种85特征图就是255个,还有标签(真实)数据,这里90表示如上w*h(19*19中)每个格子最多有90个label,而每个label前面4个float表示box的四个点,后面1个float表示当前类别,搞清楚这二个对应排列,在如下的forward_yolo_layer里,我们才能明白如何计算的delta,代码加上注释有点多,这段就不贴了,代码部分说明下。

主要有二部分,还是先说下,在这里delta表示 期望输出-out(不同框架可能不同,我看caffe里的yolo实现,就是out-期望输出)。

第一部分,前面查找所有特征图(在这1batch是三张)里的所有元素(19*19)里的所有confidence,准确来说是主支的19*19个元素,每个元素有三个大框预测,检测对应所有框里真实数据最好的box的iou,如果iou大于设定的ignore_thresh,则设delta为0,否则就是0-out(0表示没有,我们期望输出是0)。

第二部分,在对照所有真实label中,先找到这个label是否是大框,如果不是,这个yolo层不管,如果是,继续看是上面6,7,8中的那一个,我们假设是7,根据真实框的位置确定在特征图的位置(19*19中),其对应255张特征图中间的85-170这85张图,然后比较真实的BOX与对应特征图预测的box,算出对应box的 delta,然后是confidence的delta(可以知道,正确的box位置上的元素会算二次confidence损失),然后是类别的delta。各delta比较简单,如果认为是真的,delta=1-out,如果是错的,delta=0-out,简单来说就是期望输出-out,最后网络cost就是每层yolo的delta的平方和加起来的均值。

然后是yolo训练时输出的各项参数(这图用的是yolov3-tiny训练,所以只有16和23这二个yolo层),对比如上16层检测大的,23检测小的。

d20d6ec7c0e76d490ad56c62dfe08981.png

可以看到,count是表示当前层与真实label正确配对的box数,其中所有参数都是针对这个值的平均值,除no obj外,不过从代码上来,这个参数意义并不大,所以当前yolo层如果出现nan这个的打印,也是正常的,只是表示当前batch刚好所有图片都是大框或是小框,所以提高batch的数目可以降低nan出现的机率,不过相应的是,batch提高,可能显存就暴了,我用的2070一次用默认的64张显存就不够,只能改成32张。其中avg iou表示当前层正确配对的box的交并比的平均值,class表示表示当前层正确配对类别的平均机率,obj表示confidence = P(object)* IOU,表示预测box包含对象与IOU好坏的评分,0.5R/0.7R:表示iou在0.5/0.7上与正确配对的box的比率。

搞明白darknet框架各层后,回到我们需求,引入检测模型,只检测人物,然后是图像能侧立,这样人物在里面占比更多,也更清晰,也不需要检测人占比小的情况。先说明下,用的yolov3-tiny,因为可能要每桢检查并不需要占太多资源,故使用简化模型。

首先筛选满足条件的数据集,本来准备用coco数据自带api分析,发现还麻烦些,数据全有了,逻辑并不复杂,用winform自己写了就行了。

/// <summary>

只有一点需要注意,我们只记录人类box标签数据,但是这些标签需要全部大于特定面积的图,如果你选择的上面还有小面积人物,又不给box标签训练,最后yolo层并没面板的损失函数,会造成干扰,在这本来也没有检查小面积人物的需求,yolov3-tiny层数本也不多,需求泛化后精度很低。

darknet本身并没有针对侧立做适配,我们需要修改相应逻辑来完成,很简单,一张图四个方向旋转后,同样修改相应的truth box就行了是,darknet数据加载主要在data.c这部分,找到我们使用的加载逻辑load_data_detection里,主要针对如下修改。

data 

然后拿到yolov3-tiny.cfg文件,先把burn_in修改成1,我们没有预精确数据,最开始就以原始学习率开始训练,对应二个yolo层里的classes改成一,记的前面说过,这个层就是分析上面的卷积层,故上面的输出filters=3*(4+1+1)=18,第一次训练后发现五W次就没怎么收敛了,分析了下,应该是anchors导致的,当图像侧立后,这里的也应该有类似数据,故选择全大面积人物二种特定框,分别取侧立,这里正确的搞法应该是用k-means再重新取K=2算一下所有现在特定图的框,分别对应大框与小框,然后侧立下,大框就有二个,小框二个,num=4,mask每层设二个索引,或是K=4,然后让上面来,后面抽出时间完善这步,现暂时用如下数据anchors = 100,100, 119,59, 59,119, 200,200, 326,373, 373,326,这些调整后,现训练21W次,也还一直收敛中。

训练与验证根据他自身的train_yolo/validata_yolo修改下,自己可以打印出自己想要的信息,验证可以结合opencv显示我们想要的各种图形比对效果。

7cfa8c2a79d39b45e0af899afda393c4.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值