最近看看这个古早的目标检测网络,看了好多文章,感觉对损失函数的部分讲得都是不很清楚得样子,所以自己捋一下。
首先,SSD 得损失函数由两部分得加权和,一部分是定位损失 L l o c L_{loc} Lloc,另一部分是分类置信率损失 L c o n f L_{conf} Lconf。公式一般写成: 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_{conf}(x, c) + \alpha L_{loc}(x, l, g) \right) L(x,c,l,g)=N1(Lconf(x,c)+αLloc(x,l,g))总结来说,定位损失 L l o c L_{loc} Lloc 是使用 smooth L1 loss 来计算的,而分类置信率损失 L c o n f L_{conf} Lconf 是通过 softmax loss 来计算的。
接下来就分开讲讲两部分,首先是定位损失 L l o c L_{loc} Lloc, 它的公式可以写成: L l o c ( x , l , g ) = ∑ i ∈ P o s N ∑ m ∈ { c x , c y , w , h } x i j p ⋅ s m o o t h L 1 ( l i m − g ^ j m ) L_{loc}(x, l, g) = \sum_{i \in Pos}^{N} \sum_{m \in \left\{ cx, cy, w, h \right\}} x_{ij}^p \cdot \mathbf{smooth_{L1}}(l_i^m - \hat{g}_j^m) Lloc(x,l,g)=i∈Pos∑Nm∈{cx,cy,w,h}∑xijp⋅smoothL1(lim−g^jm)下昂西介绍一下里面的各种参数的含义:
回到前面提到的偏移值,如果 default box i i i 的位置参数是 { d i c x , d i c y , d i w , d i h } \{ d_i^{cx}, d_i^{cy}, d_i^{w}, d_i^{h} \} {dicx,dicy,diw,dih},gt box j j j 的位置参数是 { g j c x , g j c y , g j w , g j h } \{ g_j^{cx}, g_j^{cy}, g_j^{w}, g_j^{h} \} {gjcx,gjcy,gjw,gjh},我们就可以算出真实值对应的偏移量 { g ^ j c x , g ^ j c y , g ^ j w , g ^ j h } \{ \hat{g}_j^{cx}, \hat{g}_j^{cy}, \hat{g}_j^{w}, \hat{g}_j^{h} \} {g^jcx,g^jcy,g^jw,g^jh}:
g ^ j c x = ( g j c x − d i c x ) d i w g ^ j w = log ( g j w d i w ) g ^ j c y = ( g j c y − d i c y ) d i h g ^ j h = log ( g j h d i h ) \begin{align*} \hat{g}_j^{cx} = \frac{(g_j^{cx} - d_i^{cx})}{d_i^w} & \space\space\space\space\space\space\space\space\space \hat{g}_j^{w} = \log\left( \frac{g_j^w}{d_i^w} \right)\\ \hat{g}_j^{cy} =\frac{ (g_j^{cy} - d_i^{cy})}{d_i^h} & \space\space\space\space\space\space\space\space\space \hat{g}_j^{h} = \log\left( \frac{g_j^h}{d_i^h} \right) \end{align*} g^jcx=diw(gjcx−dicx)g^jcy=dih(gjcy−dicy) g^jw=log(diwgjw) g^jh=log(dihgjh)同理,我们也可以通过预测得到的 bounding box 参数 { b i c x , b i c y , b i w , b i h } \{b_i^{cx}, b_i^{cy}, b_i^{w}, b_i^{h} \} {bicx,bicy,biw,bih} ,来计算得到 bounding box 的偏移量,也就是预测值 l l l。 l i c x = ( b i c x − d i c x ) d i w l i w = log ( b i w d i w ) l i c y = ( b i c y − d i c y ) d i h l i h = log ( b i h d i h ) \begin{align*} l_i^{cx} = \frac{(b_i^{cx} - d_i^{cx})}{d_i^w} & \space\space\space\space\space\space\space\space\space l_i^{w} = \log\left( \frac{b_i^w}{d_i^w} \right)\\ l_i^{cy} =\frac{ (b_i^{cy} - d_i^{cy})}{d_i^h} & \space\space\space\space\space\space\space\space\space l_i^{h} = \log\left( \frac{b_i^h}{d_i^h} \right) \end{align*} licx=diw(bicx−dicx)licy=dih(bicy−dicy) liw=log(diwbiw) lih=log(dihbih)
中心点的偏移量计算是很好理解的,为什么宽高的偏移量要用 log 函数来算呢?
SSD 是用到 smooth L1 loss 来计算真实值与预测值之间的差异: s m o o t h L 1 ( x ) = { 0.5 x 2 if ∣ x ∣ < 1 ∣ x ∣ − 0.5 otherwise \mathbf{smooth_{L1}}(x) =\begin{cases} 0.5x^2 & \text{ if } |x|< 1 \\ |x| -0.5 & \text{ otherwise } \end{cases} smoothL1(x)={0.5x2∣x∣−0.5 if ∣x∣<1 otherwise
这篇文章我觉得解释得挺清晰的,比较了 L1 loss, L2 loss 和 smooth L1 loss 三者之间的优劣。也提到了 loc loss 的演进。
bounding box 回归损失函数,也就是用于定位边界框的损失函数,其演进线路如下:
我记得 YOLOv1 的损失函数,在计算位置损失的时候,还是使用的欧式距离,也就是所谓的 L2 loss。
L1 loss 是求两个数之间的绝对值距离,导数是常数(小于 0 则为 -1,大于等于 0 则为 1),在零点处是不平滑的;
L2 loss 是两个数之间差的平方,导数是 2 x 2x 2x(也可以看出,受到 x x x 的影响很大),但是在零点处是平滑的。多个 L2 loss 求和再平均也叫做 MSE loss (Mean Square Error)。
而我们的主角 smooth L1 loss,如名字所见,是平滑版的 L1 loss,导数为: d s m o o t h L 1 ( x ) d x = { x if ∣ x ∣ < 1 ± 1 otherwise \frac{ \mathrm{d} \space \mathbf{smooth_{L1}}(x)}{\mathrm{d}x} =\begin{cases} x & \text{ if } |x|< 1 \\ \pm1 & \text{ otherwise } \end{cases} dxd smoothL1(x)={x±1 if ∣x∣<1 otherwise 在零点附近都是平滑的,而且在其它区间都是常数,也不会出现 L2 loss 随着 x x x 的增大而在损失函数中占据主导地位。
下面就讲一下分类的置信率损失 L c o n f L_{conf} Lconf,完整的公式如下: 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 c ^ i 0 where c ^ i p = exp ( c i p ) ∑ p exp ( c i p ) L_{conf}(x, c) = - \sum_{i \in Pos}^N x_{ij}^p\log{\hat{c}_i^p} - \sum_{i\in Neg} \log{\hat{c}_i^0} \space\space\space\space \text{where} \space\space\space\space \hat{c}_i^p=\frac{\exp{(c_i^p)}}{\sum_p \exp{(c_i^p)}} Lconf(x,c)=−i∈Pos∑Nxijplogc^ip−i∈Neg∑logc^i0 where c^ip=∑pexp(cip)exp(cip),从公式的形态,可以看出来是二元交叉熵。没错,其实 softmax loss 就相当于交叉熵和 softmax 的组合,先看看最后的 softmax 公式: c ^ i p = exp ( c i p ) ∑ p exp ( c i p ) \hat{c}_i^p=\frac{\exp{(c_i^p)}}{\sum_p \exp{(c_i^p)}} c^ip=∑pexp(cip)exp(cip)
然后就是主公式的各个参数的具体含义:
其实这个公式也没什么难理解的。
大致就是这么多了,如果大家有什么不清楚的地方或者是文章哪里写错了,欢迎评论留言。