Kaggle实战目标检测奇淫技巧合集

栏目: 编程语言 · 发布时间: 5年前

内容简介:同时提供每月大咖直播分享、真实项目需求对接、干货资讯汇总,行业技术交流

加入极市 专业CV交流群,与 6000+来自腾讯,华为,百度,北大,清华,中科院 等名企名校视觉开发者互动交流!更有机会与 李开复老师 等大牛群内互动!

同时提供每月大咖直播分享、真实项目需求对接、干货资讯汇总,行业技术交流 点击文末“ 阅读原文 ”立刻申请入群~

本文授权转载自   我爱计算机视觉

Kaggle实战目标检测奇淫技巧合集

本文来自52CV群友Spytensor参加Kaggle目标检测比赛的总结,作者是位数据竞赛爱好者,文章非常具有实战意义。欢迎收藏~

原文链接:

http://spytensor.com/index.php/archives/53/

背景

国内的数据竞赛真的缺乏交流,还是喜欢 kaggle 的 kernel 和讨论区,真硬核!这里分享一下我总结的一些目标检测中会用到的 “奇淫技巧”,牵扯到代码的我就直接拿 mmdetection[1] 来举例了,修改起来比较简单。

1. 模型选择

近一年多以来目标检测领域没有太大的动静,即使最近一段时间的 Anchor Free 和神经网络搜索框架比较热,但都没有太大的革新,当前检测竞赛圈的通用配置还是 Cascade-R-CNN + ResNeXt/ResNet 系列 + FPN+DCN 2,毕竟二阶段为王!然后就是一些根据实验结果的调整了,由于商汤没有开源 SeNet 系列的训练模型,所以如果有卡的话可以自己搞。

Kaggle实战目标检测奇淫技巧合集

2. 数据预处理

如果你 baseline 选的准,那么基本上已经领先一大部分人了,但是如果在数据预处理过程中没有搞好,那基本上就跟 TOP 系列无缘了,毕竟在数据处理上能够领先的大佬,后面炼丹的技术也绝对不差。这里分为以下几个部分聊一聊数据这方面的策略:

2.1 数据扩充

如果说待检测目标具有旋转不变性,那这里就可以对目标做上下翻转、左右反转、90°*3 旋转等操作;如果目标中存在模糊的情况,在扩充的时候也可以适当做一些高斯模糊什么的;对于颜色抖动、锐度变化、随机缩放等这些操作,我实验的过程中也很难界定他们的效果,而且跟队友做相同实验时,所起的作用也不一样,总结来说,有的时候真的是随机上分。

2.2 mixup

mixup 的意思就是将两张图按照一定的比例混合在一起,详情移步论文:Bag of Freebies for Training Object Detection Neural Networks[4]。这里要说的是如何 mixup,如何选择 mixup 的对象。

Kaggle实战目标检测奇淫技巧合集

在工业类缺陷检测或者违禁物品检测中,常常会给出一些不含有待检测目标的正常图像,可以将含有目标的图像和随机选取的正常图像进行 mixup(随机意味着更多的组合~),这样数据量又上来了。还有一种是徐大哥用的比较骚的操作,就是跟 coco 的数据集进行 mixup,真是服气。。。

2.3 填鸭式

这个肯定别人也这么叫过,但是我们队一开始想到的时候,就这么称呼了。所谓填鸭式,就是将一些目标(也可以是误捡的)扣出来,放到没有目标的图上去,增加图像的鲁棒性。比如我们在钢筋识别的时候,有一些小石子和吊机容易被误判成钢筋,索性就选了一些图,把这些伪目标填充合理的位置上,效果就是没有再误判过了。

在津南 2 违禁物品的检测中,我们一开始也测试了 mixup 的策略,但是效果一般,后来改用 “填鸭式” 处理,效果要好很多,应该说前排基本都用了这个方法吧(猜测)。这里有一个要注意的就是“随机”,要是能够让目标在正常图像中的随机位置填充并且随机旋转和缩放,那就完美了,无奈这个没有实现好,如果有大佬实现了,求指导。。。。

Kaggle实战目标检测奇淫技巧合集

3. 预训练模型

