yolo系列之yolo v3【深度解析】——讲的挺好,原作者厉害的

版权申明:转载和引用图片,都必须经过书面同意。获得留言同意即可
本文使用图片多为本人所画,需要高清图片可以留言联系我,先点赞后取图
这篇博文比较推荐的yolo v3代码是qwe的keras版本,复现比较容易,代码相对来说比较容易理解。同学们可以结合代码和博文共同理解v3的精髓。
github地址:https://github.com/qqwweee/keras-yolo3


前言

前言就是唠唠嗑,想直接看干货可以跳过前言,直接看Yolo v3。
yolo_v3是我最近一段时间主攻的算法,写下博客,以作分享交流。
看过yolov3论文的应该都知道,这篇论文写得很随意,很多亮点都被作者都是草草描述。很多骚年入手yolo算法都是从v3才开始,这是不可能掌握yolo精髓的,因为v3很多东西是保留v2甚至v1的东西,而且v3的论文写得很随心。想深入了解yolo_v3算法,是有必要先了解v1和v2的。以下是我关于v1和v2算法解析所写的文章:
v1算法解析:《yolo系列之yolo v1
v2算法解析:《yolo系列之yolo v2
yolo_v3作为yolo系列目前最新的算法,对之前的算法既有保留又有改进。先分析一下yolo_v3上保留的东西:

  1. “分而治之”,从yolo_v1开始,yolo算法就是通过划分单元格来做检测,只是划分的数量不一样。
  2. 采用"leaky ReLU"作为激活函数。
  3. 端到端进行训练。一个loss function搞定训练,只需关注输入端和输出端。
  4. 从yolo_v2开始,yolo就用batch normalization作为正则化、加速收敛和避免过拟合的方法,把BN层和leaky relu层接到每一层卷积层之后。
  5. 多尺度训练。在速度和准确率之间tradeoff。想速度快点,可以牺牲准确率;想准确率高点儿,可以牺牲一点速度。

yolo每一代的提升很大一部分决定于backbone网络的提升,从v2的darknet-19到v3的darknet-53。yolo_v3还提供替换backbone——tiny darknet。要想性能牛叉,backbone可以用Darknet-53,要想轻量高速,可以用tiny-darknet。总之,yolo就是天生“灵活”,所以特别适合作为工程算法。
当然,yolo_v3在之前的算法上保留的点不可能只有上述几点。由于本文章主要针对yolo_v3进行剖析,不便跑题,下面切入正题。


YOLO v3

网上关于yolo v3算法分析的文章一大堆,但大部分看着都不爽,为什么呢?因为他们没有这个玩意儿:

图1. yolo_v3结构图
yolo系列里面,作者只在v1的论文里给出了结构图,而v2和v3的论文里都没有结构图,这使得读者对后两代yolo结构的理解变得比较难。but,对于yolo学习者来说,脑子里没有一个清晰的结构图,就别说自己懂yolo了。上图是我根据官方代码和官方论文以及模型结构可视化工具等经过好几个小时画出来的,修订过几个版本。所以, 上图的准确性是可以保证的

这里推荐的模型结构可视化工具是Netron
netron方便好用,可以直观看到yolo_v3的实际计算结构,精细到卷积层。But,要进一步在人性化的角度分析v3的结构图,还需要结合论文和代码。对此,我是下了不少功夫。
上图表示了yolo_v3整个yolo_body的结构,没有包括把输出解析整理成咱要的[box, class, score]。对于把输出张量包装成[box, class, score]那种形式,还需要写一些脚本,但这已经在神经网络结构之外了(我后面会详细解释这波操作)。
为了让yolo_v3结构图更好理解,我对图1做一些补充解释:
DBL: 如图1左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+BN+Leaky relu。对于v3来说,BN和leaky relu已经是和卷积层不可分离的部分了(最后一层卷积除外),共同构成了最小组件。
resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。这是yolo_v3的大组件,yolo_v3开始借鉴了ResNet的残差结构,使用这种结构可以让网络结构更深(从v2的darknet-19上升到v3的darknet-53,前者没有残差结构)。对于res_block的解释,可以在图1的右下角直观看到,其基本组件也是DBL。
concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。

我们可以借鉴netron来分析网络层,整个yolo_v3_body包含252层,组成如下:
layers

表0. yolo_v3_layers
根据表0可以得出,对于代码层面的layers数量一共有252层,包括add层23层(主要用于res_block的构成,每个res_unit需要一个add层,一共有1+2+8+8+4=23层)。除此之外,BN层和LeakyReLU层数量完全一样(72层),在网络结构中的表现为: 每一层BN后面都会接一层LeakyReLU。卷积层一共有75层,其中有72层后面都会接BN+LeakyReLU的组合构成基本组件DBL。看结构图,可以发现上采样和concat都有2次,和表格分析中对应上。每个res_block都会用上一个零填充,一共有5个res_block。

