RDSNet的一个亮点在于同一个网络同时学习目标检测和目标分割,这两个任务相互促进提升模型精度。RDSNet提出了双流结构,分别取学习目标尺度和像素尺度上的物体。同时两条流上的信息相互融合,相互促进各自的训练。object level为pixel level提供了实例信息,为pixel提供一些分割上的先验。pixel level为object level重新定义边框的定位,提升精度。

在这个结构中,来自两个流的信息是交替融合,即对象层的信息引入实例意识和翻译差异到像素级,像素级的信息-在对象级别细化对象的定位精度作为回报

简介

目标识别上,找出一个tight bounding box是非常具有挑战的,即要么无法全部选中目标,要么bounding 太大选中过多。

image-20200318110910599

一个主要的原因是我们在做边框回归的时候,由于逐点回归并不能直接感知整个对象,因此将这个问题转化为pixel wise更加合理,即根据mask的大小,找到一个最小的包围盒。

实例分割的目的是进一步预测除类别外的每个对象的每像素二值掩码。核心思想是:实例分割时,像素类别是具有实例感知的。如在MASK-RCNN中,mask是根据网络提取出来的单独的proposal来生成的,因此具有整个对象的感知。但是这种方法必须依赖于目标检测的结果。

通过上面的分析,这里两种任务时能够相互促进的,因此作者提出了RDSNet,一种互惠的目标检测方法和实例分割网络(RDSNet)来利用这两项任务之间的关系。

RDSNet利用双流结构,即对象流和像素流,同时这两条流的信息相互融合,具体来说,对象流集中在对象级别特征是一个回归的检测器,而像素流关注像素级特征,结构沿用FCN的结构,以保证高分辨率输出。

为了利用来自对象流的对象级提示,提出了一个相关模块和一个裁剪模块,该模块将实例感知和翻译方差特性引入到像素流,并产生实例感知的分割掩码。然后,提出了一种基于掩模的边界求精模块,以减小定位误差像素流,即基于实例掩码生成更精确的边界框。

RDSNet充分考虑了目标检测和实例分割任务之间的相互关系.与以往的方法相比,它有以下三个优点:1)由RDSNet生成的掩码对不同尺度的对象具有一致的高分辨率;2)由于具有巧妙的裁剪模块,掩码对检测结果的依赖性较小;3)更准确和更准确;更紧密的包围盒是用一种新的像素级公式得到的对象包围盒位置。

网络结构

image-20200318114954524

双流结构

RDSNet的核心是双流结构,即对象流和像素流。这两条流共用相同的FPN(Lin等人.2017a)主干,然后为每个相应的任务分离。这种平行结构支持对象级和像素级信息的分离以及不同任务的可变分辨率。

对象流。对象流侧重于对象级信息,包括对象类别,位置等。可有各种回归的检测器充当(Liu等)。此外,我们还添加了一个与分类和回归分支并行的新分支,以提取每个锚点(或位置)的对象特征。这条流负责产生检测结果,稍后将由像素级信息进一步提取信息(见SEC.3.3)。

像素流。像素流的重点是像素级信息,并遵循FCN(2015)的高分辨率输出设计。具体来说,每像素特征是在这个流中提取的,并且用于通过使用对象级信息生成实例掩码(参见SEC.3.2)。

对象感知:相关性模块

主要思路是将实例信息融合到像素上来,以便做分割处理:
$$
M_{o}=\operatorname{softmax}\left(\Psi(U) \star \phi\left(v_{o}\right)\right)
$$
其中 $v_0$ 表示从obejct stream上的特征,U表示来着像素流的特征,将两个特征映射之后,做一个卷积操作,然后在M0上计算一个pixelwise的交叉熵损失,作为最后loss的一部分。

其中U的维度为1xdxhxw,v的维度为2xdx1x1,其中2表示当前像素是属于前景还是背景。因此U与v做完卷积之后,得到的维度是2x1xwxh,即每一个位置上有两个值,表示前景和背景的概率。每一个anchor对应一个v,与U做完卷积之后计算softmax得到一个二值图。因此可以发现,网络检测出多少anchor,最终segmentation的时候,就会输出多少张二值图,理论上每一个二值图表示一个对象。

2xkxdx1x1 representation即表示anchor对象的深层含义。

翻译改变到翻译不变

