YOLO-V3

YOLO-V3

image-20211117094201993

设计思想

主要特点:

  • 单阶段检测,同时完成候选区域生成 + 物体位置和类别的预测

  • 每个真实框只对应一个正的候选区域

image-20211117100411935

实现方案

image-20211117100703331

生成锚框和候选区域

生成锚框

step1:将原图划分成多个小方块区域

原图大小:640 × 480

小方块尺寸:32 × 32

划分成了20 × 15 个小方块区域

step2:以小方块区域为中心,生成一系列锚框

生成锚框的规则:

  • 中心点:小方块区域的中心

  • 大小:3种 [w,h]

    • [116,90] , [156,198] , [373,326] (数字的选择-聚类中心)

在每个小方块区域都生成三种形状的锚框,将会覆盖整张图片

一张图片上锚框的总数为20 ×15 × 3 = 900

image-20211117102303950

产生候选区域

生成预测框

所有锚框覆盖住了整张图片,但是锚框的位置是固定的,一般不会跟物体真实框刚好重合。

要想得到跟物体真实框足够接近的预测结果,需要在锚框的基础上做一些小的调整。

预测框

可以看作是 在锚框的基础上做微调, 可以调整 中心坐标和宽度、高度。

image-20211117104422113

image-20211117104446683

step1:选择第10行第4列的小方块区域, Cx ,Cy = [4,10]

step2:以小方块为中心,生成锚框。所示锚框大小为[250,250]

step3:计算预测框的中心坐标和尺寸

image-20211117104924506

image-20211117105017974

标注候选区域

image-20211117110435874

标注锚框 ----objectness

  • 标注objectness标签

    • 找出真实框中心点所在的小方块区域,从这个区域的3个锚框中挑选出跟他形状最匹配的锚框

    • 计算iou,找出跟真实框最匹配的锚框,将其objectness标注为1,其余标注为0。

image-20211117111013520

标注锚框----location(位置)

image-20211117111707843

标注锚框----classification

  • 当objectness = 1 时,需要确定包含的物体所属的类别 classification

image-20211117111844690

  • YOLO-V3模型对每个类别独立的计算概率,标注的时候将类别标签表示成one-hot 向量

image-20211117111941734

标注总结

image-20211117112041753

  • 每个锚框需要的标注数据个数:

    • location(4) + objectness(1) + classification(C) = 5+C

    • m × n 个方块区域,每个区域K个锚框,则标注数据的维度是[k(5+C)] × m × n

标注锚框----程序实现

image-20211117210945371

image-20211117212955535

特征提取

生成候选区域并对其进行标注 objectness location classification

  • 使用卷积神经网络提取特征

  • 网络选择:Darknet53

    • 一共52层卷积 + 1层全连接

  • 检测模型将 C0 以后的层去掉,从输入到 C0 部分的网络被称为检测模型的 骨干模型(backbone)

  • YOLO-V3 算法中使用了C0、C1、C2 三个层级的特征图来产生候选区域的输出。

image-20211118093129176

  • 创建Darknet53骨干网络模块

image-20211118093749514

image-20211118093830680

image-20211118093855275

对C0进一步提取特征运用到的模块 YoloDetectionBlock

关联特征图与候选区域

image-20211121102328781

建立损失函数

采用sum-squared error(损失总平方和)的方式把localization error(bounding box的坐标误差)和classificaton error整合在一起。

找出objectness = -1的锚框

image-20211121103144019

建立损失函数

损失函数的设计目标就是让坐标(x,y,w,h)8维,confidence 2维,classification 20维这个三个方面达到很好的平衡。

采用误差的平方和整合了预测框定位误差与有无目标的IOU误差以及分类误差

image-20211121104816426

多尺度检测

image-20211122205555687

image-20211122210146331

image-20211122210211083

端到端训练

模型预测

image-20211122210623910

image-20211122210653384

消除冗余预测框

非极大值抑制(NMS)

如果有多个预测框位置比较接近,只选出得分最高的那个预测框,剩下的预测框被丢弃掉。

核心思想是:选择得分最高的作为输出,与该输出重叠的去掉,不断重复这一过程直到所有备选处理完。

预测框位置是否接近?

  • 看iou是否超过阈值

    • 超过阈值说明他们重合度很大,很有可能预测的是同一个物体。

例如:

image-20211122212000817

image-20211122212350875

YOLO -V3流程总结

image-20211122214044931

附:

L2正则化

L2正则化就是loss function后边所加正则项为L2范数的平方,加上L2正则相比于L1正则来说,得到的解比较平滑(不是稀疏),但是同样能够保证解中接近于0(但不是等于0,所以相对平滑)的维度比较多,降低模型的复杂度。

