论文名称:YOLOv4: Optimal Speed and Accuracy of Object Detection
论文下载地址:https://arxiv.org/abs/2004.10934
对应视频讲解:https://b23.tv/WLptQ7Q
文章目录
YOLOv4是2020年Alexey Bochkovskiy等人发表在CVPR上的一篇文章,并不是Darknet的原始作者Joseph Redmon发表的,但这个工作已经被Joseph Redmon大佬认可了。之前我们有聊过YOLOv1~YOLOv3以及Ultralytics版的YOLOv3 SPP网络结构,如果不了解的可以参考之前的视频,YOLO系列网络详解。如果将YOLOv4和原始的YOLOv3相比效果确实有很大的提升,但和Ultralytics版的YOLOv3 SPP相比提升确实不大,但毕竟Ultralytics的YOLOv3 SPP以及YOLOv5都没有发表过正式的文章,所以不太好讲。所以今天还是先简单聊聊Alexey Bochkovskiy的YOLOv4。

如果之前有阅读过YOLOv4这篇论文的小伙伴,你会发现作者就是把当年所有的常用技术罗列了一遍,然后做了一堆消融实验。实验过程及结果写的还是很详细的,但对我个人而言感觉有点杂乱,没能很好的突出重点。如果大家对实验不敢兴趣的话,直接从论文3.4章节往后看就行了。
在论文3.4章节中介绍了YOLOv4网络的具体结构:
CSPDarknet53SPP,PANYOLOv3相比之前的YOLOv3,改进了下Backbone,在Darknet53中引入了CSP模块(来自CSPNet)。在Neck部分,采用了SPP模块(Ultralytics版的YOLOv3 SPP就使用到了)以及PAN模块(来自PANet)。Head部分没变还是原来的检测头。
关于CSPDarnet53,后面有专门的章节讲解,这里暂时跳过。关于SPP(Spatial Pyramid Pooling)模块之前讲YOLO系列网络详解时详细介绍过,SPP就是将特征层分别通过一个池化核大小为5x5、9x9、13x13的最大池化层,然后在通道方向进行concat拼接在做进一步融合,这样能够在一定程度上解决目标多尺度问题,如下图所示。

PAN(Path Aggregation Network)结构其实就是在FPN(从顶到底信息融合)的基础上加上了从底到顶的信息融合,如下图(b)所示。

但YOLOv4的PAN结构和原始论文的融合方式又略有差异,如下图所示。图(a)是原始论文中的融合方式,即特征层之间融合时是直接通过相加的方式进行融合的,但在YOLOv4中是通过在通道方向Concat拼接的方式进行融合的。

有关训练Backbone时采用的优化策略就不讲了有兴趣自己看下论文的4.2章节,这里直接讲下训练检测器时作者采用的一些方法。在论文4.3章节,作者也罗列了一堆方法,并做了部分消融实验。这里我只介绍确实在代码中有使用到的一些方法。
在原来YOLOv3中,关于计算预测的目标中心坐标计算公式是:
b
x
=
σ
(
t
x
)
+
c
x
b
y
=
σ
(
t
y
)
+
c
y
b_x = \sigma(t_x) + c_x \\ b_y = \sigma(t_y) + c_y
bx=σ(tx)+cxby=σ(ty)+cy
其中:
sigmoid激活函数,将预测的偏移量限制在0到1之间,即预测的中心点不会超出对应的Grid Cell区域
但在YOLOv4的论文中作者认为这样做不太合理,比如当真实目标中心点非常靠近网格的左上角点(
σ
(
t
x
)
\sigma(t_x)
σ(tx)和
σ
(
t
y
)
\sigma(t_y)
σ(ty)应该趋近与0)或者右下角点(
σ
(
t
x
)
\sigma(t_x)
σ(tx)和
σ
(
t
y
)
\sigma(t_y)
σ(ty)应该趋近与1)时,网络的预测值需要负无穷或者正无穷时才能取到,而这种很极端的值网络一般无法达到。为了解决这个问题,作者引入了一个大于1的缩放系数(
s
c
a
l
e
x
y
{\rm scale}_{xy}
scalexy):
b
x
=
(
σ
(
t
x
)
⋅
s
c
a
l
e
x
y
−
s
c
a
l
e
x
y
−
1
2
)
+
c
x
b
y
=
(
σ
(
t
y
)
⋅
s
c
a
l
e
x
y
−
s
c
a
l
e
x
y
−
1
2
)
+
c
y
b_x = (\sigma(t_x) \cdot {\rm scale}_{xy} - \frac{{\rm scale}_{xy}-1}{2}) + c_x \\ b_y = (\sigma(t_y) \cdot {\rm scale}_{xy} - \frac{{\rm scale}_{xy}-1}{2})+ c_y
bx=(σ(tx)⋅scalexy−2scalexy−1)+cxby=(σ(ty)⋅scalexy−2scalexy−1)+cy
通过引入这个系数,网络的预测值能够很容易达到0或者1,我看现在比较新的实现方法包括YOLOv5都将
s
c
a
l
e
x
y
{\rm scale}_{xy}
scalexy设置2,即:
b
x
=
(
2
⋅
σ
(
t
x
)
−
0.5
)
+
c
x
b
y
=
(
2
⋅
σ
(
t
y
)
−
0.5
)
+
c
y
b_x = (2 \cdot \sigma(t_x) - 0.5) + c_x \\ b_y = (2 \cdot \sigma(t_y) - 0.5) + c_y
bx=(2⋅σ(tx)−0.5)+cxby=(2⋅σ(ty)−0.5)+cy
下面是我绘制的 y = σ ( x ) y = \sigma(x) y=σ(x)对应sigma曲线和 y = 2 ⋅ σ ( x ) − 0.5 y = 2 \cdot \sigma(x) - 0.5 y=2⋅σ(x)−0.5对应scale曲线,很明显通过引入缩放系数scale以后, x x x在同样的区间内, y y y的取值范围更大,或者说 y y y对 x x x更敏感了。并且偏移的范围由原来的 ( 0 , 1 ) (0, 1) (0,1)调整到了 ( − 0.5 , 1.5 ) (-0.5, 1.5) (−0.5,1.5)。

