国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[醫(yī)學(xué)分割大模型系列] (3) SAM-Med3D 分割大模型詳解

這篇具有很好參考價(jià)值的文章主要介紹了[醫(yī)學(xué)分割大模型系列] (3) SAM-Med3D 分割大模型詳解。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

論文地址:SAM-Med3D

開源地址:https://github.com/uni-medical/SAM-Med3D

發(fā)表日期:2023年10月

參考資料:

  1. 王皓宇(上海交通大學(xué))SAM-Med3D基于SAM構(gòu)建3D醫(yī)學(xué)影像通用分割模型
  2. SAM-Med3D:三維醫(yī)學(xué)圖像上的通用分割模型,醫(yī)療版三維 SAM 開源了!
  3. SAM-Med3D (SJTU 2024)

1. 特點(diǎn)

  • 通用分割能力:在各種3D目標(biāo)上精準(zhǔn)分割,效果明顯優(yōu)于SAM,SAM-Med2D(相對于切片進(jìn)行2D分割)
  • 更高的效率:比現(xiàn)有通用分割模型更快,提示需求更少(相對于切片進(jìn)行2D分割)
  • 遷移能力:作為預(yù)訓(xùn)練模型,在多個(gè)任務(wù)上效果良好
  • 模型輸入:要分割的圖像和一個(gè)/幾個(gè)提示點(diǎn)(提示點(diǎn)越多,效果越好)
  • 模型輸出:分割結(jié)果
  • 數(shù)據(jù)集:SAM-Med3D-130K數(shù)據(jù)集,擁有 131K 3D mask和 247 個(gè)類別
  • 網(wǎng)絡(luò)結(jié)構(gòu):類SAM,將結(jié)構(gòu)換成3D版本
  • 分割對象:3D醫(yī)學(xué)圖像

2. 背景

  • 3D醫(yī)學(xué)圖像:體素形式的3D圖像和標(biāo)注,以不同分布的灰度圖像為主
  • 任務(wù)特定模型的局限:
    • 沉重的訓(xùn)練負(fù)擔(dān):使用U-Net,UNETR等分割網(wǎng)絡(luò)在醫(yī)學(xué)數(shù)據(jù)集上訓(xùn)練,使用A100也需要2-7天
      醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
    • 泛化性弱
      使用特定數(shù)據(jù)集訓(xùn)練出來的模型(左列)在其他數(shù)據(jù)集上的表現(xiàn)(行)不佳
      醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
  • SAM在3D醫(yī)學(xué)分割的局限:
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
    • 由于醫(yī)學(xué)圖像知識(shí)的嚴(yán)重不足,將 SAM 直接應(yīng)用于醫(yī)學(xué)領(lǐng)域的有效性有限。解決這個(gè)問題的一種直接的方法是:將醫(yī)學(xué)知識(shí)融入到 SAM 中。比如,MedSAM 是一種典型示例,它通過使用110萬個(gè)掩碼(mask)對SAM 的解碼器(Mask Decoder)進(jìn)行微調(diào),從而使 SAM 能夠通過邊界框(Bounding Box)作為提示來更好地分割醫(yī)學(xué)影像;SAM-Med2D 則引入了適配器(Adapter)和約2000萬個(gè)掩碼(mask)對 SAM 進(jìn)行了充分微調(diào),從而在醫(yī)學(xué)圖像分割中表現(xiàn)出了卓越的性能。
    • 然而,這些方法必須采用逐切片(slice)的方法來處理三維醫(yī)學(xué)圖像,也即,將三維數(shù)據(jù)從某個(gè)維度分解為二維切片,然后獨(dú)立處理每個(gè)切片,最后將二維分割結(jié)果匯總為三維分割結(jié)果。這種方法忽略了切片之間的三維空間信息,因此在三維醫(yī)學(xué)影像上表現(xiàn)不佳,這一問題可以從上圖中的結(jié)果看出。SAM和SAM-Med2D都是一張張切片進(jìn)行分割,每張切片都需要一個(gè)提示,所以總共需要N個(gè)提示。對于一些切片,他們的表現(xiàn)不佳,從而導(dǎo)致空間信息的不連貫。
    • 除了將 SAM 直接應(yīng)用于三維數(shù)據(jù),一些研究人員希望通過引入二維到三維的適配器(Adapter)來捕捉三維空間信息。這些方法通常在保持編碼器(Image Encoder)不變的同時(shí)引入了三維適配器(Adapter),以使模型能夠從三維圖像中學(xué)習(xí)到三維空間信息。然而,這些方法存在兩個(gè)主要限制:(1)數(shù)據(jù)規(guī)模有限:這些方法的模型通常只在有限的數(shù)據(jù)規(guī)模下進(jìn)行訓(xùn)練(通常在1K到25K個(gè)mask范圍內(nèi)),并且只針對有限的目標(biāo)類型。這限制了模型的泛化性能和適用范圍。(2)凍結(jié)的二維編碼器:現(xiàn)有的三維 SAM-based 模型一直堅(jiān)守著凍結(jié)原始二維 SAM 編碼器(Image Encoder)的設(shè)計(jì)范式,這限制了模型全面建模三維空間信息的能力,大大限制了 SAM 在三維醫(yī)學(xué)圖像處理領(lǐng)域的發(fā)展?jié)摿Α?/li>