upsample和subsample

  • subsample:缩小图像(或称为下采样(subsample)或降采样(downsample))的主要目的有两个:

    • 使得图像符合显示区域的大小

    • 生成对应图像的缩略图。

  • upsample:放大图像(或称为上采样(upsampling)或图像插值(interpolating))的主要目的是

    • 放大原图像,从而可以显示在更高分辨率的显示设备上。

anchors

使用道德anchor的尺寸,如[10,13,16,30,33,23,30,61,156,198,373]

anchor_mask

每个层级上使用的anchor的掩码,[[6,7,8],[3,4,5],[0,1,2]]

conf_thresh

置信度阈值,得分低与该阈值的预测框位置数值不用计算直接设置为0.0

category

为现有的类添加新方法。

好处:可以把类的实现分开在几个不同的文件里面。这样做有几个显而易见的好处

a)可以减少单个文件的体积

b)可以把不同的功能组织到不同的category里

c)可以由多个开发者共同完成一个类

d)可以按需加载想要的category

range

range(start,stop[,step])

  • start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);

  • stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5

  • step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)

enumerate()说明

enumerate在字典上是枚举、列举的意思

对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值

 #如果对一个列表,既要遍历索引又要遍历元素时,首先可以这样写
 list1 = ["这", "是", "一个", "测试"]
 for i in range (len(list1)):
     print i ,list1[i]
     
 #上述方法有些累赘,利用enumerate()会更加直接和优美
 list1 = ["这", "是", "一个", "测试"]
 for index, item in enumerate(list1):
     print index, item
 >>>
 0 这
 1 是
 2 一个
 3 测试
 ​
 #enumerate还可以接收第二个参数,用于指定索引起始值
 list1 = ["这", "是", "一个", "测试"]
 for index, item in enumerate(list1, 1):
     print index, item
 >>>
 1 这
 2 是
 3 一个
 4 测试

listdir()

os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表,

基本语法:os.listdir(path),其中参数需要列出的目录路径 返回值:返回指定路径下的文件和文件夹列表。

np.random.seed()随机数种子

np.random.seed()参考

随机数种子,相当于我给接下来需要生成的随机数一个初值,按照我给的这个初值,按固定顺序生成随机数。

通俗理解: 随机数种子是给了一批数(随机数种子应该是按一定顺序生成随机数的,并不是一次给了一批数,但如果这些数有固定顺序,我们是不是可以简单认为随机种子给了我们很多数据),当需要生成随机数时,就从这一批数中依次取值。

例子:

 np.random.seed(0)  # 先定义一个随机数种子,()中的参数值后下个小节说
 print(np.random.rand(5))  # "随机"生成5个数
 print(np.random.rand(5))  # 再"随机"生成5个数
 ​
 np.random.seed(0)
 for i in range(7):
     print(np.random.random())  # "随机"生成7个数
     
 # 结果
 [0.5488135  0.71518937 0.60276338 0.54488318 0.4236548 ]
 [0.64589411 0.43758721 0.891773   0.96366276 0.38344152]
 ​
 0.5488135039273248
 0.7151893663724195
 0.6027633760716439
 0.5448831829968969
 0.4236547993389047
 0.6458941130666561
 0.4375872112626925

观察结果:下边的 ‘ 随机 ’ 生成的7个数和上边 ‘ 随机 ’ 生成的十个数中的前7个相同。

为了方便理解,我们把随机种子看成一个超级超级长的 list ,我们接下来的取随机数操作,( np.random.rand(5) )就是从这个 list 中依次取5个随机数。

 np.random.seed(0)
 for i in range(7):
     print(np.random.random())
     
 np.random.seed(0)
 print(np.random.rand(2, 3))
 ​
 0.5488135039273248
 0.7151893663724195
 0.6027633760716439
 0.5448831829968969
 0.4236547993389047
 0.6458941130666561
 0.4375872112626925
 ​
 [[0.5488135  0.71518937 0.60276338]
  [0.54488318 0.4236548  0.64589411]]

2x3矩阵的6个数 和 随机生成的前6个数相同!

所以如果我想生成两个一样的随机矩阵怎么办?在生成矩阵前,定义随机数种子就好了

总结:

(1)随机数种子相当于给我们一个初值,之后按照固定顺序生成随机数(也就是我们说的超级长的 list ) (2)随机数种子对后面的结果一直有影响,在一个随机数种子后生成的随机数都受这个随机数种子的影响,即生成的随机数都是由这个随机数种子给的初值,按照固定顺序生成的(生成的随机数受离它最近的随机数种子影响,即它之前的随机数种子)。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值