在数据预处理时将四张图片拼接成一张图片,增加学习样本的多样性,之前在YOLO系列网络详解P4中讲过,这里不在赘述。

在YOLOv3中针对每一个GT都只分配了一个Anchor。但在YOLOv4包括之前讲过的YOLOv3 SPP以及YOLOv5中一个GT可以同时分配给多个Anchor,它们是直接使用Anchor模板与GT Boxes进行粗略匹配,然后在定位到对应cell的对应Anchor。
首先回顾下之前在讲YOLOv3 SPP源码解析时提到的正样本匹配过程。流程大致如下图所示:比如说针对某个预测特征层采用如下三种Anchor模板AT 1、AT 2、AT 3

AT 2cell(图中黑色的
×
\times
×表示cell的左上角)cell对应的AT2为正样本但在YOLOv4以及YOLOv5中关于匹配正样本的方法又有些许不同。主要原因在于1.2.1 Eliminate grid sensitivity中提到的缩放因子
s
c
a
l
e
x
y
scale_{xy}
scalexy,通过缩放后网络预测中心点的偏移范围已经从原来的
(
0
,
1
)
(0, 1)
(0,1)调整到了
(
−
0.5
,
1.5
)
(-0.5, 1.5)
(−0.5,1.5)。所以对于同一个GT Boxes可以分配给更多的Anchor,即正样本的数量更多了。如下图所示:

YOLOv4中IoU的阈值设置的是0.213)AT 2cell(注意图中有三个对应的cell,后面会解释)cell对应的AT2都为正样本为什么图中的GT会定位到3个cell,这里简单做下解释(这里是通过分析ultralytics的YOLOv5源码得到的)。刚刚说了网络预测中心点的偏移范围已经调整到了
(
−
0.5
,
1.5
)
(-0.5, 1.5)
(−0.5,1.5),所以按理说只要Grid Cell左上角点距离GT中心点在
(
−
0.5
,
1.5
)
(-0.5, 1.5)
(−0.5,1.5)范围内它们对应的Anchor都能回归到GT的位置处。在回过头看看刚刚上面的例子,
G
T
x
c
e
n
t
e
r
,
G
T
y
c
e
n
t
e
r
GT^{center}_x, GT^{center}_y
GTxcenter,GTycenter它们距离落入的Grid Cell左上角距离都小于0.5,所以该Grid Cell上方的Cell以及左侧的Cell都满足条件,即Cell左上角点距离GT中心在
(
−
0.5
,
1.5
)
(-0.5, 1.5)
(−0.5,1.5)范围内。这样会让正样本的数量得到大量的扩充。但需要注意的是,YOLOv5源码中扩展Cell时只会往上、下、左、右四个方向扩展,不会往左上、右上、左下、右下方向扩展。下面又给出了一些根据
G
T
x
c
e
n
t
e
r
,
G
T
y
c
e
n
t
e
r
GT^{center}_x, GT^{center}_y
GTxcenter,GTycenter的位置扩展的一些Cell,其中%1表示取余并保留小数部分。

