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