3. 訓(xùn)練數(shù)據(jù)集

3.1 數(shù)據(jù)集收集

醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型作者進(jìn)行了三維醫(yī)學(xué)圖像數(shù)據(jù)集的廣泛收集和標(biāo)準(zhǔn)化工作,整合了116個(gè)公開和私有的三維醫(yī)學(xué)圖像數(shù)據(jù)集,經(jīng)過4輪數(shù)據(jù)篩選和清晰,創(chuàng)建了迄今為止規(guī)模最大的三維醫(yī)學(xué)圖像分割數(shù)據(jù)集。該數(shù)據(jù)集包含了 2.1 萬個(gè)三維醫(yī)學(xué)圖像(病人數(shù)量)和 13.1 萬個(gè)三維掩碼(mask)。從下表可以清晰地看出,這一數(shù)據(jù)集的規(guī)模遠(yuǎn)遠(yuǎn)超過了現(xiàn)有最大的三維醫(yī)學(xué)圖像分割數(shù)據(jù)集,如 TotalSegmentator 和 BraTS21,其規(guī)模擴(kuò)大了 10 倍以上。
醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
該數(shù)據(jù)集涵蓋 27 種模態(tài)(CT 和 26 種MRI 序列)和 7 種解剖結(jié)構(gòu)。如下圖所?,共涵蓋了 247 個(gè)不同的類別,包括器官和病變。
醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型

3.2 數(shù)據(jù)清洗

醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
四步數(shù)據(jù)清洗:

  1. 基于元信息的數(shù)據(jù)清理 我們首先總結(jié)了所收集數(shù)據(jù)的元信息,包括每張醫(yī)學(xué)影像的深度、寬度和高度。我們刪除了所有物理尺寸小于 1 立方厘米或任何單個(gè)尺寸小于 1.5 厘米的病例,以確保目標(biāo)mask的可見性。
  2. 基于連接域的掩碼清理 在計(jì)算連通域的過程中,我們首先將原始的多類mask分割成多個(gè)類別的單擊格式。然后,我們計(jì)算每個(gè)單擊掩碼的前 5 個(gè)最大連通域的大小和背景。根據(jù)這些掩碼的匯總信息,我們會(huì)刪除背景占整個(gè)體積 99% 以上的mask。
  3. 基于連接域的標(biāo)簽質(zhì)量改進(jìn) 對于過濾后的mask,我們設(shè)計(jì)了一個(gè)基于連接域的pipeline來提高標(biāo)簽質(zhì)量。根據(jù)每個(gè)mask的前 5 個(gè)最大連通域的匯總信息,我們只需刪除小于這 5 個(gè)連通域的任何其他域,以減少噪音。
  4. 基于對稱性的標(biāo)簽質(zhì)量改進(jìn) 最后,我們將一些對稱目標(biāo)的mask拆分為不同類別的成對mask。例如,我們將 "腎 "的mask分為 "左腎 "和 “右腎”。這一步的目的是加強(qiáng)不同類別mask的語義一致性,防止模型分不清是分割整個(gè)結(jié)構(gòu)還是只分割單個(gè)的左右部分。為了解決這個(gè)問題,SAM 為每個(gè)提示生成多個(gè)預(yù)測,并采用額外的頭部生成分?jǐn)?shù),以方便選擇最合適的預(yù)測。鑒于醫(yī)學(xué)圖像的mask通常不那么模糊,我們選擇直接處理數(shù)據(jù)來消除這種模糊性,從而增強(qiáng)mask類別之間的語義一致性,降低網(wǎng)絡(luò)訓(xùn)練的復(fù)雜性。

3.3 模型微調(diào)數(shù)據(jù)集

目前SAM-Med3D-turbo是現(xiàn)已發(fā)布經(jīng)過微調(diào)的 SAM-Med3D 的最新版本checkpoint。在SAM-Med3D的基礎(chǔ)上又在 44 個(gè)數(shù)據(jù)集 ( 以下list )上對其進(jìn)行了微調(diào)以提高性能。

AMOS2022
ATM2022
AbdomenCT1K
BTCV_Cervix
BraTS2020
BraTS2021
BrainTumour
Brain_PTM
CAUSE07
CHAOS_Task_4
COSMOS2022
COVID19CTscans
CTPelvic1k
CT_ORG
FLARE21
FLARE22
Heart_Seg_MRI
ISLES_SISS
ISLES_SPES
KiPA22
KiTS
KiTS2021
LAScarQS22_task1
LAScarQS22_task2
LITS
MMWHS
MSD_Colon
MSD_HepaticVessel
MSD_Liver
MSD_Pancreas
MSD_Prostate
MSD_Spleen
PROMISE12
Parse22
Promise09
Prostate_MRI_Segmentation_Dataset
SLIVER07
STACOM_SLAWT
SegThor
Totalsegmentator_dataset
VESSEL2012
VerSe19
VerSe20
WORD

