继续创作,加快成长!这是我参加「日新计划 10 月更文应战」的第21天,点击检查活动详情
前语
无意中翻到一篇本来的一篇漫笔,水一下,明天更新强化学习TSP,下个礼拜完结WhiteHole的核心业务开发~ 那么这篇博文的话,主要是关于方针检测的一个文章。
GitHub 水项目之 快速上手 YOLOV5
YOLOV5 参数设定与模型练习的坑点一二三
YOLOV1论文小收拾
在代码部分还参阅了原先这篇博文的规划: 嘿~全流程带你根据Pytorch手撸图片分类“框架“–HuClassify
那么本文两个方针:
一. 理论
- 搞清楚什么是方针检测
- 方针检测的重难点
- 相关方针检测算法思想
- 怎么规划一个方针检测算法
其间的理论部分像我说不会太深入仅仅快速入门,编码部分的话却是有许多相关算法的完成。那么编码的话在方针检测部分的网络,咱们也是直接运用yolo的网络,当然这儿仍是会做改动的。这篇博文的更多的一个目的其实仍是说建立一个简略的方针检测渠道,这样感兴趣的朋友能够自己DIY,对我本人的话也是有DIY的需求。
那么废话不多说,马上发车了!
方针检测
要说到方针检测的话,那么咱们就不得不先说到图片分类了。 因为图片分类在咱们的方针检测傍边是十分重要的但是二者的区别也是存在的,不过他们之间却有许多相似的地方。
图片分类
图片分类是一个十分经典的问题,给定一张图片然后对这个图片进行分类,它的任务十分简略,并且规划一个这样的网络也十分简略。 你只需求运用一定量的卷积,最终和一定量的全衔接网络输出一组巨细和类别的最终一个维度相同的tensor就行了,然后运用穿插熵作为你的丢失函数。
比方最简略的分类网络:LeNet
class LeNet(nn.Module):
def __init__(self,classes):
super().__init__()
self.feature = Sequential(
nn.Conv2d(3,6,kernel_size=5),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2,stride=2),
nn.Conv2d(6,16,5),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2,stride=2)
)
self.classifiar = nn.Sequential(
nn.Linear(16*5*5,120), # B
nn.ReLU(),
nn.Linear(120,84),
nn.ReLU(),
nn.Linear(84,classes)
)
def forward(self,x):
x = self.feature(x)
x = x.view(x.size()[0],-1)
x = self.classifiar(x)
return x
def initialize_weights(self):
#参数初始化,随便给点权重,这样的话会加快一点速度(练习)
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.xavier_normal_(m.weight.data)
if m.bias is not None:
m.bias.data.zero_()
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight.data, 0, 0.1)
m.bias.data.zero_()
咱们只需求输入一张图片就阔以得到这张图片的类别。
但是这仍是远远不够的。
方针检测
方针检测则是在图片分类的基础上,咱们还需求知道咱们对应的一个物体的位置,比方下面这张图: 咱们知道这是一只猫,但是在图片场景傍边并不是只需一只猫,猫仅仅图片傍边的一个很明显的特征,假如做图片分类的话,你说这个是猫能够,但是我说这是个草形似也能够。所以现在的任务是我不仅仅要知道这个图片有猫,我还要知道这个猫在图片的位置。
单方针检测
现在咱们假定,咱们的图片只需一个物体,就如上面的图片相同。那么假如咱们需求想方法让神经网络得到这样一个框的,当然在此基础上,咱们还需求得到对应的概率,也便是,假如图片只需一个方针的话,咱们只需求在本来的基础上想方法多生成一组对应的框的坐标就能够了。也便是说,咱们以上面的LeNet网络为例子。咱们能够这样干。
咱们只需把本来的那个直接输出概率的那一个全衔接层拆掉,然后再来几个全衔接层之后别离猜想就完了。
至于丢失函数,这也好办,一个是穿插熵得到Loss1 还有一个是求方差,求对应的框的点和标示的框的差错就完了得到Loss2 之后Loss=Loss1+Loss2
多方针检测
然而抱负是很饱满的,但是现实很严酷。现在的图片傍边往往都是有多个方针的,并且哪怕是同一个方针,在一张图片傍边也或许有多个,那问题不就为难了,比方下面的图片:
所以咱们需求处理这个问题。
问题剖析
首要咱们来想想,咱们现在面对的问题,首要关于一张图片,对送进神经网络的图片来说(假定数据集不是咱们 自己搞的)咱们是不知道当时这个图片它是有几个方针的,所以假如是按照咱们从前那个对LeNet的改动的话,咱们是压根就不知道要生成几个框,做几个概率的猜想的。假定咱们知道了,或者说咱们一股脑直接生成一堆框,那么咱们需求怎么挑选这些有用的框出来?并且咱们怎么区别这些框对应的类别是啥?最终咱们的丢失函数又要怎么规划?
那么假如咱们能够找到一种方法能够搞定上面的问题,那么多方针检测应该就能够完成了,换句话说能够通用的方针检测算法就ok了。
滑动窗口
前面剖析了咱们假如想要完成那个多方针检测,咱们需求处理的问题。那么第一个问题,怎么生成框。回到一开始的方法,咱们是直接输入了一张图片,然后,对这张图片生成一个框,然后做猜想等操作,那么已然如此,那么我就直接这样,我把一张图片直接分成一个个区域,相当于截图相同,一个一个区域截图,然后别离送进神经网络。然后你懂的,咱们套用刚刚提出的方法。
也便是下面这样
我能够生成不同的滑动窗口,然后疯狂搞。 理论上只需电脑不冒烟,我就能够一向搞。只需功率显然….
所以还需求优化一下。
RCNN
那么这个时分,你或许会想了,刚刚的问题难度在于咱们很难去得到这些框,因为做分类对咱们来说仍是十分简略的作业,但是做检测,偏偏有个猜想框很难弄。假如咱们能够直接得到一堆候选框,然后对每一个框所属的类别进行猜想之后再选用某一种方法去挑选出合适的框不久变得简略了嘛。
那么这个时分RCNN呈现了,在2014年的时分,那个时分我应该仍是个小学生。它的流程是这样的:
- 关于一张图片,找出默认2000个候选区域
- 2000个侯选区域做巨细变换,输入AlexNet傍边,得到特征向量 [2000,4096]
- 通过20个类别的SVM分类器,关于2000个候选区域做判别,得 到[2000,20]得分矩阵
- 2000个候选区域做NMS,取出不好的,重度高的一些候选 区域,得到剩下分数高,成果好的相
- 修正候选框,bbox的回归微调
那么现在已然说到了RCNN,那么咱们现在就不得不先说到两个概念了,第一是IOU,第二是NMS算法也便是那个挑选算法。
不过在这儿我先说一些IOU,因为NMS在代码阶段会详细介绍,咱们需求手动完成这个算法,当然IOU也需求,但是它十分简略。 便是这个东西
咱们能够用这个玩意来衡量这两个生成的框是不是重合了,重合了多少,假如重合太多的话,是不是说他们两个框都在猜想同一个物体,那么咱们就可不能够把概率低的给干掉。而这个的话其实也是NMS的思想,具体仍是看下文。
那么这儿处理了能够自动生成框的问题,但是这儿的分类器用的仍是SVM,并且这个SVM必定也是需求先练习好的,不然很难完结分类呀。并且在练习SVM的时分,咱们是把通过了一个神经网络的数据给SVM的,那么意味还需求对AlexNet做处理,需求缓存许多中间数据然后练习。 并且每一个框都要进入神经网络,2000个要进去似乎也没有比暴力好到那儿去。
SPPNet
前面说了RCNN,其实最大的一个改善相关于滑动窗口来说,似乎便是多了一个方法去生成候选框。实际上后边那些SVM咱们也未尝不能够和AlexNet直接合并成一个大网络然后对2000个候选框做分类,而不是分开来。
但是最大的问题并不是这个,问题在于咱们仍是需求进入2000次卷积。
那么有没有方法能够削减卷积咧,有SPPNet!
首要候选框仍是咱们RCNN那种方法提取出来的,但是它直接把一张图片输入进一个卷积里边。 然后得到一个特征向量,之后这个特征向量里边包含了本来的候选框的信息,他们之间存在这样的映射联系: 这个映射联系的不是咱们的重点,这儿就疏忽了,感兴趣的能够自己去了解,不够这个拿到feature map 绝对是方针检测史上最重要的一点之一!不过在这儿还没有太大体现。
那么后边的操作其实就和RCNN相似了,仅仅中间又加了一些池化等等操作
至于缺陷:
1. 练习依然过慢、功率低,特征需求写入磁盘(因为SVM的存在)
2. 分阶段练习网络:选取候选区域、练习CNN、练习SVM、练习bbox回归器,SPPNet)反向传达功率 低
Fast-RCNN
当我把标题独自放在外面的时分,我想你应该知道了这玩意的重要性。
来咱们直接看到整个图:
前面的部分其实和SPPNet很像,也便是一个卷积,但是后边全部变成 net,这个好像有点像咱们一开始瞎扯说到的方法了,也便是在后半部分。不过有点惋惜的是总体上FastRCNN 的改善其实是把SPPNet后边的东西改了,前面的候选框其实仍是运用RCNN的那一套机制,也便是SS算法。
不够尽管如此,fast rcnn 总算是和咱们现在的方针检测算法的姿态有点像了,因为咱们总算抛弃了SVM,总算让咱们的神经网络去做更多的作业了。
并且说到了咱们的多任务丢失,并且不用把网络拆来了练习了,而是能够做到端到端了。
并且速度有了很大的提升
之后它的网络图是这样的:
那么虽然现已很快了,那么还有方法嘛?本来RCNN 但是2000个候选区域啊。能不能缩减!有没有方法?
(这儿面还有许多细节没有说到,需求读者自行搜索,不过不影响本文观看)
答案是有!
Faster RCNN
前面咱们的FastRCNN 现已让神经网络做了许多作业了,那么为什么不能把候选框的提取也做了,让神经网络做到更多的作业?并且还有哪些东西是能够加强改善的?feature map 能不能利用起来?
嘿!还真能。
咱们直接在feature map上面做提取,在上面生成候选区域,然后再执行后续操作,后续操作和咱们fast rcnn是相同的,咱们只需求对这些候选框和分类器处理。所以咱们的网络结构就变成了这样
在feature后边提取的网络叫做RPN
RPN 作业流程
说到这个玩意咱们就必须提一下,因为这个东西的作业流程绝对是十分重要的,这意味着咱们能够做出更大的改善在后边!
咱们知道它的作业地方实在feature map上面 那么他怎么作业呢。
这儿引入一个称号叫做anchor 其实也便是bbox,那个猜想框。
他是这样的,在那个feature map 的基础上,每一个网格,都会生成9个框,假定那个特征是20×20 的那么他有9个便是20x20x9 假如要具体表明的话,xmin,ymin,xmax,ymax(左上角,右下角)那便是20x20x36的张量
那么这儿为什么是9个呢,由所以这样的,原作者规划了三种比例三种巨细的样式,因为图片傍边物体的巨细是不相同的。 那么刚好对应的便是9个组合。之后的部分我就不细说了。
Yolo
那么到这儿,你或许又有疑问了,那个RPN相同的网络能不能放在featur map 前面呢?假如我一开始就指定好图片的网格,然后不同的网格去生成候选框会怎么样? 没错大名鼎鼎的yolo出来了:(这儿是v1)
我先直接这样以为分成7×7的格子然后每个格子发生候选框,这儿是2个候选框。
之后得到7x7x30的张量.
这儿解释一下30里边包含了啥。
这儿面存储了 两大类信息。 第一个 是 边框信息,起点,宽高,可信度。 第二个是 类别的条件概率,这儿主要是20个类。
之后咱们通过NMS对这些候选框进行挑选。
然后进入丢失函数,这部分咱们后边说,它的丢失函数是这样的 咱们接下来要自制的方针检测框架其实也是根据yolov1的。
小结
那么关于理论部分咱们就先到这儿,这儿面的话仍是有许多细节是没有说到的,例如Fast rcnn 里边,咱们NMS处理以后,咱们的那些剩下的框虽然是知道了所属的分类,但是咱们回归的时分咱们是和那些手动标示的框进行回归?这部分我没有说,因为篇幅问题,这部分也是需求读者自行探索,其实读者也能够斗胆猜想一下和IOU有没有联系咧?此外还有其他的优秀算法没有介绍到,比方SSD等等。
当然前面的大部分内容仅仅做了解即可,因为愈加完整的将在代码部分进行。