1. backbone

整个v3结构里面,是没有池化层和全连接层的。前向传播过程中,张量的尺寸变换是通过改变卷积核的步长来实现的,比如stride=(2, 2),这就等于将图像边长缩小了一半(即面积缩小到原来的1/4)。在yolo_v2中,要经历5次缩小,会将特征图缩小到原输入尺寸的 1 / 251 / 251 / 2 5 1/251/25 1/2^5 1/251/251/25to),然后通过公式1计算出绝对的(x, y, w, h, c)。
logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。作者在论文种的描述如下:

If the bounding box prior is not the best but does overlap a ground truth object by more than some threshold we ignore the prediction, following[17]. We use the threshold of 0.5. Unlike [17] our system only assigns one bounding box prior for each ground truth object.

如果模板框不是最佳的即使它超过我们设定的阈值,我们还是不会对它进行predict。
不同于faster R-CNN的是,yolo_v3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模。
疑问解答和说明:

在评论里有同学问我关于输出的问题,看来我在这里没有说的很清楚。了解v3输出的输出是至关重要的。

第一点, 9个anchor会被三个输出张量平分的。根据大中小三种size各自取自己的anchor。

第二点,每个输出y在每个自己的网格都会输出3个预测框,这3个框是9除以3得到的,这是作者设置
的,我们可以从输出张量的维度来看,13x13x255。255是怎么来的呢,3*(5+80)。80表示80个种类,5表
示位置信息和置信度,3表示要输出3个prediction。在代码上来看,3*(5+80)中的3是直接由
num_anchors//3得到的。

第三点,作者使用了logistic回归来对每个anchor包围的内容进行了一个目标性评分(objectness score)。
根据目标性评分来选择anchor prior进行predict,而不是所有anchor prior都会有输出。

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

loss function

对掌握Yolo来讲,loss function不可谓不重要。在v3的论文里没有明确提所用的损失函数,确切地说,yolo系列论文里面只有yolo v1明确提了损失函数的公式。对于yolo这样一种讨喜的目标检测算法,就连损失函数都非常讨喜。在v1中使用了一种叫sum-square error的损失计算方法,就是简单的差方相加而已。想详细了解的可以看我关于v1解释的博文。我们知道,在目标检测任务里,有几个关键信息是需要确定的: ( x , y ) , ( w , h ) , c l a s s , c o n f i d e n c e ( x , y ) , ( w , h ) , c l a s s , c o n f i d e n c e ( x , y ) , ( w , h ) , c l a s s , c o n f i d e n c e (x,y),(w,h),class,confidence(x,y),(w,h),class,confidence (x, y), (w, h), class, confidence (x,y),(w,h),class,confidence(x,y),(w,h),class,confidence(x,y),(w,h),class,confidence(x,y),(w,h),class,confidence
根据关键信息的特点可以分为上述四类,损失函数应该由各自特点确定。最后加到一起就可以组成最终的loss_function了,也就是一个loss_function搞定端到端的训练。可以从代码分析出v3的损失函数,同样也是对以上四类,不过相比于v1中简单的总方误差,还是有一些调整的:

xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy, raw_pred[..., 0:2],
                                                                       from_logits=True)
wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh - raw_pred[..., 2:4])
confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \
                          (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5],
                                                                    from_logits=True) * ignore_mask
class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[..., 5:], from_logits=True)

xy_loss = K.sum(xy_loss) / mf
wh_loss = K.sum(wh_loss) / mf
confidence_loss = K.sum(confidence_loss) / mf
class_loss = K.sum(class_loss) / mf
loss += xy_loss + wh_loss + confidence_loss + class_loss

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

以上是一段keras框架描述的yolo v3 的loss_function代码。忽略恒定系数不看,可以从上述代码看出:除了w, h的损失函数依然采用总方误差之外,其他部分的损失函数用的是二值交叉熵。最后加到一起。那么这个binary_crossentropy又是个什么玩意儿呢?就是一个最简单的交叉熵而已,一般用于二分类,这里的两种二分类类别可以理解为"对和不对"这两种。关于binary_crossentropy的公式详情可参考博文《常见的损失函数》。


总结

v3毫无疑问现在成为了工程界首选的检测算法之一了,结构清晰,实时性好。这是我十分安利的目标检测算法,更值得赞扬的是,yolo_v3给了近乎白痴的复现教程,这种气量在顶层算法研究者中并不常见。你可以很快的用上v3,但你不能很快地懂v3,我花了近一个月的时间才对v3有一个清晰的了解(可能是我悟性不够哈哈哈)。在算法学习的过程中,去一些浮躁,好好理解算法比只会用算法难得很多。

                                </div>
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值