

本系列为 斯坦福CS231n 《深度学习与计算机视觉(Deep Learning for Computer Vision)》的全套学习笔记,对应的课程视频可以在 这里 查看。更多资料获取方式见文末。
ShowMeAI在前面的内容中给大家做了很多图像分类的介绍,主要围绕卷积神经网络(LeNet / AlexNet / NIN / VGG / Google / ResNet / MobileNet / squeezenet)讲解,但计算机视觉领域有其他一些更为复杂的任务,例如本篇开始介绍的目标检测(object detection)问题。
大家知道人工智能领域的3大热点方向是计算机视觉(CV,computer vision)、自然语言处理(Natural Language Process, NLP )和语音识别(Speech Recognition) 应用 。而计算机视觉领域又有图像分类、目标检测、图像分割三大任务,如下图所示

这3大任务其实对应机器视觉理解图像的3个主要层次:
图像分类任务中,我们要将图像识别判定为某个类别。它是最简单、最基础的图像理解任务,也是深度学习模型最先取得突破和实现大规模应用的任务。大家在前面也了解到了 ImageNet 这个权威评测集,每年的ILSVRC催生了大量的优秀深度网络结构,为其他任务提供了基础。
有一些其他的应用,包括人脸识别、场景识别等都可以化归为分类任务来解决。
图像分类任务关心整体图片类别,而目标检测则关注特定的物体目标,要求在图片中,同时识别出目标物的类别信息和位置信息(是一个classification + localization的问题)。
相比分类,目标检测任务要求我们需要从背景中分离出感兴趣的目标,并确定这一目标的描述(类别和位置),检测模型的输出形式通常是一个列表,列表的每一项使用一个数组给出检出目标的类别和位置(常用矩形检测框的坐标表示)。
图像分割包括语义分割(semantic segmentation)和实例分割(instance segmentation),前者是对前背景分离的拓展,要求分离开具有不同语义的图像部分(相当于像素级别的分类),而后者是检测任务的拓展,要求描述出目标的轮廓(相比检测框更为精细)。
分割是对图像的像素级描述,它赋予每个像素类别意义,适用于理解要求较高的场景,如无人驾驶中对道路和非道路的分割,医疗影像中对于不同区域的划分。
图像分类对应将图像划分为单个类别的过程,它通常对应于图像中最突出的物体。实际现实世界的很多图像通常包含多个物体,如果仅仅使用图像分类模型分配单一标签是非常粗糙的,并不准确。而目标检测(object detection)模型可以识别一张图片的多个物体,并可以给出不同物体的具体位置(边界框)。目标检测在很多场景有用,如无人驾驶和安防系统。
常见的经典目标检测算法如下图所示:

目标检测的基本思路是:解决定位(localization) + 识别(Recognition) 两个任务。
一个大致的pipeline如下图所示,我们可以用同样的特征抽取过程,借助两个不同的分支输出。

传统的目标检测框架,主要包括三个步骤:
现在主流的深度学习目标检测方法主要分为两类:两阶段(Two Stages)目标检测算法和一阶段(One Stage)目标检测算法。

上述两类方法,基于候选区域(Region Proposal)的方法(两阶段)在检测准确率和定位精度上占优,基于端到端(一阶段)的算法速度占优。相对于R-CNN系列的「两步走」(候选框提取和分类),YOLO等方法只「看一遍」。
我们在本篇中给大家介绍两阶段的目标检测方法,主要是R-CNN系列目标检测方法,在下篇内容目标检测 (SSD,YOLO系列)中给大家介绍一阶段的目标检测方法(YOLO系列,SSD等)。

如何将深度学习分类算法应用到目标检测?
R-CNN核心思想: 对每张图片选取多个区域,然后每个区域作为一个样本进入一个卷积神经网络来抽取特征。

R-CNN算法是较早提出的两阶段目标检测算法,它先找出 Region Proposal,再进行分类和回归。
对于每张输入的图像,R-CNN目标检测主要包括下述步骤:

R-CNN 的效果如下图所示,它有一些不足之处(也是系列算法后续改进的点):
优化方式为:

我们通过前面的 CNN 相关知识学习知道,CNN 的卷积层不需要固定尺寸的图像,而全连接层是需要固定大小的输入。所以当全连接层面对各种尺寸的输入数据时,就需要对输入数据进行 crop(抠图)或者 wrap(图像resize)操作。
在 R-CNN中,因为不同的 proposal 大小不同,所以需要先 resize 成相同大小再输入到 CNN 中。既然卷积层是可以接受任何尺寸的,可以在卷积层后面加上一部分结构使得后面全连接层的输入为固定的,这个「化腐朽为神奇」的结构就是 spatial pyramid pooling layer。
下图是 R-CNN 和 SPP-Net 检测流程的比较:

SPP-Net 和普通 CNN 的对比结构如下,在网络结构上,直接把 pool5 层替换成 SPP 层:

SPP-Net 的具体细节如下,由 features map 上确定的 region proposal 大小不固定,将提取的 region proposal 分别经过三个卷积 \(4 \ast 4\),\(2 \ast 2\),\(1 \ast 1\) ,都将得到一个长度为 21 的向量(21是数据集类别数,可以通过调整卷积核大小来调整),因此不需要对 region proposal 进行尺寸调整:

相比R-CNN,SPP-Net有两大优点。
① 通过「特征金字塔池化」模块,实现了 CNN 的多尺度输入,使得网络的输入图像可以是任意尺寸的,输出则不变,同样是一个固定维数的向量。
② R-CNN 要对每个区域计算卷积,而 SPPNet 只需要计算一次卷积,从而节省了大量的计算时间。
对于 RCNN 速度过慢等问题,提出了基于 RCNN 的改善模型 Fast RCNN。
Fast RCNN 主要改进以下部分:
如下图所示为Fast R-CNN流程与网络结构

Fast R-CNN具体包括的核心环节如下:
跟RCNN一样,Fast-RCNN 采用的也是 Selective Search 的方法来产生 Region Proposal,每张图片生成 2k 张图片。但是不同的是,之后不会对 2k 个候选区域去原图截取,后输入 CNN,而是直接对原图进行一次 CNN,在 CNN 后的 feature map,通过 ROI project 在 feature map 上找到 Region Proposal的位置。
就是对原图输入到 CNN 中去计算,Fast-RCNN 的工具包提供提供了 3 种 CNN 的结构,默认是使用 VGG-16 作为 CNN 的主干结构。根据 VGG-16 的结构,Fast-RCNN 只用了 4 个 MaxPooling 层,最后一个换成了 ROI Pooling,因此,只需要对 Region Proposal 的在原图上的 4 元坐标 \((x, y, w, h)\) 除以 \(16\),并找到最近的整数,便是 ROI Project 在 feature map 上映射的坐标结果。最终得到 \(2k\) 个 ROI。
对每一个 ROI 在 feature map 上截取后,进行 ROI Pooling,就是将每个 ROI 截取出的块,通过 MaxPooling 池化到相同维度。
ROI Pooling的计算原理是,将每个不同大小的 ROI 平均划分成 \(7 \times 7\) 的 grid,在每个 grid 中取最大值,最后所有 ROI 都会池化成大小为 \(7 \times 7\) 维度。
将每个 ROI Pooling 后的块,通过全连接层生成 ROI 特征向量,最后用一个 Softmax 和一个 bbox regressor 进行分类和回归预测,得到每个 ROI 的类别分数和 bbox 坐标。全连接层为矩阵相乘运算,运行消耗较多,速度较慢,作者在这里提出可以使用 SVD 矩阵分解来加快全连接层的计算。
Fast-RCNN 的两个任务:

Fast R-CNN 效果如上图所示,相比之 R-CNN 它在训练和预测速度上都有了很大的提升,但它依旧有不足之处,大家观察整个流程,会发现在候选区域选择上,依旧使用的 Selective Search 方法,它是整个流程中的时间消耗瓶颈,无法用 GPU 硬件与网络进行加速。
Faster-RCNN 在 Fast-RCNN 的基础上做了两个重大的创新改进:

Faster R-CNN的总体流程结构如下,可分为Backbone、RPN、ROI+分类 / 回归 三个部分。


Anchor 是图像检测领域一个常用的结构,它可以用来表示原图中物体所在的区域,是一个以feature map 上某个点为中心的矩形框。
Faster-RCNN 的 anchor,在 feature map 上每个点,生成 3 种尺度和 3 种比例共 9 个 anchor。


