天天看點

用自然語言分割一切圖像【lang-segment-anything】

作者:新缸中之腦

近年來,計算機視覺取得了顯着進步,特别是在圖像分割和目标檢測任務方面。 Segment Anything Model (SAM) 是最近的一項重大突破,這是一種多功能的深度學習模型,旨在有效地從圖像和輸入提示中預測對象掩碼。 通過利用強大的編碼器和解碼器,SAM 能夠處理範圍廣泛的分割任務,使其成為研究人員和開發人員等的寶貴工具。

用自然語言分割一切圖像【lang-segment-anything】
推薦:用 NSDT設計器 快速搭建可程式設計3D場景。

1、SAM簡介

SAM 使用圖像編碼器(通常是視覺轉換器 (ViT))來提取圖像嵌入,作為掩碼預測的基礎。 該模型還包含一個提示編碼器,它對各種類型的輸入提示進行編碼,例如點坐标、邊界框和低分辨率掩碼輸入。 然後将這些編碼的提示連同圖像嵌入一起輸入掩碼解碼器以生成最終的對象掩碼。

用自然語言分割一切圖像【lang-segment-anything】

上述架構允許在已經編碼的圖像上進行快速和輕便的提示。

SAM 旨在處理各種提示,包括:

  • Mask:可以提供一個粗糙的、低分辨率的二進制掩碼作為初始輸入來指導模型。
  • Point:使用者可以輸入 [x, y] 坐标及其類型(前景或背景)以幫助定義對象邊界。
  • Box:可以使用坐标 [x1, y1, x2, y2] 指定邊界框,以告知模型對象的位置和大小。
  • Text:文本提示也可用于提供額外的上下文或指定感興趣的對象。
用自然語言分割一切圖像【lang-segment-anything】

深入研究 SAM 的架構,我們可以探索其關鍵元件:

  • 圖像編碼器:SAM預設的圖像編碼器是ViT-H,但也可以根據具體要求使用ViT-L或ViT-B。
  • 下采樣:為了降低提示二進制掩碼的分辨率,采用了一系列卷積層。
  • 提示編碼器:位置嵌入用于對各種輸入提示進行編碼,這有助于告知模型圖像中對象的位置和上下文。
  • Mask 解碼器:修改後的 transformer 編碼器用作 mask 解碼器,将編碼的提示和圖像嵌入轉換為最終的對象掩碼。
  • 有效掩碼:對于任何給定的提示,SAM 都會生成三個最相關的掩碼,為使用者提供一系列可供選擇的選項。

他們使用 focal、dice 和 IoU 損失的權重組合來訓練模型。 權重分别為 20、1、1。

SAM 的優勢在于它的适應性和靈活性,因為它可以使用不同的提示類型來生成準确的分割掩碼。 與作為各種自然語言處理應用程式的強大基礎的基礎語言模型 (LLM) 非常相似,SAM 也為計算機視覺任務提供了堅實的基礎。 該模型的架構旨在促進下遊任務的輕松微調,使其能夠針對特定用例或領域進行定制。 通過針對特定任務資料微調 SAM,開發人員可以增強其性能并確定其滿足其應用程式的獨特要求。

這種微調能力不僅讓 SAM 在各種場景下都能獲得令人印象深刻的性能,而且還促進了更高效的開發過程。 以預訓練模型為起點,開發人員可以專注于針對他們的特定任務優化模型,而不是從頭開始。 這種方法不僅節省了時間和資源,而且還利用了預訓練模型中編碼的廣泛知識,進而使系統更加穩健和準确。

2、自然語言提示

文本提示與 SAM 的內建使模型能夠執行高度特定和上下文感覺的對象分割。 通過利用自然語言提示,可以引導 SAM 根據感興趣的對象的語義特性、屬性或與場景中其他對象的關系來分割感興趣的對象。

在訓練 SAM 的過程中,使用最大的公開可用的 CLIP 模型(ViT-L/14@336px)來計算文本和圖像嵌入。 這些嵌入在用于訓練過程之前被歸一化。

為了生成訓練提示,首先将每個掩碼周圍的邊界框擴充一個範圍為 1x 到 2x 的随機因子。 然後将展開的框裁剪成正方形以保持其縱橫比并将大小調整為 336×336 像素。 在将作物送入 CLIP 圖像編碼器之前,掩膜外的像素以 50% 的機率被清零。 Masked attention 在編碼器的最後一層使用,以確定嵌入集中在對象上,将輸出 token 的注意力限制在 mask 内的圖像位置。 輸出标記嵌入作為最終提示。 在訓練過程中,首先提供基于 CLIP 的提示,然後是疊代點提示以改進預測。

對于推理,未修改的 CLIP 文本編碼器用于為 SAM 建立提示。 該模型依賴于 CLIP 實作的文本和圖像嵌入的對齊,這使得在沒有顯式文本監督的情況下進行訓練,同時仍然使用基于文本的提示進行推理。 這種方法允許 SAM 有效地利用自然語言提示來實作準确和上下文感覺的分割結果。

不幸的是,Meta 還沒有釋出帶有文本編碼器的 SAM 的權重。

3、lang-segment-anything

lang-segment-anything 庫結合了 GroundingDino 和 SAM 的優勢,提供了一種創新的對象檢測和分割方法。

最初,GroundingDino 執行零樣本文本到邊界框對象檢測,根據自然語言描述有效地識别圖像中感興趣的對象。 然後将這些邊界框用作 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)
           
用自然語言分割一切圖像【lang-segment-anything】

4、Lightening應用

你可以使用 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())
           

就這樣,應用程式在浏覽器中啟動了!

用自然語言分割一切圖像【lang-segment-anything】

5、結論

這就是我們對 Segment Anything Model 的介紹。 很明顯,SAM 是計算機視覺研究人員和開發人員的寶貴工具,它能夠處理各種分割任務并适應不同的提示類型。 它的架構易于實施,使其具有足夠的通用性,可以針對特定的用例和領域進行定制。 總體而言,SAM 已迅速成為機器學習社群的重要資産,并且肯定會繼續在該領域掀起波瀾。

原文連結:http://www.bimant.com/blog/lang-segment-anything/

繼續閱讀