yolov5的head 的每层中分别为一个分支,同时预测3个内容:检测框质量( 1 是否为目标 ∗ i o u p r e d , l a b e l 1_{是否为目标}*iou_{pred,label} 1是否为目标∗ioupred,label)、类别的onehot、box的xywh。
与yolov5不同,yolov8的目标检测解耦了目标框和类别的预测,每层有两个分支,分别预测:类别的 o n e h o t ∗ i o u p r e d , l a b e l onehot*iou_{pred,label} onehot∗ioupred,label、box的xywh。
GFL工作解决:分类IoU联合表示
分类onehot向量的标签 在真实类别位置上的是其相应的定位质量(预测box与标签box的iou)。也就是:类别的 o n e h o t ∗ i o u p r e d , l a b e l onehot*iou_{pred,label} onehot∗ioupred,label。
训练时和测试时使用相同的规则,它消除了训练-测试的不一致性,并使定位质量和分类之间具有最强的相关性。
GFL工作:
对于边界框表示,直接学习box位置上的离散概率分布,而不引入任何其他更强的先验(比如统计出来的anchor)。因此,我们可以获得更可靠和准确的边界框估计,同时了解它们的各种潜在分布。
给定标签y的范围为 y 0 ≤ y ≤ y n , n ∈ N + y_0≤y≤y_n,n∈N^+ y0≤y≤yn,n∈N+,我们可以从模型中得到估计值 y ^ \hat{y} y^, 也满足 y 0 ≤ y ^ ≤ y n y_0≤\hat{y}≤y_n y0≤y^≤yn: y ^ = ∫ − ∞ + ∞ P ( x ) x d x = ∫ y 0 y n P ( x ) x d x \hat{y}=\int_{-\infty }^{+\infty }P(x)xdx=\int_{y_0}^{y_n}P(x)xdx y^=∫−∞+∞P(x)xdx=∫y0ynP(x)xdx为了与卷积神经网络保持一致,我们将连续域上的积分转换为离散表示,从离散范围[y0,yn]到一个集合 { y 0 , y 1 , . . . , y i , y i + 1 . . . , y n − 1 , y n } \{y0,y1,...,y_i,y_{i+1}...,y_{n−1},y_n\} {y0,y1,...,yi,yi+1...,yn−1,yn},其间隔∆=1。因此,给定离散分布性质 ∑ i = 0 n P ( y i ) = 1 \sum_{i=0}^{n}P(y_i)=1 ∑i=0nP(yi)=1,估计的回归值 y ^ \hat{y} y^可以表示为: y ^ = ∑ i = 0 n P ( y i ) y i \hat{y}=\sum_{i=0}^{n}P(y_i)y_i y^=i=0∑nP(yi)yi
尝试多种分布,最终发现下图第三种效果最好
举例子:
左边为已有工作,右边为GFL,针对分类项目可称为DFL
算法具体实现:
主要的公式为: ∑ i = 0 n P ( y i ) = 1 \sum_{i=0}^{n}P(y_i)=1 ∑i=0nP(yi)=1、 y ^ = ∑ i = 0 n P ( y i ) y i \hat{y}=\sum_{i=0}^{n}P(y_i)y_i y^=∑i=0nP(yi)yi。然后我们仅使用边界的浮点型位置,使用项链的两个整形表达。
假设第三个输出层的尺寸上的标签(6.25, 4.75, 18.375, 12.875),此时框的中心设为(11,9),左边框距离anchor为5.75= 11-6.25。则用长度为16的向量表示该距离 d l d_l dl:[0,0,0,0,0.25, 0.75,0,0,0,0, 0,0,0,0,0, 0]。该向量满足内容为: ∑ i n d e x ∗ v a l u e = 5.75 \sum index*value=5.75 ∑index∗value=5.75, ∑ v a l u e = 1 \sum value=1 ∑value=1。
计算box在每一层的每个grid ceil上的iou、对齐衡量指标(匹配得分)。 a l i g n _ m e t r i c = s α ∗ u β align\_metric =s^{\alpha }*u^{\beta} align_metric=sα∗uβ 其中 s 和 u 分别表示分类得分和IoU,α 和 β 是权重系数用来控制两个任务对匹配得分的影响大小
我们使用 ℓ ( x , y ) \ell(x,y) ℓ(x,y)来表示损失函数,则有 ℓ ( x , y ) = L = { l 1 , ... , l N } ⊤ \ell(x, y) = L = \{l_1,\dots,l_N\}^\top ℓ(x,y)=L={l1,...,lN}⊤其中【N】batch、【x】input(在使用中一般为网络输出的内容)、【y】target、【 x n , y n x_{n,y_n} xn,yn】表示对应target那一类的概率。
nn.NLLLoss():
l n = − w y n x n , y n l_n = - w_{y_n} x_{n,y_n} ln=−wynxn,yn
nn.BCELoss中:
l n = − w n [ y n ⋅ log ( x n ) + ( 1 − y n ) ⋅ log ( 1 − x n ) ] l_n = - w_n \left[ y_n \cdot \log (x_n) + (1 - y_n) \cdot \log (1 - x_n) \right] ln=−wn[yn⋅log(xn)+(1−yn)⋅log(1−xn)]
nn.BCEWithLogitsLoss = sigmoid + BCELoss
l n = − w n [ y n ⋅ log 1 1 + exp ( − x n ) + ( 1 − y n ) ⋅ log ( 1 − 1 1 + exp ( − x n ) ) ] l_n = - w_n \left[ y_n \cdot \log \frac{1}{1+\exp(-x_n)} + (1 - y_n) \cdot \log (1 - \frac{1}{1+\exp(-x_n)}) \right] ln=−wn[yn⋅log1+exp(−xn)1+(1−yn)⋅log(1−1+exp(−xn)1)]
CrossEntropyLoss = softmax + log + NLLloss
l n = − ∑ c = 1 C w c log exp ( x n , c ) exp ( ∑ i = 1 C x n , i ) y n , c l_n = - \sum_{c=1}^C w_c \log \frac{\exp(x_{n,c})}{\exp(\sum_{i=1}^C x_{n,i})} y_{n,c} ln=−c=1∑Cwclogexp(∑i=1Cxn,i)exp(xn,c)yn,c
N L L ( l o g ( s o f t m a x ( i n p u t ) ) , t a r g e t ) = − Σ i = 1 n O n e H o t ( t a r g e t ) i × l o g ( s o f t m a x ( i n p u t ) i ) ( i n p u t ∈ R m × n ) \large \mathbf{NLL(log(softmax(input)),target) = -\Sigma_{i=1}^n OneHot(target)_i\times log(softmax(input)_i)} (input∈Rm×n) NLL(log(softmax(input)),target)=−Σi=1nOneHot(target)i×log(softmax(input)i)(input∈Rm×n)
Distribution Focal Loss (DFL):使用向量表达边界与基准点的距离,然后结合softmax交叉熵计算得DFL项的loss
将边界距离基准点的距离记为y,则可将基准点转换为(tl, tr),两者对应的权重为(wl, wr)。y.shape = tl.shape = tr.shape= [batch, n, 4]。
tl.view(-1).shape = tr.view(-1).shape = [batc*n*4](假设左边界距离y=5.6,则 t l = 5 tl=5 tl=5, t r = 6 tr=6 tr=6, t l = 0.4 tl=0.4 tl=0.4, w r = 0.6 wr=0.6 wr=0.6)
此时网络输出的边界为pred_dist,pred_dist.shape=[batc*n*4,16]。则损失函数如下,:
【gridceil中目标的mask的计算】
1 通过mask_coef 和 Proto的线性叠加求出mask,其中 n 为 第n个检出结果: m a s k n = ∑ i = 0 32 m a s k _ c o e f i ∗ P r o t o i mask_n = \sum_{i=0}^{32}mask\coef{i}*Proto_{i} maskn=i=0∑32mask_coefi∗Protoi2 仅保留该gridceil检测出的box内的mask,然后再对mask框内的mask的每个像素进行阈值过滤(工程中阈值设为0.5),即得到该目标的最终的mask。
3.3 mask的损失函数
网络的输出经过 3.2 章节的处理后,得到解析后的mask信息
训练时,mask与标签进行计算损失函数。也就是并不会对 Proto 和 mask_coef 直接进行监督;仅对每个box内有效的处理后的mask做损失函数的计算。