SAM主要有图像编码器(image encoder)、提示编码器(prompt encoder)和掩码解码器(mask decoder)三部分构成,前两部分都比较直观,最后的掩码解码器(mask decoder)相对来说复杂一些。以下是搜集到的一些帮助理解掩码解码器(mask decoder)的资料。
文字讲解:
代码:
SAM之MaskDecoder总结(个人研究)_sam maskdecoder-CSDN博客
个人笔记内容:
在SAM(Segment Anything Model)中,mask decoder的output tokens由两部分组成:iou token和mask tokens。
-
iou token:这是一个特殊的token,用于预测模型输出的mask与真实mask之间的IoU(Intersection over Union)分数。IoU分数是一个衡量预测mask质量的指标,它计算预测mask和真实mask之间的交集与并集的比例。iou token通过一个单独的embedding层(
iou_token
)来生成,并且在Transformer模型的输出中占据第一个位置。 -
mask tokens:这些tokens对应于模型预测的每个可能的分割mask。在SAM模型中,为了处理可能的歧义,通常会生成多个候选mask(例如,默认情况下可能会生成三个)。每个mask token通过一个嵌入层(
mask_tokens
)生成,并且它们在Transformer模型的输出中紧随iou token之后。
在mask decoder的前向传播过程中,iou token和mask tokens会一起参与到Transformer的解码过程中。通过这种方式,模型可以同时预测mask的质量评估(通过iou token)和多个可能的分割mask(通过mask tokens)。最终,根据任务的需求和模型的配置,可以选择返回单一的最佳mask或者多个候选mask供进一步分析或决策。
在SAM(Segment Anything Model)中,mask decoder的iou token和mask tokens是可学习的嵌入,它们不是从图像或其他外部数据直接得来的,而是在模型训练过程中学习得到的。
-
iou token:这个token用于预测分割掩码的质量,即预测模型输出的掩码与真实掩码之间的IoU分数。在模型初始化时,iou token通过一个嵌入层(
iou_token
)随机初始化,然后在训练过程中通过反向传播算法进行调整,以便更好地预测掩码的质量。 -
mask tokens:这些tokens代表了模型可能生成的每个分割掩码。与iou token类似,mask tokens也是在模型初始化时通过嵌入层(
mask_tokens
)随机生成的,并且在训练过程中不断学习以优化模型的分割性能。
在模型的前向传播过程中,这些tokens与图像编码器(image encoder)和提示编码器(prompt encoder)的输出一起输入到mask decoder的Transformer结构中。通过这种方式,模型能够结合图像内容和提示信息来生成准确的分割掩码,并预测每个掩码的质量。这些tokens的可学习性质使得模型能够灵活地适应各种图像分割任务,并提高其泛化能力。
在SAM(Segment Anything Model)的源码中,iou token和mask token的初始化可以在`MaskDecoder`类的构造函数(`__init__`)中找到。以下是相关的代码段,其中详细展示了如何在`MaskDecoder`中初始化这些tokens:
class MaskDecoder(nn.Module):
def __init__(self, *, transformer_dim: int, transformer: nn.Module, num_multimask_outputs: int = 3,
activation: Type[nn.Module] = nn.GELU, iou_head_depth: int = 3,
iou_head_hidden_dim: int = 256,) -> None:
super().__init__()
self.transformer_dim = transformer_dim
self.transformer = transformer
self.num_multimask_outputs = num_multimask_outputs
self.iou_token = nn.Embedding(1, transformer_dim) # 初始化iou token
self.num_mask_tokens = num_multimask_outputs + 1 # 计算mask token的数量
self.mask_tokens = nn.Embedding(self.num_mask_tokens, transformer_dim) # 初始化mask tokens
# ... 其他组件的初始化 ...
在这段代码中,`iou_token`是通过`nn.Embedding`层创建的一个嵌入层,它接受1个输入token,并将其嵌入到`transformer_dim`维度的向量空间中。这个嵌入层的输出将代表IoU(Intersection over Union)预测的token。
`mask_tokens`同样是通过`nn.Embedding`层创建的,它初始化了`num_mask_tokens`个mask tokens。`num_mask_tokens`是`num_multimask_outputs`加1,其中`num_multimask_outputs`是模型预测时用于消除歧义的mask数量,默认值为3。这样,加上IoU预测的token,总共会有4个tokens(1个iou token和3个mask tokens)。
这些tokens在模型的前向传播过程中与图像特征和其他提示信息一起输入到Transformer中,用于生成分割掩码和预测它们的质量。初始化的tokens是可学习的,这意味着它们在模型训练过程中会根据数据进行调整,以便更好地执行图像分割任务。
标签:SAM,iou,mask,tokens,token,decoder,掩码,模型 From: https://blog.csdn.net/m0_46690805/article/details/137455944