4. 模型結(jié)構(gòu)

醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
基于SAM修改后SAM-Med3D 的 3D 架構(gòu)。 原始2D組件被轉(zhuǎn)換為3D對應(yīng)組件,包括3D Image Encoder、3D Prompt Encoder 和3D mask Decoder。采用3D卷積、3D位置編碼(PE)和3D layer norm來構(gòu)建3D模型。

4.1 3D Image Encoder

在 3D 圖像編碼器中,首先使用內(nèi)核大小為 (16, 16, 16) 的 3D 卷積嵌入塊生成embedding,并與可學(xué)習(xí)的 3D 絕對位置編碼 absolute Positional Encoding (PE) 配對。 這種編碼是通過自然地將附加維度擴(kuò)展到 SAM 的 2D PE 來獲得的。 然后將補(bǔ)丁的嵌入輸入到 3D 注意力塊中。 對于 3D 注意力模塊,我們將 3D 相關(guān) PE 合并到 SAM 的多頭自注意力(MHSA)模塊中,使其能夠直接捕獲空間細(xì)節(jié)。

class PatchEmbed3D(nn.Module):
    """
    Image to Patch Embedding.
    """

    def __init__(
        self,
        kernel_size: Tuple[int, int] = (16, 16, 16),
        stride: Tuple[int, int] = (16, 16, 16),
        padding: Tuple[int, int] = (0, 0, 0),
        in_chans: int = 1,
        embed_dim: int = 768,
    ) -> None:
        """
        Args:
            kernel_size (Tuple): kernel size of the projection layer.
            stride (Tuple): stride of the projection layer.
            padding (Tuple): padding size of the projection layer.
            in_chans (int): Number of input image channels.
            embed_dim (int): Patch embedding dimension.
        """
        super().__init__()

        self.proj = nn.Conv3d(
            in_chans, embed_dim, kernel_size=kernel_size, stride=stride, padding=padding
        )

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        x = self.proj(x)
        # B C X Y Z -> B X Y Z C
        x = x.permute(0, 2, 3, 4, 1)
        return x
class Attention(nn.Module):
    """Multi-head Attention block with relative position embeddings."""

    def __init__(
        self,
        dim: int,
        num_heads: int = 8,
        qkv_bias: bool = True,
        use_rel_pos: bool = False,
        rel_pos_zero_init: bool = True,
        input_size: Optional[Tuple[int, int, int]] = None,
    ) -> None:
        """
        Args:
            dim (int): Number of input channels.
            num_heads (int): Number of attention heads.
            qkv_bias (bool):  If True, add a learnable bias to query, key, value.
            rel_pos (bool): If True, add relative positional embeddings to the attention map.
            rel_pos_zero_init (bool): If True, zero initialize relative positional parameters.
            input_size (tuple(int, int) or None): Input resolution for calculating the relative
                positional parameter size.
        """
        super().__init__()
        self.num_heads = num_heads
        head_dim = dim // num_heads
        self.scale = head_dim**-0.5

        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
        self.proj = nn.Linear(dim, dim)

        self.use_rel_pos = use_rel_pos
        if self.use_rel_pos:
            assert (
                input_size is not None
            ), "Input size must be provided if using relative positional encoding."
            # initialize relative positional embeddings
            self.rel_pos_d = nn.Parameter(torch.zeros(2 * input_size[0] - 1, head_dim))
            self.rel_pos_h = nn.Parameter(torch.zeros(2 * input_size[1] - 1, head_dim))
            self.rel_pos_w = nn.Parameter(torch.zeros(2 * input_size[2] - 1, head_dim))

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        B, D, H, W, _ = x.shape
        # qkv with shape (3, B, nHead, H * W, C)
        qkv = self.qkv(x).reshape(B, D * H * W, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)
        # q, k, v with shape (B * nHead, H * W, C)
        q, k, v = qkv.reshape(3, B * self.num_heads, D * H * W, -1).unbind(0)

        attn = (q * self.scale) @ k.transpose(-2, -1)

        if self.use_rel_pos:
            attn = add_decomposed_rel_pos(attn, q, self.rel_pos_d, self.rel_pos_h, self.rel_pos_w, (D, H, W), (D, H, W))

        attn = attn.softmax(dim=-1)
        x = (attn @ v).view(B, self.num_heads, D, H, W, -1).permute(0, 2, 3, 4, 1, 5).reshape(B, D, H, W, -1)
        x = self.proj(x)

        return x

4.2 3D Prompt Encoder

在提示編碼器中,稀疏提示利用 3D 位置編碼來表示 3D 空間細(xì)微差別,而密集提示則通過 3D 卷積進(jìn)行處理。

