
【斯坦福CS231n 学习笔记6】检测、分割、可视化、理解
学习了传统计算机视觉的另外三大任务以及如何对计算机视觉任务进行可视化理解。
语义分割的任务是输入一张 RGB 图像 ,输出一张同尺寸的分割图 ,输出图中的每一个像素点 都被分配一个类别标签 (为预定义的类别总数,通常包含背景类)。
主要的特征是像素级分类(不输出边界框,而是对每个像素进行密集预测)与不区分实例(如果图像中有多个同类型实例,则将其标记为同一类型,不区分具体实例)。
在深度学习应用于分割的早期,直观的思路是将分割视为对每个像素的独立分类问题。为了对像素 进行分类,取以该像素为中心的一个固定大小的 Patch(例如 crop 出一块区域 ),将其输入到分类网络(CNN)中,以预测中心像素的类别。
但是这种方法需要对图像中的每一个像素都执行一次完整的 CNN 前向传播,图像的像素数量往往较多,且相邻的 Patch 之间存在大量重叠区域,导致特征提取计算冗余,计算成本过高,并不具备工程上的可行性。
为解决滑动窗口的效率问题,提出全卷积网络的设计思想。传统的分类网络(如 AlexNet/VGG)在末端通常是若干全连接层,其要求输入是固定长度的向量,因此也破坏了空间结构,而全卷积网络的思想就是,全连接层可以视作一种特殊的卷积层,假设在进入 FC 之前,有一个形状为 的特征张量,将其展平后接一个 FC 得到 维输出,那么这个 FC 的权重矩阵形状等价于 ,现在反过来理解:相当于用 个卷积核,每个卷积核空间尺寸恰好是 ,通道数是 ,在该特征图上做一次卷积,得到 的输出,即全连接层等价于卷积核覆盖整个输入的卷积,但是在将 FC 替换为卷积之后,网络就不再要求固定输入尺寸,输入特征图如果更大,那么卷积就会在不同的空间位置中产生输出,从而给出一个空间网格上的类别得分图。
但是这样也会存在一个问题:当分类网络卷积化之后,得到一个空间尺寸很小的得分图,例如输入可能是 ,但是输出可能只有 ,虽然实现了预测,但是预测的网络很长粗糙,每个输出位置对应输入图像中的一个较大的感受野区域,输出更像是一个比较粗糙的块装分割,因为分类网络体系为了获得大的感受野和语义网络抽象,会反复 stride/pooling,从而将空间尺寸压下去。
这一类方法不需要学习参数,计算较为简单,能够把空间的尺寸恢复,但是本质上是几何差值,不会恢复被下采样抹除的边界细节,只能把粗糙块状预测变平滑或变细网格,细节仍来自原来的粗网格。
可学习上采样主要采用的是转置卷积。在标准卷积中是输入区域与卷积核做点积得到一个标量输出,而在转置卷积中,是输入的一个标量与卷积核(权重矩阵)相乘,将结果投射到输出的较大区域上。
其中转置卷积的 stride 定义了输出特征图放大的倍数,例如 Stride=2 的转置卷积会将空间分辨率放大 2 倍。当多个输入标量的投射区域在输出图上发生重叠,重叠部分的数值进行累加。由于其权重是可训练的,网路可以自适应地学习最佳的上采样方式,而非使用固定的插值算法。
即使使用了转置卷积,如果仅依靠 Decoder 从高度压缩的 bottleneck 特征中恢复细节,效果仍然有限,因为下采样的过程中丢失的高频信息是不可逆的。
U-Net 提出了一种解决方案来提升分割精度:
目标检测的任务是在图像中定位物体,输出 Bounding Box 和类别标签。输出不再是固定形状的网格或向量,而是一组数量不定的对象,每个对象都要携带类别与几何信息,且对象之间还会发生“竞争”和“去重”的推理逻辑。
检测的监督信号通常是对一张图,给出若干个目标实例,每个实例包含一个类别 和一个边界框 。边界框常见参数化形式是 或者 。与分类/语义分割在数学形态上不同的是,分类输出是固定维度的向量,语义分割输出的是固定尺寸的像素网络,检测输出是一个集合,集合大小随着图像内容的变化而变化。这意味着模型在训练和推理时需要解决两个额外问题,一是如何让网络在固定的计算图中表达数量可变的结果,二是如何将预测与标注建立对应关系。
假设图中只有一个目标,任务就偏向于“分类+回归”:网络输出一个类别分数向量外加四个回归值表示识别框的位置,这个设定下的监督对其非常直接,因为输出的框天然对应唯一的框,损失也可以简单地拆分称为分类损失与边界框回归损失。
但是一旦进入多目标检测,由于图里的目标数量不定、类别混杂、目标尺度差异巨大,相互遮挡与重叠普遍存在,且必须输出很多候选框,再决定哪些是有效目标、哪些是背景、以及同一目标的重复预测如何合并。
朴素方法也是通过简单的滑动窗口来进行目标检测,通过训练一个 CNN,输入图像的一个 Patch,输出是背景还是某种物体,而后在原图上以不同的大小和长宽比进行密集滑动,对每个裁剪区域运行 CNN。这样的计算复杂度是灾难性的,需要运行成千上万次 CNN 前向传播,且绝大多数窗口都是背景,效率低下。
为了解决滑动窗口的低效,引入了 Region Proposals,利用图像处理中的非学习方法(基于纹理、颜色、强度等低级特征),在图像中快速提取出约 2000 个可能包含物体的候选框。这样能够将搜索空间从数百万个窗口降低到几千个。
对于一张输入图像,先使用 Region Proposals 生成大约 2000 个 Regions of Interest(RoI),此处的 proposal method 通常是 Selective Search 这类传统视觉算法,其意义是将“连续巨大且稀疏的框空间”离散化为一个相对可处理的候选集合,将检测问题从无限多框中找目标变为在 2000 多个候选区域中判断哪些是目标。
由于 CNN 分类网络通常要求固定输入尺寸,因此每个 RoI 都要被强制缩放成固定大小,之后才能送入卷积网络,这会改变候选区的几何比例,但是此阶段不关心几何细节,而在于检测。
对每个 RoI 单独前向通过一个 ConvNet,得到一个特征向量,然后用 SVMs 对区域进行分类,使用 Bbox reg 分支预测对 RoI 的修正量 ,即将 proposal 当成一个粗框,然后通过回归预测将框中心平移多少,宽高缩放多少,从而更加贴近 ground-truth 框,本质上是一个条件回归。
但是这个 R-CNN 的问题是慢,每张图都要对大约 2000 个 RoI 做独立的卷积网络前向传播,且相邻的 RoI 在同一张图上高度重叠,但是特征却没有共享,并且这个方法不是端到端的:RoI 提取、CNN、SVM、回归器是独立训练的,无法进行联合优化。
为了解决 Slow R-CNN 重复计算的问题,Fast R-CNN 提出特征共享机制,先对整张图进行一次卷积计算得到高分辨率特征图,然后再去裁剪 RoI 对应的卷积特征,而不是对每个 RoI 重复进行卷积。
输入图像先经过 backbone 得到一张较低分辨率但是语义更强的特征图,与此同时,仍然从外部的 proposal method 得到 RoIs,然后在特征图上对每个 RoI 做裁剪和缩放特征,将每个 RoI 映射为一个固定大小的 RoI 特征张量,Fast R-CNN 的输出头一支输出 Object category,另一支输出 Box offset,从特征提取与分类器/回归器分离转向在一个网络中多任务联合学习,同一份 RoI 特征同时服务于分类与框回归,训练过程更加端到端,且分类分支与回归分支共享特征,可以让回归更加稳定、分类更一致,由于 backbone 只进行一次,速度更快。
但是由于仍然保留了外部的 proposal method,导致系统速度虽然比 Slow R-CNN 快很多,但是还是被 proposal 生成所限制,成为速度瓶颈。
为了移除 Selective Search 这个最后的瓶颈,提出了 RPN(Region Proposal Network),将外部的 proposal method 替换为一个可学习、可端到端训练、速度更快的模块。
在特征图的每个空间位置,“想象”放置一个固定大小的 anchor box,这个 anchor 的意义是将连续的框回归问题参数化为“围绕某个参考框”的相对变换,不需要在无限多框里盲猜,而是在每个位置上,从若干个参考框出发预测其是否可能包含目标以及如何微调到更贴近真实框。
RPN 主要有两类输出:
R-CNN 都是两个阶段,RPN 产生稀疏 proposals,然后 RoI head 做分类回归。而单阶段目标检测的切入点是,本来就在 backbone 输出的特征图上做卷积,那也能在特征图上的每个空间位置上预测这里有没有目标、是什么类别、边界框怎么回归,从而不需要显式的 proposal 集合,也不需要 RoI Pool/Align 的裁剪与对齐过程。
以 YOLO v1 为例,首先将输入图像划分为 的网格,如果一个物体的中心点落入某个网格,该网格就负责检测该物体。每个网格预测 个边界框和 个类别概率,每个边界框包含 5 个预测值: 和 Confidence(置信度)。输出的张量的维度为 。其中置信度是一个显式定义的数学量,反映了模型对“该框内含有物体”的信心以及预测框的准确度:
如果网格内无物体,则 , 置信度取向 0,如果网格内有物体,,置信度趋向预测框与真实框的交并比。
每个网格单元预测一组条件类别概率:
即假设网格内存在物体,其是第 类的概率是多少。
为了衡量特定位置存在特定类别物体的可能性,需要计算置信度与条件类别概率的联合概率:
得到上述得分后,会面临冗余检测问题。对于一个图像中的一个目标,由于 CNN 的空间平移特性,目标中心附近的多个网格单元可能都会被激活,并且都预测了针对该目标的边界框,而要做的是对于同一个物体,只保留一个最佳的预测框,抑制其他重叠的冗余框。YOLO 使用非极大值抑制 (Non-Maximum Suppression, NMS) 算法,对于类别 ,要处理的所有预测框的集合 ,对应的置信度得分为 。首先移除所有得分低于设定阈值的框,这可以大幅减少后续计算量,去除明显的背景噪声,然后进入迭代循环,直至 为空:
DETR 彻底摒弃了传统检测器中复杂的手工设计组件,将目标检测重新定义为一个直接集合预测问题。
传统的检测器是密集预测:在特征图中的每个像素或网格上进行预测,产生数千个候选框,最后通过 NMS 过滤。而 DETR 使用集合预测,设定一个固定的预测数量 ,模型一次性并行输出 个预测结果,这 个预测结果是一个无序集合,无需后续的去重操作。
DETR 主要由三部分组成:
Decoder 输出的 个解码向量分别输入到两个独立的前馈网络(FFN):
确保每个真实物体都匹配到一个对其预测效果最好的 Query,且不会有多个 Queries 匹配同一个 GT。在确定匹配关系后,计算最终的 Loss:
Instance Segmentation 的任务就是区分实例,且需要像素级边界,每个实例一张 mask。
Mask R-CNN 就是在 Faster R-CNN 的基础上在 RoI head 上再加上第三条 mask 分支,输出一个固定分辨率的二值 mask(或类别条件 mask),输出按照 RoI 对齐,并不是对整张图输出一张大 mask 图,而是对每个候选的实例输出一张小的 mask,然后再映射回原图的对应的框区域。
其中最重要的技术就是 RoI Align,因为实例分割对空间对齐极其敏感。传统的 Fast/Faster R-CNN 中,RoI Pooling 用于将不同尺寸的特征图区域下采样为固定尺寸,涉及两次量化,分别是将浮点数的 RoI 坐标映射到特征图的整数坐标;将特征图区域划分为网格时,网格边界的取整。这种取整导致了空间不对齐,对于分割任务这种偏差会导致生成的 Mask 与原图物体在位置上无法重合。
RoI Align 全程保留浮点数精度,当需要获取某个浮点数坐标 处的特征值时,不进行四舍五入,而是找到坐标周围最近的 4 个整数网格点,利用 4 个点的数值进行双线性插值,计算出该浮点坐标处的精确值,以修复特征图与原图之间的空间对应关系,显著提升了 Mask 的边缘精度。
卷积核的滤波器就是可学习参数,对于第一层卷积,滤波器的输入通道就是图像的 RGB 三通道,因此滤波器权重与像素空间有直接对应关系,可以将一个第一层 filter 写成 ,对局部的 的 RGB patch 做加权求和,输出一个响应值,由于输入就是颜色像素,可以将 可视化为一张小彩色图片,就能够直观判断这个 filter 在检测什么。
但是随着层数的深入,滤波器的输入通道不再是 RGB,而是上一层产生的特征通道,深层滤波器的每个通道都对应一种抽象特征的激活,而不是人类可以直接解释的颜色像素,无法使用人类视觉直觉解释。
第一层卷积的可视化是从看参数长什么样出发,而 Saliency maps 则从对于某个具体的输出,输入图像中的哪些像素或区域对此输出贡献最大出发。
网络是一个函数 ,输入图像是 ,输出是某个类别 的得分,如果想要直到输入中哪个部分最影响这个得分,最直接的局部近似就是一阶泰勒展开:
此处的 即为当轻微改变这个像素时,得分会如何变化的敏感度,于是梯度的绝对值大,意味着该像素对该类别得分影响更强。
具体来说 saliency map 会先通过前向计算得到类别得分 ,而后对输入像素求梯度 ,其中 的形状与输入图像一样 。最后再对三通道梯度合并为一个单通道热度图(通常是对通道取最大值或取 范数):
或
最后再将 归一化,并且叠加到原图上显示。
CAM 是最早提出的一种利用全局平均池化来实现定位的技术,其核心思想是利用网络架构的特殊性,通过线性加权组合特征来生成热力图。
不过其并不适合所有的网络,要求网络必须具有特定的结构:
将 展开,得到
而后将换求和顺序:
其中括号内的部分 即为 CAM 热力图在 处的值:
CAM 的本质就是特权图的加权线性组合, 代表了第 个特征图对类别 的重要性,如果 很大且为正,说明第 个特征图强烈支持类别 ,将所有特权图按照权重叠加,就得到了模型关注的区域。
但是 CAM 必须要修改网络结构,对于 VGG 这一类以 Flatten+Dense Layer 结尾的网络,必须移除全连接层重新训练一个带有 GAP 的网络,成本高且破坏了原有的参数分布。
为了解决需要修改网络重新训练的问题,Grad-CAM 使用梯度取代全连接层的权重 来表示“特征图的重要性”。
Grad-CAM 首先需要计算梯度,进行一次前向传播得到类别 的得分 ,然后将 对最后一层卷积层的特征图 进行反向传播,计算梯度:
为了得到第 个特征图整体的重要性权重 ,Grad-CAM 对梯度图进行全局平均池化:
最后再进行加权组合与 ReLU,利用计算出的权重 对特征图 就进行加权求和,并应用 ReLU 激活函数:
加上 ReLU 的作用是我们只对分类有正向影响的特征感兴趣,ReLU 能够过滤掉负值,去除掉抑制类别 的得分的权重。
Transformer 相比于复杂的梯度计算来猜测网络关注点哪里不同,天然具有更高的可解释性。
由 Self-Attention 公式 ,矩阵元素中的 直接给出了 Token i 对 Token j 的关注程度,可以通过直接提取并且可视化注意力图,而不需要任何额外的反向传播计算。
参考如下:
https://cs231n.stanford.edu/index.html