数据处理完以后,基本上就是要冲击前排了,这里就是要考虑如何选用预训练模型了,一般的检测都是使用 ImageNet 预训练的 backbone,这是基本配置,高级一点的就是针对数据集做一次预训练,比如津南 2 的违禁物品检测,可以将所有目标裁剪出来,然后训练一个不错的分类模型,这样的初始化相比 ImageNet 就要好太多了。。。

再一点就是使用 coco 预训练的完整检测模型权重,这样的效果就是模型收敛速度贼快,而且效果一般都比较好,也是大家最常用的方法,这里给出 mmdetection 修改 coco 预训练权重类别数的脚本:


 

# for cascade rcnn

import torch

num_classes = 21

model_coco = torch.load("cascade_rcnn_x101_32x4d_fpn_2x_20181218-28f73c4c.pth")


# weight

model_coco["state_dict"]["bbox_head.0.fc_cls.weight"].resize_(num_classes,1024)

model_coco["state_dict"]["bbox_head.1.fc_cls.weight"].resize_(num_classes,1024)

model_coco["state_dict"]["bbox_head.2.fc_cls.weight"].resize_(num_classes,1024)

# bias

model_coco["state_dict"]["bbox_head.0.fc_cls.bias"].resize_(num_classes)

model_coco["state_dict"]["bbox_head.1.fc_cls.bias"].resize_(num_classes)

model_coco["state_dict"]["bbox_head.2.fc_cls.bias"].resize_(num_classes)

#save new model

torch.save(model_coco,"coco_pretrained_weights_classes_%d.pth"%num_classes)

这里再说一下 backbone 的选择,因为要考虑到要使用 coco 预训练权重的原因,暂时采用的都是官方给出的模型以及对应的 backbone。我自己也在 mmdetection 中实现了 SeNet 系列的 backbone,无奈没卡,没法训一个 coco 出来。。。。

4. 训练技巧

深度炼丹名不虚传。。。。。

4.1 warmup lr

翻译一下就是对学习率进行预热,最开始是在 ResNet 的论文中提到的一种方法,原始是先在前几个 epoch 或 iter 或目标达到一个水准之前以小于预设值得 lr 进行训练,然后再恢复 lr 到初始值。后来 Facebook 提出了改良版本,详情请移步论文: Gradual warmup[5],这也是当前检测和分割中必不可少的环节,mmdetection 中默认是启用了的:


 

lr_config = dict(

policy='step',

warmup='linear',

warmup_iters=500,

warmup_ratio=1.0 / 3,

step=[8, 11])

4.2 lr 如何计算

学习率的初始化设置一直是一个比较头疼的问题,有的时候需要经常实验才能得到一个比较好的值,我们在检测任务中常用的计算方法是:lr = 0.02 / 8 x num_gpus x img_per_gpu / 2,一般情况都是这么计算后设置。

4.3 多尺度训练

检测的两大任务:分类和定位,定位需要模型能够适应变化频繁的尺度特征,但是这恰恰是卷积神经网络所不具备的,目前在网络模型上通过 FPN 结构可以缓解一部分,另外就是多尺度训练,在不同的 iter 下选择不同的尺度进行训练,注意尺寸最好时能够被 32 整除,不过 mmdetection 会检查这一点,帮你 pad 一下。

4.4 损失函数

4.4.1 Focal Loss

这是 CV 中根据实验结果调整损失函数最先考虑的一个,论文: Focal Loss for Dense Object Detection, 主要是针对模型拟合困难的样例或者样本不均衡的样例,在图像分类中常用作最终的损失函数,直接进行优化,而在目标检测中却有两个选择,一个是在 RPN 层使用 FocalLoss,这样可以缓解由于目标占比较少导致生成的 anchor 正负样本比例失衡;另一种就是类似图像分类一样,在 bbox_head 中使用,mmdetection 中的相应配置 (如果要正确使用,需要做点改动,自行修改源码吧,不难):


 

#1. rpn 处更改