RPN 是一个全卷积的神经网络,它的工作原理可以分成 classification,regression 和 proposal 三个部分
Classification 部分将得到的 feature map 通过一个 \(3 \times 3\) 和 \(1 \times 1\) 的卷积后,输出的维度为 \([1 \times 18 \times 38 \times 50]\),这18个channel可以分解成 \(2\times9\),2代表着是否是感兴趣物体备选区域(region proposal)的 0/1 的 score,9 代表着 9 个 anchors。
因此,特征图维度 \(38\times50\) 的每一个点都会生成 9 个 anchor,每个 anchor 还会有 0/1 的 score。
Regression 部分原理和 Classification 部分差不多,feature map通过一个 \(3 \times 3\) 和 \(1 \times 1\) 的卷积后,输出的维度为 \([1 \times 36 \times 38 \times 50]\),其中 36 个channel可以分成 \(4 \times 9\),9就是跟 cls 部分一样的 9 个anchor,4 是网络根据 anchor 生成的 bbox 的 4 元坐标 target 的 offset。通过 offset 做 bbox regression,再通过公式计算,算出预测 bbox 的 4 元坐标 \((x, y, w, h)\) 来生成 region proposal。
将前两部分的结果综合计算,便可以得出 Region Proposals。
一般来说,前景和背景的 anchor 保留的比例为 \(1:3\)

RPN 网络的训练样本有如下的策略和方式:

RPN 网络是监督学习训练,包含分类和回归两个任务,分类分支和回归分支的预测值和 label 构建方式如下:

RPN 网络的总体 loss 由 2 部分构成,分别是分类 loss 和回归 loss,为其加权求和结构。其中分类 loss 使用常规的交叉熵损失,回归损失函数使用的是 Smooth L1 Loss,本质上就是L1 Loss 和 L2 Loss 的结合。

特别说一下回归部分使用到的 Smooth L1 Loss,对比于 L1 Loss 和 L2 Loss,Smooth L1 Loss 可以从两方面限制梯度:

结合分类和回归结果得出 Region Proposals。若 anchor 的 \(IoU > 0.7\),就认为是前景;若 \(IoU < 0.3\),就认为是背景,其他的anchor全都忽略。一般来说,前景和背景的anchor保留的比例为 \(1:3\) 。
得到 Region Proposal 后,会先筛选除掉长宽小于 16 的预测框,根据预测框分数进行排序,取前N(例如6000)个送去 NMS,经过 NMS 后再取前 \(top_k\)(例如300)个作为 RPN 的输出结果。

候选框共享特征图特征,并保持输出大小一致。
候选框分为若干子区域,将每个区域对应到输入特征图上,取每个区域内的最大值作为该区域的输出。

在 ROI 映射中,涉及到 region proposal 的坐标映射变换问题,在这过程中难免会产生小数坐标。但是在 feature map 中的点相当于一个个的 pixel,是不存在小数的,因此会将小数坐标量化成向下取整,这就会造成一定的误差。
在 ROI Pooling 中,对每个 ROI 划分 grid 的时候又会有一次坐标量化向下取整。
这样,整个过程像素坐标会经过两次量化,导致 ROI 虽然在 feature map 上有不到 1 pixel 的误差,映射回原图后的误差可能会大于 10 pixel,甚至误差可能会大于整个物体,这对小物体的检测非常不友好。

Faster R-CNN 中通过 ROI Align 消除 RoI Pooling 中产生的误差。

ROI Align 的原理是,先将 ROI Project 和 ROI Pooling 时计算出的 ROI 带小数的坐标存储在内存中,不直接量化成像素坐标。
随后,ROI Align 不取每个 grid 的最大值,而是再将每个 grid 划分成 \(2\times2\) 的小格,在每个小格中找到中心点,将离中心点最近的四个点的值进行双线性差值,求得中心点的值,再取每个 \(grid\) 中四个中心点的最大值作为 \(Pooling\) 后的值。

下面是分类与回归的 BBox 头部分,它的处理流程展开后如下图所示:

而BBox训练阶段的样本构建方式如下,我们对比RPN阶段的样本构建方式:

BBox头的分类与回归任务的标签构建方式如下,其中分类分支是典型的分类问题,学习每个预测框的类别;回归分支则是学习每个 RoI 到真实框的偏移量。

BBox 头的总体 loss 由分类 loss 和回归 loss 加权组合构成。

Faster R-CNN的效果如下图所示

可以点击 B站 查看视频的【双语字幕】版本

我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题