SegmentAnythingModel
類別keras_cv.models.SegmentAnythingModel(
backbone, prompt_encoder, mask_decoder, **kwargs
)
任意分割 (SAM) 模型。
參數
參考文獻
範例
>>> import numpy as np
>>> from keras_cv.src.models import ViTDetBBackbone
>>> from keras_cv.src.models import SAMPromptEncoder
>>> from keras_cv.src.models import SAMMaskDecoder
建立 SAM 模型的所有組件
>>> backbone = ViTDetBBackbone()
>>> prompt_encoder = SAMPromptEncoder()
>>> mask_decoder = SAMMaskDecoder()
實例化模型
>>> sam = SegmentAnythingModel(
... backbone=backbone,
... prompt_encoder=prompt_encoder,
... mask_decoder=mask_decoder
... )
定義骨幹的輸入。對於我們正在使用的 ViT 骨幹,這必須是一批形狀為 (1024, 1024, 3)
的影像。
>>> image = np.ones((1, 1024, 1024, 3))
SAM 通過提示輸入影像來工作。有三種提示方式
(1) 標記點:前景點(標籤為 1 的點)經過編碼,以便遮罩解碼器生成的輸出遮罩包含它們,而背景點(標籤為 0 的點)經過編碼,以便生成的遮罩不包含它們。(2) 框:框告訴模型要分割影像的哪個部分/裁剪。(3) 遮罩:輸入遮罩可用於細化遮罩解碼器的輸出。
這些提示可以混合和匹配,但必須至少存在一個提示。若要關閉特定提示,只需將其從模型的輸入中排除即可。
TODO(ianstenbit):移除對 1
軸的需求,並修復框形狀
.
(1) 對於點提示,預期形狀為 (批次大小, 點數, 2)
。標籤必須具有相應的形狀 (批次大小, 點數)
。(2) 對於框提示,預期形狀為 (批次大小, 1, 2, 2)
。(3) 同樣,遮罩提示的形狀為 (批次大小, 1, 高度, 寬度, 1)
。
例如,若要傳入所有提示,請執行以下操作
>>> points = np.array([[[512., 512.], [100., 100.]]])
>>> # For labels: 1 means foreground point, 0 means background
>>> labels = np.array([[1., 0.]])
>>> box = np.array([[[[384., 384.], [640., 640.]]]])
>>> input_mask = np.ones((1, 1, 256, 256, 1))
準備輸入字典
>>> inputs = {
... "images": image,
... "points": points,
... "labels": labels,
... "boxes": box,
... "masks": input_mask
... }
...
>>> outputs = sam.predict(inputs)
>>> masks, iou_pred = outputs["masks"], outputs["iou_pred"]
輸出 ```masks``` 中的第一個遮罩(即 ```masks[:, 0, ...]```)是模型根據提示預測的最佳遮罩。其他 ```masks```(即 ```masks[:, 1:, ...]```)是替代預測,如果需要可以使用它們來取代第一個遮罩。
現在,如果只有點和框提示,只需排除遮罩
>>> inputs = {
... "images": image,
... "points": points,
... "labels": labels,
... "boxes": box,
... }
...
>>> outputs = sam.predict(inputs)
>>> masks, iou_pred = outputs["masks"], outputs["iou_pred"]
TODO(ianstenbit): 移除對此填補的需求
.
另一個例子是僅存在點提示。請注意,如果存在點提示但不存在框提示,則必須使用零點和 -1 標籤來填補這些點
>>> padded_points = np.concatenate(
... [points, np.zeros((1, 1, 2))], axis=1
... )
...
>>> padded_labels = np.concatenate(
... [labels, -np.ones((1, 1))], axis=1
... )
>>> inputs = {
... "images": image,
... "points": padded_points,
... "labels": padded_labels,
... }
...
>>> outputs = sam.predict(inputs)
>>> masks, iou_pred = outputs["masks"], outputs["iou_pred"]
請注意,Segment Anything 模型目前僅支援推論,尚不支援訓練。因此,呼叫 ```fit``` 方法目前將會失敗。
SegmentAnythingModel.from_preset()
從預設配置和權重實例化 SegmentAnythingModel 模型。
參數
範例
# Load architecture and weights from preset
model = keras_cv.models.SegmentAnythingModel.from_preset(
"resnet50_imagenet",
)
# Load randomly initialized model from preset architecture with weights
model = keras_cv.models.SegmentAnythingModel.from_preset(
"resnet50_imagenet",
load_weights=False,
預設名稱 | 參數 | 說明 |
---|---|---|
sam_base_sa1b | 93.74M | 在 SA1B 資料集上訓練的基本 SAM 模型。 |
sam_large_sa1b | 312.34M | 在 SA1B 資料集上訓練的大型 SAM 模型。 |
sam_huge_sa1b | 641.09M | 在 SA1B 資料集上訓練的巨型 SAM 模型。 |
keras_cv.models.SAMMaskDecoder(
transformer_dim=256,
transformer=None,
num_multimask_outputs=3,
iou_head_depth=3,
iou_head_hidden_dim=256,
activation="gelu",
**kwargs
)
Segment Anything Model (SAM) 的遮罩解碼器。
這個輕量級模組有效地將圖像嵌入和一組提示嵌入映射到輸出遮罩。在應用 Transformer 解碼器之前,該層首先將一個學習到的輸出標記嵌入插入到提示嵌入集中,該嵌入將在解碼器的輸出中使用。為了簡單起見,這些嵌入(不包括圖像嵌入)統稱為「標記」。
圖像嵌入、位置圖像嵌入和標記會被傳遞到 Transformer 解碼器。在運行解碼器後,該層使用兩個轉置卷積層將更新後的圖像嵌入放大 4 倍(現在它相對於輸入圖像縮小了 4 倍)。然後,標記再次關注圖像嵌入,並且更新後的輸出標記嵌入被傳遞到一個小型 3 層 MLP,該 MLP 輸出與放大圖像嵌入的通道維度匹配的向量。最後,通過放大圖像嵌入和 MLP 輸出的空間逐點乘積來預測遮罩。
參數
256
。None
。當為 None
時,將使用 keras_cv.models.TwoWayTransformer
層。1 + num_multimask_outputs
。默認為 3
。3
。256
。"gelu"
。參考文獻
SAMPromptEncoder
類別keras_cv.models.SAMPromptEncoder(
embed_dim=256,
image_embedding_size=(64, 64),
input_image_size=(1024, 1024),
mask_in_chans=16,
activation="gelu",
**kwargs
)
用於分割一切模型 (SAM) 的提示編碼器。
提示編碼器為三種類型的提示生成編碼
首先,將點提示和框提示連接起來,並使用隨機空間頻率生成位置編碼。一個點表示為該點位置的位置編碼和兩個學習嵌入之一的總和,這兩個學習嵌入指示該點是在前景還是在背景。一個框由一個嵌入對表示
(1)其左上角的位置編碼與表示「左上角」的學習嵌入相加,以及(2)相同的結構,但使用表示「右下角」的學習嵌入。
框和點編碼稱為「稀疏編碼」
如果傳遞了遮罩提示,則使用卷積神經網路對其進行縮小以生成「密集編碼」。如果沒有傳遞遮罩提示,則使用嵌入層來生成「無遮罩」嵌入。
參數
256
。(64, 64)
。(1024, 1024)
。16
。"gelu"
。參考文獻
TwoWayTransformer
類別keras_cv.models.TwoWayTransformer(
depth=2,
embed_dim=256,
num_heads=8,
mlp_dim=2048,
activation="relu",
attention_downsample_rate=2,
**kwargs
)
雙向交叉注意力 Transformer 解碼器。
一種 Transformer 解碼器,它使用位置嵌入提供的查詢來關注輸入圖像。
轉換器解碼器的設計如 [1]_ 所示。每個解碼器層執行 4 個步驟:(1) 權杖的自注意力機制,(2) 從權杖(作為查詢)到圖像嵌入的交叉注意力機制,(3) 以逐點 MLP 更新每個權杖,以及 (4) 從圖像嵌入(作為查詢)到權杖的交叉注意力機制。最後一個步驟使用提示信息更新圖像嵌入。每個自注意力/交叉注意力機制和 MLP 都有殘差連接和層歸一化。
為了確保解碼器能夠訪問關鍵的幾何信息,每當位置編碼參與注意力層時,它們就會被添加到圖像嵌入中。此外,每當原始提示權杖(包括其位置編碼)參與注意力層時,它們都會被重新添加到更新後的權杖中。這允許對提示權杖的幾何位置和類型產生強烈的依賴性。
參數
2
。256
。8
。2048
。"relu"
。2
。參考文獻
MultiHeadAttentionWithDownsampling
類別keras_cv.layers.MultiHeadAttentionWithDownsampling(
num_heads, key_dim, downsample_rate=1, **kwargs
)
具有下採樣的多頭注意力機制。
一種注意力層,允許在投影到查詢、鍵和值後縮減嵌入的大小。
此層首先使用密集層縮減輸入查詢、鍵和值的特徵。然後執行多頭注意力機制,並將注意力圖投影回(放大)到輸入特徵的數量。
參數
鍵維度
的輸入特徵被投影到 鍵維度 // 下採樣率
。參考文獻
TwoWayMultiHeadAttention
類別keras_cv.layers.TwoWayMultiHeadAttention(
num_heads,
key_dim,
mlp_dim,
skip_first_layer_pe,
attention_downsample_rate=2,
activation="relu",
**kwargs
)
雙向多頭注意力層。
參數
參考文獻
RandomFrequencyPositionalEmbeddings
類別keras_cv.layers.RandomFrequencyPositionalEmbeddings(
num_positional_features, scale, **kwargs
)
使用隨機空間頻率的位置編碼。
此層使用隨機空間頻率將 2D 空間中的坐標/點映射到位置編碼。
參數
參考文獻