object detection[YOLO]
这部分,我们来聊聊YOLO.
YOLO:You Only Look Once,顾名思义,就是希望网络在训练过程中,一张图片只要看一次就行,不需要去多次观察,比如滑框啥的,从而从底层原理上就减少了很多的计算量。
###0 - 扯扯

图1.YOLOv1检测过程
上图为YOLOv1的检测过程(其实第二版在整体框架上也大同小异,细节自然不同),模型都会统一将输入图片resize到448*448,然后建立CNN模型,在最后的全连接层上对应最后的输出结果。在流程上,模型就是一个整体,所以相对更容易优化,而且也减少了分离模型之间信息传递的缺失,直接就是从像素级别到预测类别和框位置的这么一个结果
Yolo是将对象检测看成一个回归问题(空间上对象框的预测和对应的类别概率)(待后面看到目标函数才知精彩)。
作者认为YOLO的优势有:
1 - 因为其他模型需要先滑框或者基于当前位置框,用分类器分类当前框内是否有对象,然后接着对当前框进行微调等复杂的组成,这里就一个模型,所以快。
2 - 不同于滑框和基于锚点(就是提前定几个不同大小的框)等技术,YOLO基于全图进行训练所以,它能够编码潜在的图片中检测到的类别上下文信息(作者在v2版本就用了锚点)。所以相对Fast R-CNN来说,YOLO能够更少的得到假阳性(也就是把背景框出来了)。
3 - YOLO能学到更广泛的对象表征,所以在自然场景下训练比如COCO,然后在艺术风格图片上预测,效果也好于R-CNN系列。
###1 - YOLO框架

图2.YOLO的网络结构
该结构有24个卷积层2个全连接层,其中用1x1的卷积层来减少特征空间参数。作者是先将该网络在imagenet上以224*224先做分类预训练,然后留待后面检测。

图3.YOLO的目标函数
个人觉得yolov1中最出彩的就是这个目标函数了。这里我们一一解释:
如图2所示,最后会得到一个$7730$的张量,而如何将这个$7730$的张量对应到既要分类又要目标的框坐标预测,那就有意思了。首先看下图:

图4.模型
网格划分:YOLO的思想是先将图片划分成不同的网格,然后假如狗这个对象的中心是在第5行第2列(左上为原点),那么cell[5,2]就负责整个对象的检测。比如图4中划分成了$SS$个网格,其中S就是对应着最后的7,也就是这张图片一共分成了$77$个网格,所以最后的张量中$7730$中的30 就是针对当前网格所需要干的其他事情了。
框预测:基于每个网格,会预测需要的B个框(也就是担心预测的一个框不准,所以多预测几个),作者这里选择2个,即$B=2$,在框预测阶段,需要每个框给出5个值,分别是$x,y,w,h,confidence$。其中
i)$x,y$表示基于当前网格中心为参照得到的预测框的中心坐标;
ii)$w,h$表示预测框相对于整个图的width和height;
iii)\(confidence = P_{object}*IOU_{pred}^{truth}\)。这里IOU的想法是来自文档检索领域的,这里就不细说了,\(IOU=\frac{真实框\bigcap 预测框}{真实框 \bigcup 预测框}\).这里的置信度就是当前区域是否有对象的概率乘以IOU的值,可以看出如果当前区域没对象,那么该置信度就是为0.
iv)因为作者采用的是voc数据集,里面一共有20个类别,所以one-hot就是20维,所以上面的30对应的就是(2*5+20)。
回顾目标函数:基于上面的网格划分和框预测,我们知道最后的$7730$是会在每个网格上都计算一次,这里我们省去目标函数中的$S2$那个求和,即基于某一个网格I来分析(下面将$1_$缩写成$1_^$):
$$\begin\
& &\lambda_\sum_B1_[(x_I-\hat x_I)^2+(y_I-\hat y_I)^2]\
&+&\lambda_\sum_B1_[(\sqrt-\sqrt{\hat w_I})2+(\sqrt-\sqrt{\hat h_I})2]\
&+&\sum_B1_(C_I-\hat C_I)2\
&+& \lambda_\sum_1_(C_I-\hat C_I)2\
&+& 1_\sum_{c \in classes}(p_I(c)-\hat p_I(c))2
\end$$
其中$1_$表示第i个网格是否有对象的真值函数,即满足则为1,否则为0;而$1_$表示在第i个网格中第j个预测候选框负责预测。I
在实现时,获取当前网格的30维度向量基础上,前面5位为一个预测候选框的值:d[:2]为$x,y$, d[2:4]为$w,h$; d[4]为置信度;剩下的d[10:30]为类别对象预测
那么就2种情况,当前网格有对象和没有对象。而且作者是这样说的,只惩罚当该网格中有对象的时候的分类错误,即如果不存在对象,那么分类上就不惩罚了;而且只惩罚负责预测当前对象的那个候选框,置于这个框怎么选,就是选取候选框中IOU最大的那个:
1 - 没有对象。则$1_^\(=0,从而该网格计算的损失函数值为\)\lambda_\sum_B1_(C_i-\hat C_i)^2$;
2 - 有对象。则开始计算损失值,首先计算B个预测候选框与真实框的IOU,然后只在那个最大IOU的候选框上计算$x,y,w,h$,和置信度。
其中$C$就是置信度,而$(C_I-\hat C_I)2$就是表示预测的置信度减去真实的置信度,因$confidence = P_*IOU_$,所以IOU一开始并无法给出,其中$C_I$就是模型给出的一个值,而$\hat C_I$是在训练过程中才能给出的值。(置信度等于出现对象概率乘以IOU,因对象概率在目标函数其他地方就已存在,我们剥离对象概率,所以就是预测IOU的值等于真实IOU的值。即当模型在test的时候,该值能告知当前预测框的置信度)
结合github上hizhangp的代码理解
def loss_layer(self, predicts, labels, scope='loss_layer'):
with tf.variable_scope(scope):
#从预测的向量中取出对应的部分
predict_classes = tf.reshape(predicts[:, :self.boundary1], [self.batch_size, self.cell_size, self.cell_size, self.num_class])
predict_scales = tf.reshape(predicts[:, self.boundary1:self.boundary2], [self.batch_size, self.cell_size, self.cell_size, self.boxes_per_cell])
predict_boxes = tf.reshape(predicts[:, self.boundary2:], [self.batch_size, self.cell_size, self.cell_size, self.boxes_per_cell, 4])
#从label中计算并生成,response表示某个对象的中心是否落在当前cell中
response = tf.reshape(labels[:, :, :, 0], [self.batch_size, self.cell_size, self.cell_size, 1])
#从label中计算当前对象的坐标信息
boxes = tf.reshape(labels[:, :, :, 1:5], [self.batch_size, self.cell_size, self.cell_size, 1, 4])
boxes = tf.tile(boxes, [1, 1, 1, self.boxes_per_cell, 1]) / self.image_size
#因为是label,所以box就一个,从5:25都是20类的类别信息
classes = labels[:, :, :, 5:]
offset = tf.constant(self.offset, dtype=tf.float32)
offset = tf.reshape(offset, [1, self.cell_size, self.cell_size, self.boxes_per_cell])
offset = tf.tile(offset, [self.batch_size, 1, 1, 1])
predict_boxes_tran = tf.stack([(predict_boxes[:, :, :, :, 0] + offset) / self.cell_size,
(predict_boxes[:, :, :, :, 1] + tf.transpose(offset, (0, 2, 1, 3))) / self.cell_size,
tf.square(predict_boxes[:, :, :, :, 2]),
tf.square(predict_boxes[:, :, :, :, 3])])
predict_boxes_tran = tf.transpose(predict_boxes_tran, [1, 2, 3, 4, 0])
#计算预测出来的box与真实box的IOU
iou_predict_truth = self.calc_iou(predict_boxes_tran, boxes)
# calculate I tensor [BATCH_SIZE, CELL_SIZE, CELL_SIZE, BOXES_PER_CELL]
#选择IOU最大的那个候选框作为预测框
object_mask = tf.reduce_max(iou_predict_truth, 3, keep_dims=True)
object_mask = tf.cast((iou_predict_truth >= object_mask), tf.float32) * response
# calculate no_I tensor [CELL_SIZE, CELL_SIZE, BOXES_PER_CELL]
noobject_mask = tf.ones_like(object_mask, dtype=tf.float32) - object_mask
boxes_tran = tf.stack([boxes[:, :, :, :, 0] * self.cell_size - offset,
boxes[:, :, :, :, 1] * self.cell_size - tf.transpose(offset, (0, 2, 1, 3)),
tf.sqrt(boxes[:, :, :, :, 2]),
tf.sqrt(boxes[:, :, :, :, 3])])
boxes_tran = tf.transpose(boxes_tran, [1, 2, 3, 4, 0])
# class_loss
#当response为1,则表示当前cell有对象,否则当前cell的分类loss为0
class_delta = response * (predict_classes - classes)
class_loss = tf.reduce_mean(tf.reduce_sum(tf.square(class_delta), axis=[1, 2, 3]), name='class_loss') * self.class_scale
# object_loss
#选取最大那个IOU作为预测框,然后计算置信度的损失,这里predict_scales是网络预测出的值,iou_predict_truth是当前预测框与真实框的IOU
object_delta = object_mask * (predict_scales - iou_predict_truth)
object_loss = tf.reduce_mean(tf.reduce_sum(tf.square(object_delta), axis=[1, 2, 3]), name='object_loss') * self.object_scale
# noobject_loss
noobject_delta = noobject_mask * predict_scales
noobject_loss = tf.reduce_mean(tf.reduce_sum(tf.square(noobject_delta), axis=[1, 2, 3]), name='noobject_loss') * self.noobject_scale
# coord_loss
coord_mask = tf.expand_dims(object_mask, 4)
boxes_delta = coord_mask * (predict_boxes - boxes_tran)
coord_loss = tf.reduce_mean(tf.reduce_sum(tf.square(boxes_delta), axis=[1, 2, 3, 4]), name='coord_loss') * self.coord_scale
tf.losses.add_loss(class_loss)
tf.losses.add_loss(object_loss)
tf.losses.add_loss(noobject_loss)
tf.losses.add_loss(coord_loss)
###2 - 训练过程
#####1 - 预训练
在设计出图2的网络结构基础上,需要先基于imagenet的一个预训练,从而找到较好的初始值作为后面的对象检测。所以作者先将图2的前20层卷积层后面部分全部删除,然后加个平均池化层和一个全连接层。作者在imagenet 2012 上训练了1个礼拜,并在验证集上获得了top5 88%准确度。
#####2 - 将模型用于检测
在得到上述训练好的模型基础上,将后面的平均池化层和全连接层扔掉,接上4个卷积层和2个全连接层(权重都是随机初始化),然后将图片输入大小从224224调整到448448。为了好计算,所以只使用了平方函数,然后为了使得分类导致的惩罚和定位导致的惩罚程度有所不同,增加有对象基础上的定位误差,减少无对象的置信度;并且在大对象上的框误差的严重程度远小于小对象上的框误差程度,所以接着在$w,h$上使用了开根号。
object detection[YOLO]的更多相关文章
- 论文阅读笔记二十八:You Only Look Once: Unified,Real-Time Object Detection(YOLO v1 CVPR2015)
论文源址:https://arxiv.org/abs/1506.02640 tensorflow代码:https://github.com/nilboy/tensorflow-yolo 摘要 该文提出 ...
- 读论文系列:Object Detection CVPR2016 YOLO
CVPR2016: You Only Look Once:Unified, Real-Time Object Detection 转载请注明作者:梦里茶 YOLO,You Only Look Once ...
- [Localization] YOLO: Real-Time Object Detection
Ref: https://pjreddie.com/darknet/yolo/ 关注点在于,为何变得更快? 论文笔记:You Only Look Once: Unified, Real-Time Ob ...
- YOLO object detection with OpenCV
Click here to download the source code to this post. In this tutorial, you’ll learn how to use the Y ...
- 机器学习:YOLO for Object Detection (一)
最近看了基于CNN的目标检测另外两篇文章,YOLO v1 和 YOLO v2,与之前的 R-CNN, Fast R-CNN 和 Faster R-CNN 不同,YOLO 将目标检测这个问题重新回到了基 ...
- Object Detection(RCNN, SPPNet, Fast RCNN, Faster RCNN, YOLO v1)
RCNN -> SPPNet -> Fast-RCNN -> Faster-RCNN -> FPN YOLO v1-v3 Reference RCNN: Rich featur ...
- [YOLO]《You Only Look Once: Unified, Real-Time Object Detection》笔记
一.简单介绍 目标检测(Objection Detection)算是计算机视觉任务中比较常见的一个任务,该任务主要是对图像中特定的目标进行定位,通常是由一个矩形框来框出目标. 在深度学习CNN之前,传 ...
- Object Detection︱RCNN、faster-RCNN框架的浅读与延伸内容笔记
一.RCNN,fast-RCNN.faster-RCNN进化史 本节由CDA深度学习课堂,唐宇迪老师教课,非常感谢唐老师课程中的论文解读,很有帮助. . 1.Selective search 如何寻找 ...
- 论文学习-深度学习目标检测2014至201901综述-Deep Learning for Generic Object Detection A Survey
目录 写在前面 目标检测任务与挑战 目标检测方法汇总 基础子问题 基于DCNN的特征表示 主干网络(network backbone) Methods For Improving Object Rep ...
随机推荐
- Android Studio Git 分支使用实践
新公司有些项目是用的 Git,以前公司都是 svn,为了练手 Git,我个人 APP 用到了,但是仅简单的 git pull/push 的使用,并未用到 Git 精髓,只有当项目中用到,才会紧迫去全面 ...
- IPD咨询如何才能真正落地?
文/资深顾问 杨学明 IPD作为先进的产品开发理念,思想起源于PRTM公司,PACE,培思的力量,首先在IBM和波音公司迅速完善,中国是深圳华为公司. 1992年IBM公司利润停止增长,财务困难,IB ...
- mysql数据库的基本操作:创建数据库、查看数据库、修改数据库、删除数据库
本节相关: 创建数据库 查看数据库 修改数据库 删除数据库 首发时间:2018-02-13 20:47 修改: 2018-04-07:考虑到规范化,将所有语法中“关键字”变成大写;以及因为整理“mys ...
- MySQL查询日志总结
MySQL查询日志介绍 MySQL的查询日志记录了所有MySQL数据库请求的信息.无论这些请求是否得到了正确的执行.默认文件名为hostname.log.默认情况下MySQL查询日志是关闭的.生产环境 ...
- HashMap和Hashtable的同和不同(详细比较)
一.综述 可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值.虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据h ...
- [20180926]查询相似索引.txt
[20180926]查询相似索引.txt --//有时候在表上建立索引比如A,B字段,可能又建立B字段索引,甚至A字段索引以及B,A字段索引,或者还建立C,A字段索引,--//需要有1个脚本查询这些索 ...
- C#-命名空间(十五)
概念 命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方式 在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突 命名空间的定义是有一定的规范,避免引起不必要的麻烦 命名 ...
- EOS智能合约开发(一):EOS环境搭建和启动节点
EOS和以太坊很像,EOS很明确的说明它就是一个区块链的操作系统,BM在博客中也是说过的. 可以这样比喻,EOS就相当于内置激励系统的Windows/Linux/MacOS,这是它的一个定位. 包括以 ...
- SQL Server 锁机制
锁兼容性图: 一.锁的粒度: 比较需要注意的是RID/KEY.HoBT/PAGE这两对儿的区别,RID和HoBT是针对堆表的,即没有聚集索引的表. 二.锁的模式: 1.关于其中的S.U.X锁: 共享锁 ...
- wordpress安装后访问博客只显示文字的解决办法
按着网上的教程,买了腾讯云服务器,上面的镜像已经安装好WordPress了.但是发现并不像网上十分钟搭建个人站点等的写的那么简单.遇到了一些问题,下面来详细讲一讲. 首先是用ip地址不能直接访问服务器 ...