在YOLOv3中使用anchor模板是:
| 目标类型 | Anchors模板 |
|---|---|
| 小尺度 | ( 10 × 13 ) , ( 16 × 30 ) , ( 33 × 23 ) (10 \times 13), (16 \times 30), (33 \times 23) (10×13),(16×30),(33×23) |
| 中尺度 | ( 30 × 61 ) , ( 62 × 45 ) , ( 59 × 119 ) (30 \times 61), (62 \times 45), (59 \times 119) (30×61),(62×45),(59×119) |
| 大尺度 | ( 116 × 90 ) , ( 156 × 198 ) , ( 373 × 326 ) (116 \times 90), (156 \times 198), (373 \times 326) (116×90),(156×198),(373×326) |
在YOLOv4中作者针对
512
×
512
512 \times 512
512×512尺度采用的anchor模板是:
| 目标类型 | Anchors模板 |
|---|---|
| 小尺度 | ( 12 × 16 ) , ( 19 × 36 ) , ( 40 × 28 ) (12 \times 16), (19 \times 36), (40 \times 28) (12×16),(19×36),(40×28) |
| 中尺度 | ( 36 × 75 ) , ( 76 × 55 ) , ( 72 × 146 ) (36 \times 75), (76 \times 55), (72 \times 146) (36×75),(76×55),(72×146) |
| 大尺度 | ( 142 × 110 ) , ( 192 × 243 ) , ( 459 × 401 ) (142 \times 110), (192 \times 243), (459 \times 401) (142×110),(192×243),(459×401) |
在YOLOv3中定位损失采用的是MSE损失,但在YOLOv4中作者采用的是CIoU损失。之前在YOLO系列网络详解P4中很详细的讲解过IoU Loss,DIoU Loss以及CIoU Loss,这里不在赘述。

CSPDarknet53就是将CSP结构融入了Darknet53中。CSP结构是在CSPNet(Cross Stage Partial Network)论文中提出的,CSPNet作者说在目标检测任务中使用CSP结构有如下好处:
- Strengthening learning ability of a CNN
- Removing computational bottlenecks
- Reducing memory costs
即减少网络的计算量以及对显存的占用,同时保证网络的能力不变或者略微提升。CSP结构的思想参考原论文中绘制的CSPDenseNet,进入每个stage(一般在下采样后)先将数据划分成俩部分,如下图所示的Part1和Part2。但具体怎么划分呢,在CSPNet中是直接按照通道均分,但在YOLOv4网络中是通过两个1x1的卷积层来实现的。在Part2后跟一堆Blocks然后在通过1x1的卷积层(图中的Transition),接着将两个分支的信息在通道方向进行Concat拼接,最后再通过1x1的卷积层进一步融合(图中的Transition)。

接下来详细分析下CSPDarknet53网络的结构,下图是我根据开源仓库https://github.com/Tianxiaomo/pytorch-YOLOv4中代码绘制的CSPDarknet53详细结构(以输入图片大小为
416
×
416
×
3
416 \times 416 \times 3
416×416×3为例),图中:
CSPDarknet53 Backbone中所有的激活函数都是Mish激活函数
下图是我绘制的YOLOv4网络的详细结构,大家在搭建或者学习过程中可以进行参考。

我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案
我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
(本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展 是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。 如:有三个人,每个人做的不同的事物,但是是需要协作的完成。 而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据
一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su
安全产品安全网关类防火墙Firewall防火墙防火墙主要用于边界安全防护的权限控制和安全域的划分。防火墙•信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。防火墙是一个由软件和硬件设备组合而成,在内外网之间、专网与公网之间的界面上构成的保护屏障。下一代防火墙•下一代防火墙,NextGenerationFirewall,简称NGFirewall,是一款可以全面应对应用层威胁的高性能防火墙,提供网络层应用层一体化安全防护。生产厂家•联想网御、CheckPoint、深信服、网康、天融信、华为、H3C等防火墙部署部署于内、外网编辑额,用于权限访问控制和安全域划分。UTM统一威胁管理(Un
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好