由于上诉相关模块对每一个object生成的mask覆盖了整个图像,由于卷积操作产生了大量的噪声。我们使用一个裁剪模块来克服这个问题。可以利用物体的边框进行裁剪,边框以外的像素设置成背景,但是这种做法又会受到检测结果的影响,因此我们选择裁剪经过扩展后的边框,保证mask对box的依赖比较小。同时扩展后的边框引入了更多的背景,使得背景也容易被区分出来。需要注意的是,我们引入背景的时候也需要保持正负样本的平衡(1:1),可以使用背景像素的OHEM算法。

由mask得到精确边框

利用从对象流和像素流中获得的边界框和实例mask,得到每个对象的更精确的边界框。虽然回归边界框可能包含定位错误,但我们认为它们在一定程度上仍然为对象边界位置提供了合理的先验。因此,我们的损失联合目标检测和分割结果。

网络损失函数

最终的loss:
$$
L=L_{c l s}+\lambda_{r} L_{r e g}+\lambda_{m} L_{m a s k}
$$
即分类损失,边框回归损失,相关模块产生的mask损失。

代码阅读

数据的组织形式

GT中segmentation部分采用coco的标注格式,即ploygon多边形的轮廓坐标[x1,y1,x2,y2,x3,y3…]。

box部分则表明GT中的目标所在的外包围盒。

dataset部分: 数据输出为[img, gt_bboxes, gt_labels, gt_masks]

代码结构:

  • backbone: usually an FCN network to extract feature maps, e.g., ResNet, MobileNet.
  • neck: the component between backbones and heads, e.g., FPN, PAFPN.
  • head: the component for specific tasks, e.g., bbox prediction and mask prediction.
  • roi extractor: the part for extracting RoI features from feature maps, e.g., RoI Align.

评价指标

IoU:即预测的mask与GT的重叠程度
$$
I O U(A, B)=\frac{|A \cap B|}{|A \cup B|}
$$
dice:与IoU相似,也是用来评价与GT的重叠程度:
$$
\operatorname{dice}(A, B)=\frac{2|A \cap B|}{|A|+|B|}
$$
相同的结果比值上,dice的值要比IoU稍微大一点。

COCO数据集的验证方式得到的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.397
Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.603
Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.499
Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.034
Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.463
Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.000
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.443
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.465
Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.467
Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.135
Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.501
Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = -1.000

其中IoU表示阈值,用于区分正负样本,然后计算precision和recall,得到的结果如上。

下面是各个模型的指标,可以作为一个baseline,可以说明效果不错。

image-20200320153558364

但是这个结果仅仅只是检测的结果,过于segmentation部分的结果并没有。

这个需要我自己去写一个。

对于segmentation的指标有:

pa: 是标记正确的像素占总像素的比例

mpa:每个类别被正确分类像素的比例,之后求所有类的平均

mIU:在每个类上求IoU,再求平均

fwIU:根据每个类出现的频率为其设置权重,再算IoU

FCN模型的检测结果如下,可以做为一个baseline

image-20200320152311238

验证集574张图片,能够检测出人的图像有:384张

验证后指标分别如下:

pa: 0.9326967388628634

person pa: 0.948784433562702; ski pa 0.7863983575482737

person mIU: 0.8811813306596593; ski mIU 0.47062399967040647

人体倒立的效果不好:

目前有的数据增强操作有:resize:[(1333, 640), (1333, 800)],randomFilp(左右翻转),Normalize,Pad

增加上下翻转的操作,同时翻转mask和box。

检测人体的一些参数:

置信度threshold=0.3

4.5最新的segmentation结果:

  • 增加了人的上下翻转

  • 改变了mask和人的面积的占比的阈值

  • 使用了RDSNet原始的预训练模型

  • 先过滤掉skis的GT,用原始的模型跑了一版只有人的mask,然后再训练所有的数据

nums of all images:574 detect img: 574
pa: 0.9354692319143859
person pa: 0.952586679919327; ski pa 0.795659633538158
person mIU: 0.8703372762800548; ski mIU 0.4621799597472673

赅睦v3结果:

nums of all images:574 detect img: 315

pa: 0.9402883800000756 person pa: 0.9549458484555311;

ski pa 0.8145014928441581 person mIU: 0.8682211200110778

ski mIU 0.4661748785006413

4.3最新segmentation结果:

nums of all images:574 detect img: 233

pa: 0.9369132159512628

person pa: 0.9535568322424365; ski pa 0.7994298667822376

person mIU: 0.8703037390529358; ski mIU 0.4607294905584023

513张检测出来

pa: 0.931

person pa: 0.948; ski pa 0.786

person mIU: 0.881; ski mIU 0.450

最新的,雪板缺失的结果:

nums of all images:574 detect img: 492
pa: 0.9325332039535604
person pa: 0.952345728818519; ski pa 0.774363662229735
person mIU: 0.8692397985003847; ski mIU 0.46683807840731795

本周的工作

  1. 对视频进行mask抠像
  2. 将标注数据转化成80分类的数据格式,共8k张
  3. 训练了一版没有加入coco数据集80分类的结果
  4. 将coco加入数据集,重新训练新一版的结果

0413:将划水数据加入数据集中得到的结果,感觉还有提升空间,可以继续训练

nums of all images:574 detect img: 496
pa: 0.9343723520825538
person pa: 0.9539596612578186; ski pa 0.7762043705731111
person mIU: 0.8691335572039341; ski mIU 0.4734166211250842
122.55705881118774

0415:80分类的跳水 + 滑雪数据:

nums of all images:574 detect img: 500
pa: 0.9338427680139673
person pa: 0.9529509669453708; ski pa 0.7774459065324504
person mIU: 0.8697633935721094; ski mIU 0.4716099906503192
123.1501772403717

总数 det_img pa person pa person miu ski pa ski miu 备注
0420_epoch16 574 279 0.95 0.97 0.88 0.84 0.50 加入coco数据

修改的点

  1. 数据增强:加入forst,上下翻转,brightness(defocus)
  2. FL with distance aware

A distance-aware cross entropy loss

即: Class Weight based Dual Focal Loss

although FL proved to be better than CE and WCE to address both class imbalance and class weakness, it increases the weight factor on ‘positive hard’ classes {𝑃𝑖 ̂: 𝑃𝑖 = 1, 𝑃𝑖 ̂ ≪ 1}) only and remains blind to the ‘negative easy’

剪视频

滑雪视频:bFF_20191214095649.mp4

跳水场景

V1:

nums of all images:372 detect img: 109
pa: 0.8202673860246401
person pa: 0.8604234773163142; ski pa 0.4365939611642742
person mIU: 0.834689556354205; ski mIU 0.32204986948916425
57.603790283203125

v2:无

v3:

nums of all images:372 detect img: 234
pa: 0.8635791399587737
person pa: nan; ski pa 0.52861091026923
person mIU: 0.8660126998199129; ski mIU 0.37964839550921387
64.33940291404724

v4:(0413.epoch_47)

nums of all images:372 detect img: 240
pa: 0.8728082198181446
person pa: 0.9037850500010524; ski pa 0.5343325737147256
person mIU: 0.8766753717860475; ski mIU 0.3892417225535218
67.59345650672913

V5:(epoch_16)

nums of all images:372 detect img: 74
pa: 0.9405744365529746
person pa: 0.9630469046257544; ski pa nan
person mIU: 0.9072004643371733; ski mIU 0.0
62.072516441345215

  1. 将部分跳水数据转成2分类,80分类验证集
  2. 对历史模型重新测试在跳水上的效果
  3. 绘制mask可视化视频(跳水和滑雪融合)
  4. 训练加入coco的RDSNet,验证最新结果

RDSNet的loss修改

RDSNet目标检测上使用的loss是focal loss,在mask 分割上使用的loss是cross entropy loss。

mask分割的内部实现:

mmdet/models/mask_heads/rdsnet_mask_head.py:213行

1
2
3
4
5
6
7
	(Pdb) pred_mask.shape
torch.Size([34, 2, 248, 160])
(Pdb) gt_mask.shape
torch.Size([34, 248, 160])
最终通过下面函数进行计算:
input = log_softmax(input, 1)
ret = torch._C._nn.nll_loss2d(input, target, weight, _Reduction.get_enum(reduction), ignore_index)

V6 (epoch_37 0427)

滑雪:

nums of all images:574 detect img: 395
pa: 0.9525877472767361
person pa: 0.9645798724157836; ski pa 0.8437678375390546
person mIU: 0.8893634429910271; ski mIU 0.4647400425444946
110.54691290855408

跳水:

nums of all images:372 detect img: 143
pa: 0.9387247103765048
person pa: 0.9542593861783638; ski pa 0.7321668474084746
person mIU: 0.909753853880885; ski mIU 0.44296937228518907
61.86693835258484

dual focal loss训练5个epoch后的结构:

跳水:

nums of all images:372 detect img: 195
pa: 0.942374395615374
person pa: 0.9584690806034492; ski pa 0.7241165337826362
person mIU: 0.8722316754876035; ski mIU 0.47293200705732463
64.31871056556702

滑雪:

