您的位置:网站首页 > 目标运动 > 正文

YOLO一种简易快捷的目标检测算法

类别:目标运动 日期:2018-8-1 7:12:45 人气: 来源:

  YOLO全称You Only Look Once,是一个十分容易构造目标检测算法,出自于CVPR2016关于目标检测的方向的一篇优秀论文(),本文会对YOLO的思进行总结并给出关键代码的分析,在介绍YOLO前,不妨先看看其所在的领域的发展历程。

  相对于传统的分类问题,目标检测显然更符合现实需求,因为往往现实中不可能在某一个场景只有一个物体(业务需求也很少会只要求分辨这是什么),但也因此目标检测的需求变得更为复杂,不仅仅要求detector能够检验出是什么物体,还的确定这个物体在图片哪里。

  总的来说,目标检测先是经历了最为简单而又的历程,这个过程高度的符合人类的直觉。简单点来说,既然要我要识别出目标在哪里,那我就将图片划分成一个个一个个小图片扔进detector,但detecror认为某样物体在这个小区域 上了,OK,那我们就认为这个物体在这个小图片上了。而这个思,正是比较早期的目标检测思,比如R-CNN。

  然后来的Fast R-CNN,Faster R-CNN虽有改进,比如不再是将图片一块块的传进CNN提取特征,而是整体放进CNN提取除 featuremap 然后再做进一步处理,但依旧是整体流程分为区域提取 和 目标分类 两部分(two-stage),这样做的一个特点是虽然精度是了,但速度上不去,于是以YOLO为主要代表的这种一步到位(one-stage)即 End To End 的目标算法应运而生了。

  细心的读者可能已经发现,是的,YOLO的名字You only look once正是自身特点的高度概括。

  YOLO的核心思想在于将目标检测作为回归问题解决 ,YOLO首先将图片划分成SxS个区域,注意这个区域的概念不同于上文提及将图片划分成N个区域扔进detector这里的区域不同。上文提及的区域是真的将图片进行剪裁,或者说把图片的某个局部的像素扔进detector,而这里的划分区域,只的是逻辑上的划分。

  为什么是逻辑上的划分呢?这体现再YOLO最后一层全连接层上,也就是YOLO针对每一幅图片做出的预测。

  其预测的向量是SxSx(B*5+C)长度的向量。其中S是划分的格子数,一般S=7,B是每个格子预测的边框数 ,一般B=2,C是跟你实际问题相关的类别数,但要注意的是这里你应该背景当作一个类别考虑进去。

  该网络结构包括 24 个卷积层,最后接 2 个全连接层。文章设计的网络借鉴 GoogleNet 的思想,在每个 1x1 的 归约层(Reduction layer,1x1的卷积 )之后再接一个 3∗3 的卷积层的结构替代 Inception结构。论文中还提到了 st 版本的 Yolo,只有 9 个卷积层,其他则保持一致。

  因为最后使用了全连接层,预测图片要和train的图片大小一致,而其他one-stage的算法,比如SSD,或者YOLO-V2则没有这个问题,但这个不在本文讨论范围内。

  其实网络架构总体保持一致即可,个人不照抄全部参数,还是需要根据你的实际任务或计算资源进行魔改,所以接下来重点会讲述训练的过程和损失函数的构建,其中也会给出MXNET版本的代码进行解释。文末会给出全部代码的开源地址。

  其中,每一个组成部分对整体的贡献度的误差是不同的,需要乘上一个权重进行调和。相对来说,目标检测的任务其实更在意误差,故误差的权重一般为5。在此,读者可能费解,为什么框的宽和高取的是根号,而非直接计算?

  这里额外多说一句,如果有打数据挖掘比赛经验的同学,可能会比较清楚一种数据处理的手段,当某些时候,会对某一特征进行数据变换,比如和 ,取 log 这些变换有一个特征,就是数值越大,惩罚越大(变换的幅度越大,比如4和4的平方,10到10的平方)。

  而在损失函数中应用这一方法,起到的作用则是使得小框产生的误差比大框的误差更为,其目的是为了解决对小物体的检测问题。但事实上,这样的设定只能缓解却没有最终解决这个问题。

  听上去很复杂,实际我们既然能获得预测框坐标,只要通过简单的换算,该比值实际能转换成面积的计算。而同样的,这里也有一个问题,我们感兴趣的物体,对于整体图片来说,毕竟庄巧涵献b门全套图属于小数。换言之,就是在SxS个格子里面,预测出来的框大多是无效的框,这些无效框的误差积累是会对损失函数产生影响,换句话说,我们只希望有物体的预测框有多准,而不在乎没有物体的框预测得有多差。因此,我们也需要对这些无效框的在损失函数上得贡献乘上一个权重,进行调整。

  关于分类误差,论文虽然是采用mse来衡量,但是否采用交叉熵来衡量更合理呢?对于分类问题,采用mse和交叉熵来衡量,又会产生什么问题?这个问题留给读者思考。

  说完了损失函数,下面来讲述如何使用MXNET来实现YOLO,同理的,YOLO的网络结构较为简单,你可以采用任何的框架搭出,如果像我一样只是为了演示demo,对网络结构可以修改一下,采取网络拓扑上比较简单的模型。

  同样的,目标检测常使用在ImageNet上预训练(pretrain)的模型 作为特征抽取器,同样,因为这里只是演示demo,同样也省略这一部分,只是重点讲损失函数的构造。

  而是将整体式子拆分成 W x loss来计算,这样在代码上,实现起来要方便得多,以下时loss函数的计算过程:

  可能会有童鞋好奇,为什么坐标误差是用预测值和label直接mse算呢,w和h不是应该要开根号吗?是的,但我们为了数值稳定,在人工构建label时就已经将wh以开根后的形式存储好了,这是因为,神经网络的输出在初始时,正负值时随机的,尽管在数学上的结果是虚数i,但在DL相关的框架,该操作会直接造成nan,造成损失函数无法优化,而且相应代码的书写更为复杂。而采取直接以取根号后的形式我们只要在获取输出时,再将wh求一个平方即可。

  另外要说的一点就是IOU误差,虽然很多文章都将这一点直接成为IOU误差,实际上计算时IOU误差和置信度的结合。

  置信度在label的表现形式时,这个地方有目标物体则为1,没有则是0,这样用mse优化后,输出值会在0~1附近,正好可以代表某个框是否框中物体的置信度。

  但为什么不直接 对置信度用mse呢,这同样是一个权重的调节的问题,但这里不能说我们就不care那些没有物体的框的值了,因为这里的值是置信度,如果我们任由其发展,万一没有物体的框的置信度比有框中物体的置信度还要高,那我们使用阈值过滤时,就可能出现问题了。只能说我们希望loss中更重视有框中物体的框的误差。

  这里补充另外一个知识点最大值 ,简单点来说,既然每个格子会生成B个框(一般B1)这样就有可能同时两个框都框中了物体,那么到底采用那个框作为预测结果呢?答案是采用IOU值高的那个框,而IOU值小的,就会不被重视而受到。

  在求出IOU后,我们求出每一个格子的框中的最大值,再使用equal操作,使得最大值为1,其余值为0再参与后面的运算即可。

  本文由 325游戏(m.325games.com)整理发布

关键词:目标检测代码
0
0
0
0
0
0
0
0
下一篇:没有资料

网友评论 ()条 查看

姓名: 验证码: 看不清楚,换一个

推荐文章更多

热门图文更多

最新文章更多

关于联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助

声明:网站数据来源于网络转载,不代表站长立场,如果侵犯了你的权益,请联系客服删除。

CopyRight 2010-2016 阿宝运动器材网- All Rights Reserved