一文看懂YOLO v3
论文地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf
论文:YOLOv3: An Incremental Improvement
YOLO系列的目标检测算法可以说是目标检测史上的宏篇巨作,接下来我们来详细介绍一下YOLO v3算法内容,v3的算法是在v1和v2的基础上形成的,所以有必要先回忆:一文看懂YOLO v1,一文看懂YOLO v2。
网络结构
从这儿盗了张图,这张图很好的总结了YOLOV3的结构,让我们对YOLO有更加直观的理解。
DBL:代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+BN+Leaky relu。
resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。不懂resnet请戳这儿
concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。
后面我们一起分析网络一些细节与难懂的地方
backbone:darknet-53
为了达到更好的分类效果,作者自己设计训练了darknet-53。作者在ImageNet上实验发现这个darknet-53,的确很强,相对于ResNet-152和ResNet-101,darknet-53不仅在分类精度上差不多,计算速度还比ResNet-152和ResNet-101强多了,网络层数也比他们少。
Yolo_v3使用了darknet-53的前面的52层(没有全连接层),yolo_v3这个网络是一个全卷积网络,大量使用残差的跳层连接,并且为了降低池化带来的梯度负面效果,作者直接摒弃了POOLing,用conv的stride来实现降采样。在这个网络结构中,使用的是步长为2的卷积来进行降采样。
为了加强算法对小目标检测的精确度,YOLO v3中采用类似FPN的upsample和融合做法(最后融合了3个scale,其他两个scale的大小分别是26×26和52×52),在多个scale的feature map上做检测。
作者在3条预测支路采用的也是全卷积的结构,其中最后一个卷积层的卷积核个数是255,是针对COCO数据集的80类:3*(80+4+1)=255,3表示一个grid cell包含3个bounding box,4表示框的4个坐标信息,1表示objectness score。
output
所谓的多尺度就是来自这3条预测之路,y1,y2和y3的深度都是255,边长的规律是13:26:52。yolo v3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)五个基本参数,然后还要有80个类别的概率。所以3×(5 + 80) = 255。这个255就是这么来的。
下面我们具体看看y1,y2,y3是如何而来的。
网络中作者进行了三次检测,分别是在32倍降采样,16倍降采样,8倍降采样时进行检测,这样在多尺度的feature map上检测跟SSD有点像。在网络中使用up-sample(上采样)的原因:网络越深的特征表达效果越好,比如在进行16倍降采样检测,如果直接使用第四次下采样的特征来检测,这样就使用了浅层特征,这样效果一般并不好。如果想使用32倍降采样后的特征,但深层特征的大小太小,因此yolo_v3使用了步长为2的up-sample(上采样),把32倍降采样得到的feature map的大小提升一倍,也就成了16倍降采样后的维度。同理8倍采样也是对16倍降采样的特征进行步长为2的上采样,这样就可以使用深层特征进行detection。
作者通过上采样将深层特征提取,其维度是与将要融合的特征层维度相同的(channel不同)。如下图所示,85层将13×13×256的特征上采样得到26×26×256,再将其与61层的特征拼接起来得到26×26×768。为了得到channel255,还需要进行一系列的3×3,1×1卷积操作,这样既可以提高非线性程度增加泛化性能提高网络精度,又能减少参数提高实时性。52×52×255的特征也是类似的过程。
从图中,我们可以看出y1,y2,y3的由来。
Bounding Box
YOLO v3的Bounding Box由YOLOV2又做出了更好的改进。在yolo_v2和yolo_v3中,都采用了对图像中的object采用k-means聚类。 feature map中的每一个cell都会预测3个边界框(bounding box) ,每个bounding box都会预测三个东西:(1)每个框的位置(4个值,中心坐标tx和ty,,框的高度bh和宽度bw),(2)一个objectness prediction ,(3)N个类别,coco数据集80类,voc20类。
三次检测,每次对应的感受野不同,32倍降采样的感受野最大,适合检测大的目标,所以在输入为416×416时,每个cell的三个anchor box为(116 ,90); (156 ,198); (373 ,326)。16倍适合一般大小的物体,anchor box为(30,61); (62,45); (59,119)。8倍的感受野最小,适合检测小目标,因此anchor box为(10,13); (16,30); (33,23)。所以当输入为416×416时,实际总共有(52×52+26×26+13×13)×3=10647个proposal box。
感受一下9种先验框的尺寸,下图中蓝色框为聚类得到的先验框。黄色框式ground truth,红框是对象中心点所在的网格。
这里注意bounding box 与anchor box的区别:
Bounding box它输出的是框的位置(中心坐标与宽高),confidence以及N个类别。
anchor box只是一个尺度即只有宽高。
LOSS Function
YOLOv3重要改变之一:No more softmaxing the classes。
YOLO v3现在对图像中检测到的对象执行多标签分类。
logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。
如果模板框不是最佳的即使它超过我们设定的阈值,我们还是不会对它进行predict。
不同于faster R-CNN的是,yolo_v3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模。
lxy, lwh, lcls, lconf = ft([0]), ft([0]), ft([0]), ft([0])
txy, twh, tcls, indices = build_targets(model, targets)#在13 26 52维度中找到大于iou阈值最适合的anchor box 作为targets
#txy[维度(0:2),(x,y)] twh[维度(0:2),(w,h)] indices=[0,anchor索引,gi,gj] # Define criteria
MSE = nn.MSELoss()
CE = nn.CrossEntropyLoss()
BCE = nn.BCEWithLogitsLoss() # Compute losses
h = model.hyp # hyperparameters
bs = p[0].shape[0] # batch size
k = h['k'] * bs # loss gain
for i, pi0 in enumerate(p): # layer i predictions, i
b, a, gj, gi = indices[i] # image, anchor, gridx, gridy
tconf = torch.zeros_like(pi0[..., 0]) # conf # Compute losses
if len(b): # number of targets
pi = pi0[b, a, gj, gi] # predictions closest to anchors 找到p中与targets对应的数据lxy
tconf[b, a, gj, gi] = 1 # conf
# pi[..., 2:4] = torch.sigmoid(pi[..., 2:4]) # wh power loss (uncomment) lxy += (k * h['xy']) * MSE(torch.sigmoid(pi[..., 0:2]),txy[i]) # xy loss
lwh += (k * h['wh']) * MSE(pi[..., 2:4], twh[i]) # wh yolo loss
lcls += (k * h['cls']) * CE(pi[..., 5:], tcls[i]) # class_conf loss # pos_weight = ft([gp[i] / min(gp) * 4.])
# BCE = nn.BCEWithLogitsLoss(pos_weight=pos_weight)
lconf += (k * h['conf']) * BCE(pi0[..., 4], tconf) # obj_conf loss
loss = lxy + lwh + lconf + lcls
以上是一段pytorch框架描述的yolo v3 的loss_function代码。忽略恒定系数不看,以下我想着重说几点:
- 首先,yolov3要先build target,因为我们知道正样本是label与anchor box iou大于0.5的组成,所以我们根据label找到对应的anchor box。如何找?label中存放着[image,class,x(归一化),y,w(归一化),h],我们可以用这些坐标在对应13×13 Or 26×26 or 52×52的map中分别于9个anchor算出iou,找到符合要求的,把索引与位置记录好。用记录好的索引位置找到predict的anchor box。
- xywh是由均方差来计算loss的,其中预测的xy进行sigmoid来与lable xy求差,label xy是grid cell中心点坐标,其值在0-1之间,所以predict出的xy要sigmoid。
- 分类用的多类别交叉熵,置信度用的二分类交叉熵。只有正样本才参与class,xywh的loss计算,负样本只参与置信度loss。
参考文章:
https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b
https://blog.csdn.net/yanzi6969/article/details/80505421
https://blog.csdn.net/chandanyan8568/article/details/81089083
https://blog.csdn.net/leviopku/article/details/82660381
https://blog.csdn.net/u014380165/article/details/80202337
一文看懂YOLO v3的更多相关文章
- 一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系
我们知道,不同肤色的人外貌差别很大,而双胞胎的辨识很难.有意思的是Web服务器/Web容器/Web应用程序服务器/反向代理有点像四胞胎,在网络上经常一起出现.本文将带读者对这四个相似概念如何区分. 1 ...
- 一文看懂https如何保证数据传输的安全性的【转载、收藏】
一文看懂https如何保证数据传输的安全性的 一文看懂https如何保证数据传输的安全性的 大家都知道,在客户端与服务器数据传输的过程中,http协议的传输是不安全的,也就是一般情况下http是明 ...
- [转帖]一文看懂web服务器、应用服务器、web容器、反向代理服务器区别与联系
一文看懂web服务器.应用服务器.web容器.反向代理服务器区别与联系 https://www.cnblogs.com/vipyoumay/p/7455431.html 我们知道,不同肤色的人外貌差别 ...
- [转帖] 一文看懂:"边缘计算"究竟是什么?为何潜力无限?
一文看懂:"边缘计算"究竟是什么?为何潜力无限? 转载cnbeta 云计算 雾计算 边缘计算... 知名创投调研机构CB Insights撰文详述了边缘计算的发展和应用前景 ...
- 一文看懂Stacking!(含Python代码)
一文看懂Stacking!(含Python代码) https://mp.weixin.qq.com/s/faQNTGgBZdZyyZscdhjwUQ
- Nature 为引,一文看懂个体化肿瘤疫苗前世今生
进入2017年,当红辣子鸡PD-1疗法,一路横扫多个适应症.而CAR-T治疗的“小车”在获得FDA专委会推荐后也已经走上高速路,成为免疫治疗又一里程碑事件.PD-1.CAR-T之后,下一个免疫治疗产品 ...
- 一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了
一文看懂大数据的技术生态圈,Hadoop,hive,spark都有了 转载: 大数据本身是个很宽泛的概念,Hadoop生态圈(或者泛生态圈)基本上都是为了处理超过单机尺度的数据处理而诞生的.你可以把它 ...
- 转载来自朱小厮博客的 一文看懂Kafka消息格式的演变
转载来自朱小厮博客的 一文看懂Kafka消息格式的演变 ✎摘要 对于一个成熟的消息中间件而言,消息格式不仅关系到功能维度的扩展,还牵涉到性能维度的优化.随着Kafka的迅猛发展,其消息格式也在 ...
- 【转帖】一文看懂docker容器技术架构及其中的各个模块
一文看懂docker容器技术架构及其中的各个模块 原创 波波说运维 2019-09-29 00:01:00 https://www.toutiao.com/a6740234030798602763/ ...
随机推荐
- 数据库的表的字段名称与实体类(pojo)不对应解决方案
数据库的表的字段名称与实体类(pojo)不对应解决方案 数据库表  b where a.f1=1 and b.f2=2 or b.f3=3 order ...
- MyBatis的逆向工程、Example类
public void testFindUserByName(){ //通过criteria构造查询条件 UserExample userExample = new UserExample(); us ...
- UEFI+MBR
前言 传统情况下装系统的两种方案bios + mbr 或 uef i+ gpt but一直有一个疑问! 是否可以使用uefi + mbr 名词解释 硬盘格式 MBR分区:全称"Master ...
- VUE常用问题hack修改
vue-router router这里踩的坑主要是组件的重用.构建单页面大型应用的话,肯定要开启组件的缓存的,因为一般会要求后退的时候不要重新加载页面,而且要记住原始的滚动位置.首先,引入router ...
- 没有修改getModel()方法的返回值导致的Hibernate接收不到页面数据
异常1.通过id进行查询,但id为null,就出现这个异常!java.lang.IllegalArgumentException: id to load is required for loading ...
- pytest文档3-pytest+Allure+jenkins+邮箱发送
前言: 虽然网上有很多邮件配置的文章,但还是想自己写一下配置的过程,因为在中间也碰到了不同坑.按照这个文档配置的话,99%都可以成功. 一.jenkins 配置邮箱 1.打开jenkins后进入点 ...
- openstack (共享组件) 时间同步服务
云计算openstack共享组件——时间同步服务ntp(2) 一.标准时间讲解 地球分为东西十二个区域,共计 24 个时区 格林威治作为全球标准时间即 (GMT 时间 ),东时区以格林威治时区进行 ...
- archaius(4) 属性对象
讲完上一节,我们就可以使用合理的配置管理器或者实现自己的配置管理来管理我们的配置项了.archaius还提供了一种新的配置使用的方式. 动态属性对象 动态属性对象针对每个配置项以对象方式进行操作,并且 ...
- 逻辑漏洞介绍 & 越权访问攻击 & 修复建议
介绍逻辑漏洞 逻辑漏洞就是指攻击者利用业务的设计缺陷,获取敏感信息或破坏业务的完整性.一般出现在密码修改.越权访问.密码找回.交易支付金额等功能处.其中越权访问又有水平越权和垂直越权两种,如下所示. ...