class PromptEncoder3D(nn.Module):
    def __init__(
        self,
        embed_dim: int,
        image_embedding_size: Tuple[int, int, int],
        input_image_size: Tuple[int, int, int],
        mask_in_chans: int,
        activation: Type[nn.Module] = nn.GELU,
    ) -> None:
        """
        Encodes prompts for input to SAM's mask decoder.

        Arguments:
          embed_dim (int): The prompts' embedding dimension
          image_embedding_size (tuple(int, int)): The spatial size of the
            image embedding, as (H, W).
          input_image_size (int): The padded size of the image as input
            to the image encoder, as (H, W).
          mask_in_chans (int): The number of hidden channels used for
            encoding input masks.
          activation (nn.Module): The activation to use when encoding
            input masks.
        """
        super().__init__()
        self.embed_dim = embed_dim
        self.input_image_size = input_image_size
        self.image_embedding_size = image_embedding_size
        self.pe_layer = PositionEmbeddingRandom3D(embed_dim // 3)

        self.num_point_embeddings: int = 2  # pos/neg point
        point_embeddings = [nn.Embedding(1, embed_dim) for i in range(self.num_point_embeddings)]
        self.point_embeddings = nn.ModuleList(point_embeddings)
        self.not_a_point_embed = nn.Embedding(1, embed_dim)

        self.mask_input_size = (image_embedding_size[0], image_embedding_size[1], image_embedding_size[2])
        self.mask_downscaling = nn.Sequential(
            nn.Conv3d(1, mask_in_chans // 4, kernel_size=2, stride=2),
            LayerNorm3d(mask_in_chans // 4),
            activation(),
            nn.Conv3d(mask_in_chans // 4, mask_in_chans, kernel_size=2, stride=2),
            LayerNorm3d(mask_in_chans),
            activation(),
            nn.Conv3d(mask_in_chans, embed_dim, kernel_size=1),
        )
        self.no_mask_embed = nn.Embedding(1, embed_dim)

    def get_dense_pe(self) -> torch.Tensor:
        """
        Returns the positional encoding used to encode point prompts,
        applied to a dense set of points the shape of the image encoding.

        Returns:
          torch.Tensor: Positional encoding with shape
            1x(embed_dim)x(embedding_h)x(embedding_w)
        """
        return self.pe_layer(self.image_embedding_size).unsqueeze(0)  # 1xXxYxZ

    def _embed_points(
        self,
        points: torch.Tensor,
        labels: torch.Tensor,
        pad: bool,
    ) -> torch.Tensor:
        """Embeds point prompts."""
        points = points + 0.5  # Shift to center of pixel
        if pad:
            padding_point = torch.zeros((points.shape[0], 1, 3), device=points.device)
            padding_label = -torch.ones((labels.shape[0], 1), device=labels.device)
            points = torch.cat([points, padding_point], dim=1)
            labels = torch.cat([labels, padding_label], dim=1)
        point_embedding = self.pe_layer.forward_with_coords(points, self.input_image_size)
        point_embedding[labels == -1] = 0.0
        point_embedding[labels == -1] += self.not_a_point_embed.weight
        point_embedding[labels == 0] += self.point_embeddings[0].weight
        point_embedding[labels == 1] += self.point_embeddings[1].weight
        return point_embedding

    def _embed_boxes(self, boxes: torch.Tensor) -> torch.Tensor:
        """Embeds box prompts."""
        boxes = boxes + 0.5  # Shift to center of pixel
        coords = boxes.reshape(-1, 2, 2)
        corner_embedding = self.pe_layer.forward_with_coords(coords, self.input_image_size)
        corner_embedding[:, 0, :] += self.point_embeddings[2].weight
        corner_embedding[:, 1, :] += self.point_embeddings[3].weight
        return corner_embedding

    def _embed_masks(self, masks: torch.Tensor) -> torch.Tensor:
        """Embeds mask inputs."""
        mask_embedding = self.mask_downscaling(masks)
        return mask_embedding

    def _get_batch_size(
        self,
        points: Optional[Tuple[torch.Tensor, torch.Tensor]],
        boxes: Optional[torch.Tensor],
        masks: Optional[torch.Tensor],
    ) -> int:
        """
        Gets the batch size of the output given the batch size of the input prompts.
        """
        if points is not None:
            return points[0].shape[0]
        elif boxes is not None:
            return boxes.shape[0]
        elif masks is not None:
            return masks.shape[0]
        else:
            return 1

    def _get_device(self) -> torch.device:
        return self.point_embeddings[0].weight.device

    def forward(
        self,
        points: Optional[Tuple[torch.Tensor, torch.Tensor]],
        boxes: Optional[torch.Tensor],
        masks: Optional[torch.Tensor],
    ) -> Tuple[torch.Tensor, torch.Tensor]:
        """
        Embeds different types of prompts, returning both sparse and dense
        embeddings.

        Arguments:
          points (tuple(torch.Tensor, torch.Tensor) or none): point coordinates
            and labels to embed.
          boxes (torch.Tensor or none): boxes to embed
          masks (torch.Tensor or none): masks to embed

        Returns:
          torch.Tensor: sparse embeddings for the points and boxes, with shape
            BxNx(embed_dim), where N is determined by the number of input points
            and boxes.
          torch.Tensor: dense embeddings for the masks, in the shape
            Bx(embed_dim)x(embed_H)x(embed_W)
        """
        bs = self._get_batch_size(points, boxes, masks)
        sparse_embeddings = torch.empty((bs, 0, self.embed_dim), device=self._get_device())
        if points is not None:
            coords, labels = points
            point_embeddings = self._embed_points(coords, labels, pad=(boxes is None))
            sparse_embeddings = torch.cat([sparse_embeddings, point_embeddings], dim=1)
        if boxes is not None:
            box_embeddings = self._embed_boxes(boxes)
            sparse_embeddings = torch.cat([sparse_embeddings, box_embeddings], dim=1)

        if masks is not None:
            dense_embeddings = self._embed_masks(masks)
        else:
            dense_embeddings = self.no_mask_embed.weight.reshape(1, -1, 1, 1, 1).expand(
                bs, -1, self.image_embedding_size[0], self.image_embedding_size[1], self.image_embedding_size[2]
            )

        return sparse_embeddings, dense_embeddings

4.3 3D mask Decoder

3D mask Decoder與 3D 上采樣集成,采用 3D 轉(zhuǎn)置卷積。

class TwoWayAttentionBlock3D(nn.Module):
    def __init__(
        self,
        embedding_dim: int,
        num_heads: int,
        mlp_dim: int = 2048,
        activation: Type[nn.Module] = nn.ReLU,
        attention_downsample_rate: int = 2,
        skip_first_layer_pe: bool = False,
    ) -> None:
        """
        A transformer block with four layers: (1) self-attention of sparse
        inputs, (2) cross attention of sparse inputs to dense inputs, (3) mlp
        block on sparse inputs, and (4) cross attention of dense inputs to sparse
        inputs.

        Arguments:
          embedding_dim (int): the channel dimension of the embeddings
          num_heads (int): the number of heads in the attention layers
          mlp_dim (int): the hidden dimension of the mlp block
          activation (nn.Module): the activation of the mlp block
          skip_first_layer_pe (bool): skip the PE on the first layer
        """
        super().__init__()
        self.self_attn = Attention(embedding_dim, num_heads)
        self.norm1 = nn.LayerNorm(embedding_dim)

        self.cross_attn_token_to_image = Attention(
            embedding_dim, num_heads, downsample_rate=attention_downsample_rate
        )
        self.norm2 = nn.LayerNorm(embedding_dim)

        self.mlp = MLPBlock3D(embedding_dim, mlp_dim, activation)
        self.norm3 = nn.LayerNorm(embedding_dim)

        self.norm4 = nn.LayerNorm(embedding_dim)
        self.cross_attn_image_to_token = Attention(
            embedding_dim, num_heads, downsample_rate=attention_downsample_rate
        )

        self.skip_first_layer_pe = skip_first_layer_pe

    def forward(
        self, queries: Tensor, keys: Tensor, query_pe: Tensor, key_pe: Tensor
    ) -> Tuple[Tensor, Tensor]:
        # Self attention block
        if self.skip_first_layer_pe:
            queries = self.self_attn(q=queries, k=queries, v=queries)
        else:
            q = queries + query_pe
            attn_out = self.self_attn(q=q, k=q, v=queries)
            queries = queries + attn_out
        queries = self.norm1(queries)

        # Cross attention block, tokens attending to image embedding
        q = queries + query_pe
        k = keys + key_pe
        attn_out = self.cross_attn_token_to_image(q=q, k=k, v=keys)
        queries = queries + attn_out
        queries = self.norm2(queries)

        # MLP block
        mlp_out = self.mlp(queries)
        queries = queries + mlp_out
        queries = self.norm3(queries)

        # Cross attention block, image embedding attending to tokens
        q = queries + query_pe
        k = keys + key_pe
        attn_out = self.cross_attn_image_to_token(q=k, k=q, v=queries)
        keys = keys + attn_out
        keys = self.norm4(keys)

        return queries, keys

4.4 模型權(quán)重

測試了三種訓(xùn)練策略,結(jié)果表明從頭訓(xùn)練效果最好

  • 沿用2d sam,加上3d adapter進(jìn)行改造。
  • 將2d sam的權(quán)重改造成 3d 結(jié)構(gòu)可以使用的權(quán)重(對3d層采用權(quán)重復(fù)制策略)。 以卷積為例,我們將二維卷積的核復(fù)制D次并將它們堆疊起來形成三維卷積,其中D表示第三維中核的大小。
  • 使用3d數(shù)據(jù)從頭訓(xùn)練。
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型

5. 評估

對于2D切片分割和3D體積分割,我們從前景中隨機(jī)采樣一個(gè)點(diǎn)作為第一個(gè)提示,并從誤差區(qū)域中隨機(jī)選擇以下點(diǎn)。 值得注意的是,2D SAM 方法(SAM、SAM-Med2D)是逐片推斷的,而我們的 SAM-Med3D 使用基于補(bǔ)丁的推斷方法進(jìn)行操作。 這與 nnUNet 等最先進(jìn)的醫(yī)學(xué)圖像分割方法一致,賦予 SAM-Med3D 在推理時(shí)間方面的優(yōu)勢。 此外,2D方法在推斷3D醫(yī)學(xué)圖像時(shí)對每個(gè)切片進(jìn)行獨(dú)立交互,而3D方法僅在體積上進(jìn)行全局交互。 這意味著2D執(zhí)行的交互次數(shù)實(shí)際上是3D的N倍(N表示包含對象的切片數(shù)量,通常范圍為10到200)。 盡管 2D 方法采用了更多的提示點(diǎn),但其固有的片間交互缺乏造成了明顯的性能上限,特別是在相對復(fù)雜的 3D 結(jié)構(gòu)上。

5.1 評估數(shù)據(jù)集

在評估階段,我們選擇了 13 個(gè)公共基準(zhǔn)數(shù)據(jù)集來審查各種臨床場景,并納入了 MICCAI2023 挑戰(zhàn)賽中的 2 個(gè)額外數(shù)據(jù)集來驗(yàn)證不同模型的性能。 該驗(yàn)證集包含七個(gè)重要的解剖結(jié)構(gòu),例如胸部和腹部器官、大腦結(jié)構(gòu)、骨骼等。 它還包括醫(yī)學(xué)領(lǐng)域非常感興趣的五種病變類型,以及一系列體積測量模式,包括 CT、US(超聲)和八個(gè) MRI 序列。 此外,它還包含具有挑戰(zhàn)性的、以前未見過的目標(biāo),最終形成了不同類別的 153 個(gè)不同目標(biāo)。 驗(yàn)證集有三部分:
醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型

5.2 Quantitative Evaluation

  • 整體表現(xiàn)
    SAM-Med3D在使用更少點(diǎn)擊次數(shù)的情況下,獲得了更好的性能。N表示待分割目標(biāo)包含的切片(slice)數(shù)目,通常10 ≤ N ≤ 200。 T i n f T_{inf} Tinf?為N =100時(shí)所需的推理時(shí)間 (Inference time) 。
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
  • 從解剖結(jié)構(gòu)和病變角度進(jìn)行評估
    A&T 表示腹部和胸部。SAM-Med3D 只需10個(gè)提示點(diǎn)(最后一行)即可取得比 SAM 和 SAM-Med2D 更好的性能,而后兩者往往需要上百個(gè)提示點(diǎn)。在評估中,我們考慮了各種?法中可見和不可見(zero-shot)的病變。對于不可見的病變,當(dāng)提示有限時(shí),表現(xiàn)次優(yōu)。
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
    左側(cè)三張圖展示了不同模型在不同模態(tài)下的性能對比,其中SAM-Med3D在所有模態(tài)下均展現(xiàn)出優(yōu)異性能。即使SAM-Med3D沒有使用超聲(US)圖像訓(xùn)練,其性能仍與 SAM-Med2D相當(dāng)。
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型
  • 遷移性評估
    作者將 SAM-Med3D 預(yù)訓(xùn)練的 ViT 圖像編碼器遷移到 UNETR 中進(jìn)行使用,發(fā)現(xiàn)能夠獲得效果上的提升,證明了作者提出的 SAM-Med3D 具有遷移能力,這將能夠?qū)θS醫(yī)學(xué)圖像領(lǐng)域的發(fā)展提供幫助。據(jù)我們所知,SAM-Med3D 可能被定位為第一個(gè)基于 ViT 的 3D 醫(yī)學(xué)圖像基礎(chǔ)模型。
    醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型

5.3 可視化

圖五:在不同的解剖結(jié)構(gòu)中,針對不同數(shù)量的點(diǎn),對SAM、SAM-Med2D和SAM-Med3D進(jìn)行可視化。作者同時(shí)展示了軸切片和冠狀切片/矢狀切片來全面說明三維結(jié)果。
圖六:在各種模態(tài)下,針對不同的點(diǎn)數(shù),對SAM、SAM-Med2D和SAM-Med3D進(jìn)行可視化。作者同時(shí)展示了軸切片和冠狀/矢狀切片來全面說明三維結(jié)果。
醫(yī)學(xué)圖像分割medsam-3d,醫(yī)學(xué)大模型,醫(yī)學(xué)分割,人工智能,深度學(xué)習(xí),計(jì)算機(jī)視覺,大模型文章來源地址http://www.zghlxwxcb.cn/news/detail-857154.html

6. 結(jié)論

  • 在這項(xiàng)研究中,作者提出了 SAM-Med3D,這是一種專門用于3D體素醫(yī)學(xué)圖像分割的三維 SAM 模型。SAM-Med3D 在大規(guī)模的三維醫(yī)學(xué)圖像數(shù)據(jù)集上從頭訓(xùn)練,其在不同組件中都采用了三維位置編碼,直接整合三維空間信息,這使得它在體素醫(yī)學(xué)圖像分割任務(wù)中表現(xiàn)出卓越的性能。具體而言,SAM-Med3D 在提供僅一個(gè)提示點(diǎn)的情況下,相較于 SAM 在每個(gè)切片上提供一個(gè)提示點(diǎn)來說,性能提高了32.90%。這表明它能夠在更少的提示點(diǎn)的情況下,在體素醫(yī)學(xué)圖像分割任務(wù)中取得更好的結(jié)果,這證明了它出色的可用性。
  • 此外,作者還從多個(gè)角度廣泛評估了 SAM-Med3D 的能力。對于不同的解剖結(jié)構(gòu),如骨骼、心臟和肌肉,在提供有限提示點(diǎn)的情況下,SAM-Med3D 明顯優(yōu)于其他方法。在不同的圖像模態(tài)下,特別是核磁共振圖像,通常需要比CT圖像更多的提示點(diǎn)才能達(dá)到相同的性能,但 SAM-Med3D 在各種模態(tài)(包括核磁共振圖像)、器官和病變下始終表現(xiàn)出色。此外,SAM-Med3D 的可遷移性也在不同的基準(zhǔn)任務(wù)上經(jīng)過了驗(yàn)證,該模型表現(xiàn)出了很強(qiáng)的潛力,因此 SAM-Med3D 有望成為一種強(qiáng)大的三維醫(yī)學(xué)圖像 Transformer 的預(yù)訓(xùn)練模型。
  • 需要強(qiáng)調(diào)的是,不僅僅在數(shù)值結(jié)果方面,在可視化的結(jié)果中,SAM-Med3D 模型也表現(xiàn)出了更好的切片間的一致性和可用性。然而,三維模型在體積圖像中的提示點(diǎn)變得更加稀疏,這增加了訓(xùn)練的難度。因此,如何更好地訓(xùn)練三維SAM仍然是需要進(jìn)一步探索的領(lǐng)域,但這項(xiàng)研究為這一領(lǐng)域的未來發(fā)展提供了有力的方向和工具。

到了這里,關(guān)于[醫(yī)學(xué)分割大模型系列] (3) SAM-Med3D 分割大模型詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 深度學(xué)習(xí)實(shí)驗(yàn)-3d醫(yī)學(xué)圖像分割

    實(shí)驗(yàn)四 基于nnU-Net模型的3D醫(yī)學(xué)圖像分割實(shí)驗(yàn) 腹部多器官分割一直是醫(yī)學(xué)圖像分析領(lǐng)域最活躍的研究領(lǐng)域之一,其作為一項(xiàng)基礎(chǔ)技術(shù),在支持疾病診斷,治療規(guī)劃等計(jì)算機(jī)輔助技術(shù)發(fā)揮著重要作用。近年來,基于深度學(xué)習(xí)的方法在該領(lǐng)域中獲得了巨大成功。本實(shí)驗(yàn)數(shù)據(jù)集為多

    2024年02月07日
    瀏覽(99)
  • 【醫(yī)學(xué)圖像】圖像分割系列.2 (diffusion)

    【醫(yī)學(xué)圖像】圖像分割系列.2 (diffusion)

    介紹幾篇使用diffusion來實(shí)現(xiàn)醫(yī)學(xué)圖像分割的論文:DARL(ICLR2023),MedSegDiff(MIDL2023) MedSegDiff-V2(arXiv2023),ImgX-DiffSeg(arXiv2023) 基礎(chǔ)概念: 一文弄懂 Diffusion Model (qq.com)。 表示學(xué)習(xí)(representation learning)初印象 - 知乎 (zhihu.com)。 10分鐘快速入門PyTorch (10) - 知乎 (zhihu.com)。 解讀

    2024年02月07日
    瀏覽(44)
  • Med-YOLO:3D + 醫(yī)學(xué)影像 + 檢測框架

    Med-YOLO:3D + 醫(yī)學(xué)影像 + 檢測框架

    ? 論文鏈接:https://arxiv.org/abs/2312.07729 代碼鏈接:https://github.com/JDSobek/MedYOLO 提出背景 :人工智能已經(jīng)應(yīng)用于大量的醫(yī)學(xué)影像的識(shí)別,但是還缺少通用的3D醫(yī)學(xué)影像檢測框架。 在中大尺寸結(jié)構(gòu)(如心臟、肝臟和胰腺)上的性能非常高。 然而,模型在處理非常小或罕見的結(jié)構(gòu)時(shí)

    2024年01月22日
    瀏覽(23)
  • 超越nnFormer!UNETR++:高效準(zhǔn)確的3D醫(yī)學(xué)圖像分割

    超越nnFormer!UNETR++:高效準(zhǔn)確的3D醫(yī)學(xué)圖像分割

    UNETR++: Delving into Efficient and Accurate 3D Medical Image Segmentation 論文鏈接: https://arxiv.org/abs/2212.04497 代碼鏈接: https://github.com/Amshaker/unetr_plus_plus 這篇論文主要講述了一種名為 UNETR++ 的 3D 醫(yī)學(xué)圖像分割方法,它提供了 高質(zhì)量的分割結(jié)果 ,并具有 高效的參數(shù)和計(jì)算成本 。作者介紹

    2023年04月16日
    瀏覽(23)
  • SAM - 分割一切圖像【AI大模型】

    SAM - 分割一切圖像【AI大模型】

    如果你認(rèn)為 AI 領(lǐng)域已經(jīng)通過 ChatGPT、GPT4 和 Stable Diffusion 快速發(fā)展,那么請系好安全帶,為 AI 的下一個(gè)突破性創(chuàng)新做好準(zhǔn)備。 推薦:用 NSDT場景設(shè)計(jì)器 快速搭建3D場景。 Meta 的 FAIR 實(shí)驗(yàn)室剛剛發(fā)布了 Segment Anything Model (SAM),這是一種最先進(jìn)的圖像分割模型,旨在改變計(jì)算機(jī)視

    2023年04月21日
    瀏覽(26)
  • 半監(jiān)督3D醫(yī)學(xué)圖像分割(二):UA-MT

    半監(jiān)督3D醫(yī)學(xué)圖像分割(二):UA-MT

    Uncertainty-Aware Self-ensembling Model for Semi-supervised 3D Left Atrium Segmentation ? 醫(yī)學(xué)圖像的分割標(biāo)簽需要專業(yè)醫(yī)師標(biāo)注,獲取代價(jià)昂貴,而無標(biāo)簽的數(shù)據(jù)有很多。半監(jiān)督學(xué)習(xí)則是將少量有標(biāo)注的數(shù)據(jù)和大量無標(biāo)注的數(shù)據(jù)直接輸入到網(wǎng)絡(luò)中,構(gòu)建一致性損失或者多任務(wù)學(xué)習(xí),達(dá)到比單獨(dú)

    2024年02月07日
    瀏覽(28)
  • 通用醫(yī)學(xué)圖像分割模型UniverSeg

    通用醫(yī)學(xué)圖像分割模型UniverSeg

    雖然深度學(xué)習(xí)模型已經(jīng)成為醫(yī)學(xué)圖像分割的主要方法,但它們通常無法推廣到涉及新解剖結(jié)構(gòu)、圖像模態(tài)或標(biāo)簽的unseen分割任務(wù)。給定一個(gè)新的分割任務(wù),研究人員通常必須訓(xùn)練或微調(diào)模型,這很耗時(shí),并對臨床研究人員構(gòu)成了巨大障礙,因?yàn)樗麄兺狈τ?xùn)練神經(jīng)網(wǎng)絡(luò)的資

    2024年02月04日
    瀏覽(22)
  • 三維重建 閾值分割 3D可視化 醫(yī)學(xué)圖像分割 CT圖像分割及重建系統(tǒng) 可視化編程技術(shù)及應(yīng)用

    三維重建 閾值分割 3D可視化 醫(yī)學(xué)圖像分割 CT圖像分割及重建系統(tǒng) 可視化編程技術(shù)及應(yīng)用

    此系統(tǒng)實(shí)現(xiàn)了常見的VTK四視圖,實(shí)現(xiàn)了很好的CT圖像分割,可以用于骨骼,頭部,肺部,脂肪等分割,,并且通過三維重建實(shí)現(xiàn)可視化。使用了第三方庫 VTK,ITK 實(shí)現(xiàn)分割和生不重建。 窗口分為 (橫斷面)、冠狀面、矢狀面,和3D窗口;包含了體繪制和面繪制; 效果: CT分割

    2024年02月08日
    瀏覽(25)
  • 【圖像分割】Meta分割一切(SAM)模型環(huán)境配置和使用教程

    【圖像分割】Meta分割一切(SAM)模型環(huán)境配置和使用教程

    注意: python=3.8 , pytorch=1.7, torchvision=0.8 Feel free to ask any question. 遇到問題歡迎評論區(qū)討論. 官方教程: (1)pip: 有可能出現(xiàn)錯(cuò)誤,需要配置好Git。 (2)本地安裝: 有可能出現(xiàn)錯(cuò)誤,需要配置好Git。 (3)手動(dòng)下載+手動(dòng)本地安裝: ?zip文件: 解壓后運(yùn)行:? matplotlib 3.7.1和

    2023年04月12日
    瀏覽(34)
  • 醫(yī)學(xué)圖像分割綜述:U-Net系列

    醫(yī)學(xué)圖像分割綜述:U-Net系列

    論文地址 代碼地址 醫(yī)學(xué)圖像自動(dòng)分割是醫(yī)學(xué)領(lǐng)域的一個(gè)重要課題,也是計(jì)算機(jī)輔助診斷范式的一個(gè)重要對應(yīng)。U-Net是最廣泛的圖像分割架構(gòu),由于其靈活性,優(yōu)化的模塊化設(shè)計(jì),并在所有醫(yī)學(xué)圖像模式的成功。多年來,U-Net模型得到了學(xué)術(shù)界和工業(yè)界研究人員的極大關(guān)注。該

    2024年02月05日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包