这里包含三种不同的encoder:点、框、mask(如果没有会默认使用无掩码嵌入)
这里点提示和框提示处理方法类似——核心都是位置编码,但是在处理方式上又存在些许的差异,因此这里把点提示和框提示放在一起进行对比介绍。
首先看点提示:
点提示(point prompts)在 PromptEncoder 类中传入的是点的位置坐标信息。点提示通常用于指定图像中某些关键点的位置,这些点可能对应于图像中的重要特征或对象的特定部分。在cv任务中,这些点可以用来引导模型的注意力,使其专注于图像的特定区域。
点提示在 PromptEncoder 的 forward 方法中作为一个可选参数传入,它是一个元组 points,其中包含两个 torch.Tensor 对象:
1.第一个张量包含点的坐标(coords),形状通常是 (batch_size, num_points, 2),其中 batch_size 是输入的批次大小,num_points 是每个输入中点的数量,最后的 2 表示每个点的 x 和 y 坐标。
2.第二个张量包含点的标签(labels),形状为 (batch_size, num_points)。这些标签用于区分不同的点,例如,可以标记正样本点、负样本点或其他类型的点。
在 _embed_points 方法中,点提示的坐标首先被加上 0.5 来将点的位置从像素的左上角移动到像素的中心。然后,这些坐标会通过位置编码层 PositionEmbeddingRandom 进行编码,以获得位置信息。最终,根据点的标签,特定的嵌入向量会被加到位置编码的点上,生成点提示的嵌入表示。
![](https://i-blog.csdnimg.cn/blog_migrate/4b34b9e22b54d569300c9efa707cf42b.png)
其次看框提示:
框提示(box prompts)在 PromptEncoder 类中传入的也是坐标信息,但它们表示的是框(通常称为边界框或bounding boxes)的坐标,而不是单个点的坐标。边界框通常用于描述图像中对象的位置和范围,它们通常是矩形的,由左上角和右下角的坐标定义,或者通过中心点加上宽度和高度来定义。
在 PromptEncoder 类的 forward 方法中,框提示作为 boxes 参数传入,它是一个 torch.Tensor 对象,其形状通常是 (batch_size, num_boxes, 4):
- batch_size 是输入的批次大小。
- num_boxes 是每个输入中框的数量。
- 其中4 表示每个框由四个坐标组成,通常是 (x1, y1, x2, y2),其中 (x1, y1) 是框左上角的坐标,(x2, y2) 是框右下角的坐标。
在 _embed_boxes 方法中,这些框的坐标首先被加上 0.5 来将框的位置从像素的左上角移动到像素的中心。然后,框的坐标被重塑为点坐标的形式,以便能够对框的每个角点进行位置编码。具体来说,每个框由两个点组成(左上角和右下角),因此通过 reshape(-1, 2, 2) 将框的坐标转换为 (batch_size * num_boxes, 2, 2) 的形状。
接着,使用 PositionEmbeddingRandom 的 forward_with_coords 方法对这些角点进行位置编码,以获得每个角点的位置信息。最后,根据角点的位置,将特定的嵌入向量加到位置编码的结果上,从而生成框提示的嵌入表示。
最后看Mask提示:
在 PromptEncoder 类中,_embed_masks 方法的输入是 masks 参数,它是 torch.Tensor 类型的。这个张量代表了输入的掩码数据,掩码数据通常用于指示图像中感兴趣的区域,比如在图像分割任务中用于指示前景和背景的区域。
“掩码数据”(masks)是一个 torch.Tensor 类型的对象,但它并不是直接表示图像数据的张量。相反,掩码数据通常是一个二进制或多类别的标记图(mask),用于在图像处理任务中指示特定的区域或对象。
掩码数据可以是:
- 二进制掩码:在图像分割任务中,二进制掩码通常用来区分前景和背景。在这种情况下,掩码数据的每个像素值会是0或1,其中0可能表示背景,而1表示前景对象。
- 多类别掩码:在更复杂的图像分割任务中,掩码数据可能会有多个类别,每个类别对 应于不同的对象或区域。在这种情况下,掩码数据中的每个像素值会是一个特定的整数, 表示该像素属于哪个类别。
以下是对mask提示的处理方式(简单来说就是使用了正常的卷积操作):
self.mask_downscaling 是一个预定义的 nn.Sequential 模型,它执行以下操作:
1.使用 nn.Conv2d 进行卷积操作以降低掩码的空间分辨率。
2.使用 LayerNorm2d 进行层归一化。
3.应用激活函数,这里使用的是 nn.GELU 或者在初始化时指定的其他激活函数。
4.最后,通过一个 1x1 的卷积层将掩码的特征映射到嵌入维度空间。
这样处理后的掩码嵌入可以捕捉到原始掩码数据的空间特征,并将其编码为一个适合于神经网络处理的紧凑表示形式。