rpn_head=dict(

type='RPNHead',

in_channels=256,

feat_channels=256,

anchor_scales=[8],

anchor_ratios=[0.5, 1.0, 2.0],

anchor_strides=[4, 8, 16, 32, 64],

target_means=[.0, .0, .0, .0],

target_stds=[1.0, 1.0, 1.0, 1.0],

loss_cls=dict(

type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),

loss_bbox=dict(type='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0))


#2. bbox_head 处更改

bbox_head=dict(

type='SharedFCBBoxHead',

num_fcs=2,

in_channels=256,

fc_out_channels=1024,

roi_feat_size=7,

num_classes=81,

target_means=[0., 0., 0., 0.],

target_stds=[0.1, 0.1, 0.2, 0.2],

reg_class_agnostic=False,

loss_cls=dict(

type='CrossEntropyLoss', #在此处替换

use_sigmoid=False,

loss_weight=1.0),

loss_bbox=dict(

type='SmoothL1Loss', beta=1.0, loss_weight=1.0)))

4.4.2 GIou Loss

Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression,之前旷世提出了 Iou Loss 收敛性较差,GIOU 的详细介绍,我之前一篇博客介绍了,这里不再赘述,详情移步:Generalized Intersection over Union, 这里只提一下,这种损失函数对增加框的回归效果比较有效,如果你的任务要求 IOU > 0.8 或者更高,这个可以优先考虑。

4.4.3 其他损失函数

针对分类的损失函数可以试试如 GHM-C Loss,针对回归的损失函数可以试试如 GHM-R Loss。

4.5 OHEM

OHEM(online hard example mining),翻译过来就是在线难例挖掘,就是对所有的 ROI 的损失进行评估,选择损失较大的来优化网络。

5. infer 技巧

5.1 TTA

检测任务中使用比较多的就是多尺度预测,这个时间开销有点高,但是效果也是不错的。另外一个就是 CV 中最常用的 TTA 了(Test Time Augmentation),如果在训练的过程中加入了旋转和翻转,那么前向过程中也需要加上,即使训练没用的话,加上翻转也会有提升。

5.2 Soft-NMS

Soft-NMS 改进了之前比较暴力的 NMS,当 IOU 超过某个阈值后,不再直接删除该框,而是降低它的置信度 (得分),如果得分低到一个阈值,就会被排除;但是如果降低后仍然较高,就会被保留。实现细节移步:NMS 与 soft NMS

在 mmdetection 中的设置如下:


 

test_cfg = dict(

rpn=dict(

nms_across_levels=False,

nms_pre=1000,

nms_post=1000,

max_num=1000,

nms_thr=0.7,

min_bbox_size=0),

rcnn=dict(

score_thr=0.05, nms=dict(type='soft_nms', iou_thr=0.5), max_per_img=100),

keep_all_stages=False)


参考文献

[1] : mmdetection
[2] : Cascade R-CNN: Delving into High Quality Object Detection
[3] : Deformable ConvNets v2: More Deformable, Better Results
[4] : Bag of Freebies for Training Object Detection Neural Networks
[5] : Gradual warmup

*延伸阅读

点击左下角 阅读原文 ”, 即可申请加入极市 目标跟踪、目标检测、工业检测、人脸方向、视觉竞赛等技术交流群, 更有每月大咖直播分享、真实项目需求对接、干货资讯汇总,行业技术交流, 一起来让思想之光照的更远吧~

Kaggle实战目标检测奇淫技巧合集

△长按关注极市平台

觉得有用麻烦给个在看啦~    Kaggle实战目标检测奇淫技巧合集


以上所述就是小编给大家介绍的《Kaggle实战目标检测奇淫技巧合集》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

自制编译器

自制编译器

[日] 青木峰郎 / 严圣逸、绝云 / 人民邮电出版社 / 2016-6 / 99.00元

本书将带领读者从头开始制作一门语言的编译器。笔者特意为本书设计了CЬ语言,CЬ可以说是C语言的子集,实现了包括指针运算等在内的C语言的主要部分。本书所实现的编译器就是C Ь语言的编译器, 是实实在在的编译器,而非有诸多限制的玩具。另外,除编译器之外,本书对以编译器为中心的编程语言的运行环境,即编译器、汇编器、链接器、硬件、运行时环境等都有所提及,介绍了程序运行的所有环节。一起来看看 《自制编译器》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具