nums of all images:574 detect img: 433
pa: 0.9660662841297223
person pa: 0.9734102175290501; ski pa 0.865497049546744
person mIU: 0.8444838659179477; ski mIU 0.41508230594421563
108.87461352348328

dual focal loss without coco

跳水:

nums of all images:574 detect img: 478
pa: 0.9443598058031467
person pa: 0.9577760462895214; ski pa 0.8324571806551673
person mIU: 0.8813928476174313; ski mIU 0.46156182496159115
116.63049459457397

滑雪:

nums of all images:372 detect img: 186
pa: 0.8752277721197145
person pa: 0.897262192400029; ski pa 0.6044119935949241
person mIU: 0.8711407606062432; ski mIU 0.38455484339814283
63.10305881500244

训练80epoch的结果:

滑雪:

nums of all images:574 detect img: 480
pa: 0.9448030285036926
person pa: 0.9590008038256677; ski pa 0.8280578495166153
person mIU: 0.8797742794543877; ski mIU 0.4640084072051552
117.41836833953857

跳水:

nums of all images:372 detect img: 188
pa: 0.8714032581962176
person pa: 0.8949121343976324; ski pa 0.5869715304627966
person mIU: 0.8689041863792644; ski mIU 0.3728823778076807

  1. 测试加入coco数据下,dual focal loss的效果,训练了5个epoch
  2. 将coco数据集移除,训练dual focal loss 的RDSNet
  3. 阅读segmentation部分的loss,RDSNet原始版本使用的是交叉熵loss
  4. 后续版本希望修改这部分loss为dual focal loss

2分类dual loss:

滑雪:

nums of all images:574 detect img: 468
pa: 0.9398213765874458
person pa: 0.9551532269115653; ski pa 0.8188987123099618
person mIU: 0.8766970201077243; ski mIU 0.47674212496400986

跳水:

nums of all images:372 detect img: 275
pa: 0.9482054503366465
person pa: 0.9598653406334634; ski pa 0.7852411728484762
person mIU: 0.9124365370322647; ski mIU 0.4102839323682259

2 分类v96 0503

滑雪:

nums of all images:574 detect img: 475
pa: 0.939923169980097
person pa: 0.9567105804281405; ski pa 0.8082511329118433
person mIU: 0.8767730148660953; ski mIU 0.47880553997407566

跳水:

nums of all images:372 detect img: 291
pa: 0.9476719604689137
person pa: 0.96116073149258; ski pa 0.7693642239056024
person mIU: 0.9126262313523922; ski mIU 0.4118130800852414

加入随机对比度增强:(0503)

skiing:

nums of all images:574 detect img: 507
pa: 0.9365616582224128
person pa: 0.9557731597670968; ski pa 0.7875246119333108
person mIU: 0.8698177517484026; ski mIU 0.47908820398245655

跳水:

nums of all images:372 detect img: 304
pa: 0.9476233052691827
person pa: 0.9630547323478765; ski pa 0.7644954664819416
person mIU: 0.9158077226970566; ski mIU 0.44526721531789315

  1. 训练二分类的dual focal loss
  2. 数据增强部分加入随机对比度增强,测试得到结果如下:
  3. 颜色通道变换,透明度,颜色空间变换等,模型还在训练
  1. 讨论下一步的改进方向
  1. RDSNet/configs/rdsnet/ 中修改config,(35行左右)

原来:

1
2
3
4
5
6
loss_cls=dict(
type='FocalLoss',
use_sigmoid=True,
gamma=2.0,
alpha=0.25,
loss_weight=1.0),

修改成:

1
2
loss_cls=dict(
type='DualFocalLoss',),
  1. RDSNet/mmdet/models/losses/ 中替换__init__.py,添加dual_focal_loss.py
  1. 0506加入颜色空间变换,量度变换,随机crop之后结果不好:

nums of all images:574 detect img: 434
pa: 0.9284912894101659
person pa: 0.9347836581387167; ski pa 0.8339256079243513
person mIU: 0.8582783158839123; ski mIU 0.4214144635187835

nums of all images:372 detect img: 201
pa: 0.9282038176537211
person pa: 0.9157486699556354; ski pa 0.9054421235666925

person mIU: 0.8589043912125288; ski mIU 0.22410981963307305

  1. 协助解决新模型无法加载问题
  2. 绘制,分析数据mask,box检测的结果

ski检测不出来的情况有:

  • 反光严重,雪板和背景相互融合

  • ski仅仅露出一个侧边,雪板形状细长

  • 图片像素模糊