YOLO_v1
目标检测算法可以分为两类:
- 一类是基于region proposal的R-CNN系列算法(R-CNN,Fast R-CNN, Faster R-CNN),它们是two-stage的。要先使用启发式方法(selective search)或者CNN网络(RPN)产生region proposal,然后再在region proposal上做分类与回归。精确度高,速度低。
- 另一类是YOLO,SSD这类one-stage算法,仅仅使用一个CNN网络直接预测不同目标的类别与位置。精确度低,速度快。
采用滑动窗口的目标检测算法思路很简单,将检测问题转化为了图像分类问题。原理是采用不同大小和比例(宽高比)的窗口在整张图片上按照一定步长进行华东,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测。缺点是不知道要检测的目标大小,所以要设置不同大小和比例的窗口去滑动,还要采取合适的步长,这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率。
如果用的是CNN分类器,滑动窗口非常耗时,使用全卷积方法,将网络中的卷积层代替全连接层。例如输入16x16图像经过一系列卷积操作得到2x2特征图,这个图上的每个元素与原图是一一对应的,相当于卷积核14x14,步长为2的卷积,产生4个字区域,输出通道数4,可看成4个类别的预测概率值,这样一次CNN计算就可以实现窗口滑动的所有子区域的分类预测,这就是overfeat算法的思路。这是因为卷积操作图片的空间位置信息的不变性,位置对应关系保存好了。这个思路也被R-CNN借鉴,诞生了Fast R-CNN。
尽管上面可以减少滑动窗口的计算量,但只是针对一个固定大小与步长的窗口,远远不够。
YOLO算法很好的解决了这个问题,不再是窗口滑动,而是直接将原始图片分割成互补重合的小方块,然后通过卷积最后产生这样大小的特征图,特征图的每个元素也是对应原始图片的小方块,然后利用每个元素来预测那些中心点在该小方格内的目标。
设计
将图片resize成448x448,送入到CNN网络,最后处理网络预测结果得到预测的目标。
具体的说,YOLO的CNN网络将图片分割成SXS网格,每个单元格检测那些中心点落在格子内的目标,如下图狗这个目标的中心点落在左下角一个单元格内,那么这个单元格负责预测这个狗。
每个单元格会预测B个bouding box以及bouding box的confidence。这个confidence代表所预测的box中含有object的confidence和这个bounding box预测的有多准的置信度,这个值是这样算的:
:bounding box内含有目标的概率,有取1,否则为0;
:bounding box和GT之间IoU
因此每个bounding box预测 (x, y, w, h) 和 confidence 共5个值。每个单元格还要预测一个类别信息 C 类,则 SxS个 网格,每个网格要预测 B 个 bounding box 还要预测 C 个 categories(因为编码时,假如狗在单元格中心,那么狗的概率为1,其他概率为0,编码后类似:100000000000.。。)。
输出就是 S x S x (5*B+C) 的一个 tensor。
注意:class 信息是针对每个网格的,confidence 信息是针对每个 bounding box 的。
每个单元格预测的c类的方法是,只要目标落在单元格中心,单元格就负责预测这个类,所以只预测了一次。
举例说明: 在 PASCAL VOC 中,图像输入为 448x448,取 S=7,B=2,一共有20 个类别(C=20),则输出就是 7x7x30 的一个 tensor。
在 test 的时候,每个网格预测的 class 信息和 bounding box 预测的 confidence信息相乘,就得到每个 bounding box 的 class-specific confidence score:
每个网格预测类别的概率 x 含有类别的概率下的置信度 = 预测的box属于某一类的概率,也有该 box 准确度的信息
得到每个 box 的 class-specific confidence score 以后,设置阈值,滤掉得分低的 boxes,对保留的 boxes 进行 NMS 处理,就得到最终的检测结果。
*由于输出层为全连接层,因此在检测时,YOLO 训练模型只支持与训练图像相同的输入分辨率。
*虽然每个格子可以预测 B 个 bounding box,但是最终只选择只选择 IOU 最高的 bounding box 作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。这是 YOLO 方法的一个缺陷。
网络训练
在训练之前,现在Imagenet上进行预训练,其与训练的分类模型采用下图中前20个卷积层,然后添加一个average-pool层和全连接层。与训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以要将网络的输入从224x224增加到了448x448.整个网络的流程如下图所示:
也就是最后再通过全连接层将7x7x30的特征图接全连接层转化为上图所示
如何对坐标回归?
作者对坐标进行了归一处理,在同一个量刚下,这样方便处理。
假设有一个bounding box其中心刚好落在了(row,col)网格中,则这个网格需要负责预测整个红框中的dog目标。假设图像的宽为widthimage,高为heightimage;红框中心在(xc,yc),宽为widthbox,高为heightbox那么:(1) 对于bounding box的宽和高做如下normalization,使得输出宽高介于0~1:
(2) 使用(row, col)网格的offset归一化bounding box的中心坐标:
经过上述公式得到的normalization的(x, y, w, h),再加之前提到的confidence,共同组成了一个真正在网络中用于回归的bounding box;
而当网络在Test阶段(x,y,w,h)经过反向解码又可得到目标在图像坐标系的框。
损失函数
最后输出的是7x7x30,也就是一共有7x7个单元格,每个单元格有30维度,8 维是回归 box 的坐标,2 维是 box的 confidence,还有 20 维是类别。
其中坐标的 x, y 用对应网格的 offset 归一化到 0-1 之间,w, h 用图像的 width 和 height 归一化到 0-1 之间。
作者简单粗暴的全部采用了 sum-squared error loss 来做这件事。这种做法存在以下几个问题:
- 第一,8维的 localization error 和20维的 classification error 同等重要显然是不合理的;
- 第二,如果一个网格中没有 object(一幅图中这种网格很多),那么就会将这些网格中的 box 的 confidence push 到 0,相比于较少的有 object 的网格,这种做法是 overpowering 的,这会导致网络不稳定甚至发散。
解决的方法:
更重视8维的坐标预测,给这些损失前面赋予更大的 loss weight, 记为在 pascal VOC 训练中取 5。
对没有 object 的 box 的 confidence loss,赋予小的 loss weight,记为在 pascal VOC 训练中取 0.5。
有 object 的 box 的 confidence loss 和类别的 loss 的 loss weight 正常取 1。
对不同大小的 box 预测中,相比于大 box 预测偏一点,小 box 预测偏一点肯定更不能被忍受的。而 sum-square error loss 中对同样的偏移 loss 是一样。
为了缓和这个问题,作者用了一个比较取巧的办法,就是将 box 的 width 和 height 取平方根代替原本的 height 和 width。这个参考下面的图很容易理解,小box 的横轴值较小,发生偏移时,反应到y轴上相比大 box 要大。(也是个近似逼近方式)
一个网格预测多个 box,希望的是每个 box predictor 专门负责预测某个 object。具体做法就是看当前预测的 box 与 ground truth box 中哪个 IoU 大,就负责哪个。这种做法称作 box predictor 的 specialization。
- 只有当某个网格中有 object 的时候才对 classification error 进行惩罚。
- 只有当某个 box predictor 对某个 ground truth box 负责的时候,才会对 box 的 coordinate error 进行惩罚。
缺点
YOLO 方法模型训练依赖于物体识别标注数据,因此,对于非常规的物体形状或比例,YOLO 的检测效果并不理想。
YOLO 采用了多个下采样层,网络学到的物体特征并不精细,因此也会影响检测效果。
YOLO 的损失函数中,大物体 IOU 误差和小物体 IOU 误差对网络训练中 loss 贡献值接近(虽然采用求平方根方式,但没有根本解决问题)。因此,对于小物体,小的 IOU 误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。
YOLO 对相互靠的很近的物体,还有很小的群体检测效果不好,这是因为一个网格中只预测了两个框(B=2),并且只属于一类。
同一类物体出现的新的不常见的长宽比和其他情况时,泛化能力偏弱。
由于损失函数的问题,定位误差是影响检测效果的主要原因。尤其是大小物体的处理上,还有待加强。
YOLO_v1的更多相关文章
- 目标检测-yolo2
转载自:http://blog.csdn.net/qq_34784753/article/details/78825493 对于现在的最好的检测系统来说,yolo_v1 的问题主要出现在两方面,也就是 ...
- 基于OpenCV制作道路车辆计数应用程序
基于OpenCV制作道路车辆计数应用程序 发展前景 随着科学技术的进步和工业的发展,城市中交通量激增,原始的交通方式已不能满足要求:同时,由于工业发展为城市交通提供的各种交通工具越来越多,从而加速了城 ...
随机推荐
- 为应用创建多个独立python运行环境
在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4.所有第三方的包都会被pip安装到Python3的site-packages目录下. 如果我们要同时开发多个应用程序,那这 ...
- stack的常见用法
stack的常见用法 栈是什么? 栈是一种先进后出的容器 栈的定义 引入头文件 # include <stack> using namespace std; 定义栈 可以定义任何类型的栈 ...
- 初步学习jquery学习笔记(二)
jQuery事件 jquery是为事件处理而设计的 什么是事件? 页面对不同访问者的相应叫做事件. 事件处理程序指的是html中发生某些事件所调用的方法 实例: 在元素上移动鼠标 选取单选按钮 点击元 ...
- python 9*9乘法口诀 猜数字游戏
- cs244a-Introduction to Computer Networking-Unit2
Unit2: Transport 学习目标: how TCP set up a connection what TCP segment looks like how can TCP be in hig ...
- 不用再去找rem了,你想要的rem都在这
一.兼容性. 目前,IE9+,Firefox.Chrome.Safari.Opera 的主流版本都支持了rem(大胆用吧,目前几乎所有手机浏览器都支持rem) 二.什么是rem. rem是相对于根元素 ...
- .Net Core 认证系统源码解析
不知不觉.Net Core已经推出到3.1了,大多数以.Net为技术栈的公司也开始逐步的切换到了Core,从业也快3年多了,一直坚持着.不管环境怎么变,坚持自己的当初的选择,坚持信仰 .Net Cor ...
- splice方法
此方法有三种用法: 第一种: 删除功能 返回删除内容 索引从0开始 var arr = [1,2,3,4]; var arr2 = arr.splice(0,2); arr2 ===> [1, ...
- vue 列表渲染 v-for
1.数组列表 v-for 块中,我们拥有对父作用域属性的完全访问权限.v-for 还支持一个可选的第二个参数为当前项的索引 1.1 普通渲染 v-for="item ...
- Matlab 中 Data-driven 风格的 API 设计
设计 所谓 data-driven API,指的是用户可以把"操作"作为参数,传入函数,像下面这种: stream = dataStream('load', 'example.cs ...