近年来,计算机视觉取得了显着的进步,特别是在图像分割和目标检测任务方面。 最近值得注意的突破之一是分段任意模型(SAM),这是一种多功能深度学习模型,旨在有效地从图像和输入提示中预测对象掩模。 通过利用强大的编码器和解码器,SAM 能够处理各种分割任务,使其成为研究人员和开发人员的宝贵工具。
推荐:用 NSDT编辑器 快速搭建可编程3D场景
SAM 使用图像编码器(通常是视觉变换器 (ViT))来提取图像嵌入,作为掩模预测的基础。 该模型还包含一个提示编码器,它对各种类型的输入提示进行编码,例如点坐标、边界框和低分辨率掩模输入。 然后将这些编码的提示与图像嵌入一起输入掩码解码器以生成最终的对象掩码。
上述架构允许对已编码的图像进行快速、轻松的提示。
SAM 设计用于处理各种提示,包括:
深入研究 SAM 的架构,我们可以探索其关键组件:
他们使用焦点、骰子和 IoU 损失的加权组合来训练模型。 权重分别为 20、1、1。
SAM 的优势在于其适应性和灵活性,因为它可以与不同的提示类型一起生成准确的分割掩模。 与作为各种自然语言处理应用程序的坚实基础的基础语言模型 (LLM) 非常相似,SAM 也为计算机视觉任务提供了坚实的基础。 该模型的架构旨在促进下游任务的轻松微调,使其能够针对特定用例或领域进行定制。 通过针对特定于任务的数据微调 SAM,开发人员可以增强其性能并确保其满足应用程序的独特要求。
这种微调能力不仅使 SAM 在各种场景中都能实现令人印象深刻的性能,而且还促进了更高效的开发过程。 以预训练模型为起点,开发人员可以专注于针对特定任务优化模型,而不是从头开始。 这种方法不仅节省时间和资源,而且还利用预训练模型中编码的广泛知识,从而形成更加强大和准确的系统。
文本提示与 SAM 的集成使模型能够执行高度具体且上下文感知的对象分割。 通过利用自然语言提示,SAM 可以根据感兴趣的对象的语义属性、属性或与场景中其他对象的关系来对其进行分割。
在训练 SAM 的过程中,使用最大的公开可用的 CLIP 模型(ViT-L/14@336px)来计算文本和图像嵌入。 这些嵌入在用于训练过程之前会被标准化。
为了生成训练提示,每个掩码周围的边界框首先按 1 倍到 2 倍范围内的随机因子扩展。 然后对展开的框进行方形裁剪以保持其纵横比,并将大小调整为 336×336 像素。 在将裁剪图像输入 CLIP 图像编码器之前,掩模外部的像素以 50% 的概率被清零。 编码器的最后一层使用屏蔽注意力,以确保嵌入集中在对象上,从而将输出标记的注意力限制到屏蔽内的图像位置。 输出标记嵌入作为最终提示。 在训练期间,首先提供基于 CLIP 的提示,然后提供迭代点提示以完善预测。
为了进行推理,使用未修改的 CLIP 文本编码器为 SAM 创建提示。 该模型依赖于 CLIP 实现的文本和图像嵌入的对齐,这使得无需显式文本监督即可进行训练,同时仍使用基于文本的提示进行推理。 这种方法使 SAM 能够有效地利用自然语言提示来实现准确且上下文感知的分割结果。
不幸的是,Meta 还没有发布带有文本编码器的 SAM 的权重(还没有?)。
lang-segment-anything 库结合了 GroundingDino 和 SAM 的优势,提出了一种创新的对象检测和分割方法。
最初,GroundingDino 执行零样本文本到边界框(text-to-bounding-box)对象检测,根据自然语言描述有效识别图像中感兴趣的对象。 然后,这些边界框用作 SAM 模型的输入提示,该模型为识别的对象生成精确的分割掩模。
from PIL import Image
from lang_sam import LangSAM
from lang_sam.utils import draw_image
model = LangSAM()
image_pil = Image.open('./assets/car.jpeg').convert("RGB")
text_prompt = 'car, wheel'
masks, boxes, labels, logits = model.predict(image_pil, text_prompt)
image = draw_image(image_pil, masks, boxes, labels)
你可以使用Lightning AI App框架快速部署应用程序。 我们将使用 ServeGradio 组件通过 UI 部署我们的模型。 你可以在此处了解有关 ServeGradio 的更多信息。
import os
import gradio as gr
import lightning as L
import numpy as np
from lightning.app.components.serve import ServeGradio
from PIL import Image
from lang_sam import LangSAM
from lang_sam import SAM_MODELS
from lang_sam.utils import draw_image
from lang_sam.utils import load_image
class LitGradio(ServeGradio):
inputs = [
gr.Dropdown(choices=list(SAM_MODELS.keys()), label="SAM model", value="vit_h"),
gr.Slider(0, 1, value=0.3, label="Box threshold"),
gr.Slider(0, 1, value=0.25, label="Text threshold"),
gr.Image(type="filepath", label='Image'),
gr.Textbox(lines=1, label="Text Prompt"),
]
outputs = [gr.outputs.Image(type="pil", label="Output Image")]
def __init__(self, sam_type="vit_h"):
super().__init__()
self.ready = False
self.sam_type = sam_type
def predict(self, sam_type, box_threshold, text_threshold, image_path, text_prompt):
print("Predicting... ", sam_type, box_threshold, text_threshold, image_path, text_prompt)
if sam_type != self.model.sam_type:
self.model.build_sam(sam_type)
image_pil = load_image(image_path)
masks, boxes, phrases, logits = self.model.predict(image_pil, text_prompt, box_threshold, text_threshold)
labels = [f"{phrase} {logit:.2f}" for phrase, logit in zip(phrases, logits)]
image_array = np.asarray(image_pil)
image = draw_image(image_array, masks, boxes, labels)
image = Image.fromarray(np.uint8(image)).convert("RGB")
return image
def build_model(self, sam_type="vit_h"):
model = LangSAM(sam_type)
self.ready = True
return model
app = L.LightningApp(LitGradio())
这样就可以了,应用程序在浏览器中启动!
这就是我们对分段任意模型的介绍的总结。 显然,SAM 对于计算机视觉研究人员和开发人员来说是一个有价值的工具,它能够处理各种分割任务并适应不同的提示类型。 其架构允许轻松实施,使其具有足够的通用性,可以根据特定的用例和领域进行定制。 总体而言,SAM 已迅速成为机器学习社区的重要资产,并且肯定会继续在该领域掀起波澜。
原文链接:文本提示目标检测与分割 — BimAnt