既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
因此,对于每个feature map cell而言,一共有6种default box。
可以看出这种default box在不同的feature层有不同的scale,在同一个feature层又有不同的aspect ratio,因此基本上可以覆盖输入图像中的各种形状和大小的object!
(训练自己的样本的时候可以在FindMatch()之后检查是否能覆盖了所有的 ground truth box)
将prior box和 grount truth box 按照IOU(JaccardOverlap)进行匹配,匹配成功则这个prior box就是positive example(正样本),如果匹配不上,就是negative example(负样本),显然这样产生的负样本的数量要远远多于正样本。这里将前向loss进行排序,选择最高的num_sel个prior box序号集合 D。那么如果Match成功后的正样本序号集合P。那么最后正样本集为 P - Dcap{P},负样本集为 D - Dcap{P}。同时可以通过规范num_sel的数量(是正样本数量的三倍)来控制使得最后正、负样本的比例在 1:3 左右。
正负样本获得
- 正样本获得
已经确定 default box,结合 ground truth,下一步要将 default box 匹配到 ground truth 上,从 groudtruth box 出发给每个 groudtruth box 找到了最近(IOU最大)的 default box 放入 候选正样本集。然后再从 default box 出发为 default box 集中寻找与 groundtruth box 满足 IOU>0.5 的的default box放入候选正样本集。
2. 负样本获得(这是一个难例挖掘的过程)
在生成 prior boxes 之后,会产生很多个符合 ground truth box 的 positive boxes(候选正样本集),但同时,不符合 ground truth boxes 也很多,而且这个 negative boxes(候选负样本集),远多于 positive boxes。这会造成 negative boxes、positive boxes 之间的不均衡。训练时难以收敛。
将每一个GT上对应prior boxes的分类loss 进行排序。
对于候选正样本集:选择loss最高的m个 prior box 与候选正样本集匹配 (box 索引同时存在于这两个集合里则匹配成功),匹配不成功则删除这个正样本(因为这个正样本loss太低(因为符合标准所以损失小(y, y”)),易被识别,所以不在难例里,已经很接近 ground truth box 了,不需要再训练);
对于候选负样本集:选择损失最高的m个 prior box 与候选负样本集匹配,匹配成功的则留下来作为最后的负样本,不成功剔除出候选负样本,因为他们loss不够大,易被识别为背景,训练起来没难度没提升空间。
- 举例:假设在这 8732 个 default box 里,经过 FindMatches 后得到候选正样本 P 个,候选负样本那就有 8732−P个。将 prior box 的 prediction loss 按照从大到小顺序排列后选择最高的 M个 prior box。如果这 P 个候选正样本里有 a 个 box 不在这 M 个 prior box 里,将这 a个 box 从候选正样本集中踢出去。如果这 8732−P个候选负样本集中有 b个在这 M 个 prior box,则将这b个候选负样本作为正式负样本。即删除易识别的正样本,同时留下典型的负样本,组成1:3的prior boxes样本集合。SSD 算法中通过这种方式来保证 positives、negatives 的比例。
Hard example mining
example mining 是选择出特定样本来计算损失函数;从实际问题出发 hard example 应该就是指定位较困难或分类较困难或者两者都困难的候选框。
hard negative example 或 Hard positive example 的定义需要首先确定某个候选框是 negative example 还是 positive example。比如 SSD 中将与任意 gt_bbox 的 IOU 超过给定阈值 overlap_threshold(multibox_loss_param 中的一个字段,SSD 默认为 0.5)的当作正样本,即前景类别为正样本,背景类别为负样本。比如,极端的例子,当图像中没有 gt_bbox 时,那么所有的 default bboxes 都是 negative example。
SSD 中 negative mining 只计算分类损失而不计算定位损失,而 hard example mining 对分类损失和定位损失都进行计算。
SSD 的 negative mining 的过程为:
- 生成default bboxes,每个检测器对应特征图生成的default boxes数目为n×n×6或n×n×4;
- 匹配default boxes,将每个 default box 与 ground truth 匹配,保证每个ground truth 都能对应多个default boxes,避免漏检;
- 衡量default boxes,当第 i 个 default box 被匹配到第 j 个 gt_bbox,那么计算其属于背景类别的 softmax loss 或 cross entropy loss 值;
S
i
=
e
V
i
∑
i
C
e
V
i
S_{i}=\frac{e{V_{i}}}{\sum_{i}{C} e^{V_{i}}}
Si=∑iCeVieVi
其中
V
i
V_i
Vi是分类器前级输出单元的输出,i表示类别索引,总的类别个数是C,
S
i
S_i
Si表示当前元素的指数与所有元素指数之和的比值.然后Softmax将多分类的输出转化为相对概率。
4. 筛选default boxes, 计算完所有default boxes 的分类 loss后,按照 loss 排序,选择 loss 较大且与任意 gt_bbox 之间的 iou 小于 阈值neg_overlap 的样本中的前 3*num_positive 个负样本(保证留下的负样本“够坏”,同时保证1:3的正负比例)。
最后,这正负比为1:3的部分default boxes就是筛选全体default box后剩下的prior boxes,用这些prior box作为参考,对所有预测框其进行分类和回归,进行反向传播更新网络参数,即训练。
损失函数
(1) 每一个 prior box 经过Jaccard系数计算和真实框的相似度。
(2) 阈值只有大于 0.5 的才可以列为候选名单;假设选择出来的是N个匹配度高于百分之五十的框。
(3) 我们令 i 表示第 i 个默认框,j 表示第 j 个真实框,p表示第p个类。那么xi,jp 表示 第 i 个 prior box 与 类别 p 的 第 j 个 ground truth box 相匹配的Jaccard系数,若不匹配的话,则xi,jp=0 。
(4)总的目标损失函数(objective loss function)为 localization loss(loc) 与 confidence loss(conf) 的加权求和。
L
(
x
,
c
,
l
,
g
)
=
1
N
(
L
c
o
n
f
(
x
,
c
)
)
α
L
l
o
c
(
x
,
l
,
g
)
L(x, c, l, g)=\frac{1}{N}\left(L_{c o n f}(x, c)\right)+\alpha L_{l o c}(x, l, g)
L(x,c,l,g)=N1(Lconf(x,c))+αLloc(x,l,g)
L
l
o
c
(
x
,
l
,
g
)
=
∑
i
∈
Pos
N
∑
m
∈
{
c
x
,
c
y
,
w
,
h
}
x
i
j
k
s
smooth
L
1
(
l
i
m
−
g
^
j
m
)
L_{l o c}(x, l, g)=\sum_{i \in \text {Pos}}^{N} \sum_{m \in{c x, c y, w, h}} x_{i j}^{k} s \operatorname{smooth}_{L 1}\left(l_{i}{m}-\hat{g}_{j}{m}\right)
Lloc(x,l,g)=i∈Pos∑Nm∈{cx,cy,w,h}∑xijkssmoothL1(lim−g^jm)
g
^
j
c
x
=
(
g
j
c
x
−
d
i
c
x
)
/
d
i
w
g
^
j
c
y
=
(
g
j
c
y
−
d
i
c
y
)
/
d
i
h
\hat{g}_{j}^{c x}=\left(g_{j}^{c x}-d_{i}^{c x}\right) / d_{i}^{w} \quad \hat{g}_{j}^{c y}=\left(g_{j}^{c y}-d_{i}^{c y}\right) / d_{i}^{h}
gjcx=(gjcx−dicx)/diwgjcy=(gjcy−dicy)/dih
g
^
j
w
=
log
(
g
i
w
/
d
i
h
)
g
^
j
h
=
log
(
g
j
h
/
d
i
h
)
\hat{g}_{j}^{w}=\log \left(g_{i}^{w} / d_{i}^{h}\right) \quad \hat{g}_{j}^{h}=\log \left(g_{j}^{h} / d_{i}^{h}\right)
gjw=log(giw/dih)gjh=log(gjh/dih)
L
c
o
n
f
(
x
,
c
)
=
−
∑
i
∈
P
o
s
N
x
i
j
p
log
(
c
^
i
p
)
−
∑
i
∈
N
e
g
log
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
d_{i}^{h}\right) \quad \hat{g}_{j}^{h}=\log \left(g_{j}^{h} / d_{i}^{h}\right)
gjw=log(giw/dih)gjh=log(gjh/dih)
L
c
o
n
f
(
x
,
c
)
=
−
∑
i
∈
P
o
s
N
x
i
j
p
log
(
c
^
i
p
)
−
∑
i
∈
N
e
g
log
[外链图片转存中…(img-oA4H9hfc-1715843210229)]
[外链图片转存中…(img-LDKBNXIl-1715843210230)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新