第7讲:分割大模型——SAM(Segment Anything Model)

一、从一个"抠图"需求开始

1.1 传统分割的痛点

想象你有一张合影,想把背景换成海边:

传统图像分割方法:

方法1:手动抠图
  用Photoshop的魔棒工具一点点选
  头发丝?手指边缘?抠到崩溃!

方法2:自动分割(传统深度学习)
  训练一个"人"的分割模型
  问题:只能分割"人",不能分割"猫"、"汽车"、"椅子"...
  换个类别就要重新训练!

方法3:语义分割
  模型输出每个像素的类别(人/车/路/树)
  问题:只能识别训练时见过的类别
  遇到"新型滑板车"?不认识,就分不出来

核心痛点:传统模型是"封闭式"的——只能处理预定义的类别。


1.2 SAM的革命:“任意分割” anything

Meta(Facebook)2023年发布的SAM,提出了全新范式:

传统分割:
  输入:图片
  模型:训练好的"人分割器"
  输出:人的掩码
  限制:只能分人,不能分猫

SAM的分割:
  输入:图片 + 你的提示(Prompt)
         ↓
  提示可以是:
    - "点这里"(鼠标点击)
    - "框住这个区域"(画矩形框)
    - "分割这只猫"(文本描述)
    - "在这个大致形状上细化"(粗糙掩码)
         ↓
  输出:你提示的那个对象的精确掩码
  能力:任何对象!训练时没见过也能分!

通俗理解

传统模型像"专科医生":只看眼科,不看牙科。
SAM像"全科医生+听诊器":你指哪里,我看哪里,什么都能看。


二、SAM的核心思想:提示驱动分割

2.1 什么是"提示"(Prompt)?

提示就是你给模型的"指令",告诉它"我要分割什么"。

提示类型 形式 例子 适合场景
点提示 单点/多点坐标 点击猫的身体 快速选择对象
框提示 矩形框坐标 画框框住汽车 对象边界清晰
文本提示 自然语言 “分割红色的椅子” 语义明确的对象
掩码提示 粗略掩码 手绘大致轮廓 需要细化边缘

关键洞察

传统模型:模型自己决定"要分什么"(预定义类别)
SAM:用户通过Prompt告诉模型"要分什么"(开放类别)

结果:SAM不需要认识"猫"这个类别,
      你只需要点一下猫,它就帮你把猫抠出来!

2.2 为什么"任意分割"可能?

秘密1:强大的图像编码器
  用ViT-Huge(632M参数)把图像变成"超级特征图"
  这个特征图包含了图像的所有视觉信息
  不只是"类别信息",而是"一切视觉线索"

秘密2:提示编码器理解你的意图
  把你的点击/框/文本变成"查询向量"
  这个向量指向特征图中的特定区域

秘密3:掩码解码器做精细分割
  结合图像特征 + 提示查询 → 输出精确掩码
  甚至输出多个候选掩码供你选择!

三、SAM架构三件套

3.1 整体架构

┌─────────────────────────────────────────────────────────┐
│                    输入                                  │
│  图像 [3, 1024, 1024] + 提示(点/框/文本/掩码)          │
└─────────────────────────────────────────────────────────┘
                          ↓
        ┌─────────────────┴─────────────────┐
        ↓                                   ↓
┌───────────────┐                 ┌───────────────┐
│ Image Encoder   │                 │ Prompt Encoder │
│ 图像编码器       │                 │ 提示编码器       │
│                 │                 │                │
│ • ViT-Huge      │                 │ • 点/框编码      │
│ • MAE预训练      │                 │ • 文本编码(CLIP) │
│ • 输出: 64×64   │                 │ • 掩码编码      │
│   特征图         │                 │                │
│                 │                 │ 输出: 查询向量   │
│ [256, 64, 64]   │                 │ [N, 256]       │
└───────────────┘                 └───────────────┘
        ↓                                   ↓
        └─────────────────┬─────────────────┘
                          ↓
              ┌─────────────────┐
              │ 特征融合          │
              │ 图像特征 + 提示查询 │
              └─────────────────┘
                          ↓
              ┌─────────────────┐
              │ Mask Decoder    │
              │ 掩码解码器       │
              │                 │
              │ • 两层Transformer│
              │ • 动态掩码预测   │
              │ • 输出3个候选掩码│
              │   (解决歧义性)   │
              └─────────────────┘
                          ↓
              ┌─────────────────┐
              │ 输出: 分割掩码     │
              │ [1, 1024, 1024]  │
              │ 二值图:1=前景,0=背景│
              └─────────────────┘

3.2 组件1:Image Encoder(图像编码器)

作用:把整张图变成"语义地图"

架构:ViT-Huge(Vision Transformer Huge)
  - 输入:1024×1024的图像
  - 分块:16×16的patch → 64×64=4096个块
  - 处理:32层Transformer
  - 输出:256维的特征图 [256, 64, 64]

关键:用MAE(Masked Autoencoder)预训练
  MAE把图像大块遮住,让模型重建原图
  强迫模型学会"理解图像内容"而不仅是"记住标签"

为什么用这么大的编码器?

分割需要精细的边界信息。小模型只能捕捉大致形状,大模型能学到毛发、透明物体、阴影等细节。


3.3 组件2:Prompt Encoder(提示编码器)

作用:把你的"指示"变成模型能理解的向量

┌────────────────────────────────────────┐
│ 点提示 (Point Prompt)                   │
│ ─────────────────                      │
│ 输入:坐标(x,y) + 标签(前景点/背景点)   │
│ 编码:位置嵌入 + 类型嵌入                │
│ 输出:256维向量                         │
└────────────────────────────────────────┘

┌────────────────────────────────────────┐
│ 框提示 (Box Prompt)                    │
│ ─────────────────                      │
│ 输入:左上角(x1,y1) + 右下角(x2,y2)    │
│ 编码:把框变成一对点(左上+右下)的嵌入   │
│ 输出:2×256维向量                       │
└────────────────────────────────────────┘

┌────────────────────────────────────────┐
│ 文本提示 (Text Prompt)                  │
│ ─────────────────                      │
│ 输入:"一只橘色的猫"                     │
│ 编码:CLIP文本编码器                     │
│ 输出:256维向量(与图像特征对齐)         │
└────────────────────────────────────────┘

┌────────────────────────────────────────┐
│ 掩码提示 (Mask Prompt)                  │
│ ─────────────────                      │
│ 输入:粗略的二值掩码(手绘或上一轮输出)    │
│ 编码:小型CNN下采样 + 卷积嵌入            │
│ 输出:256维向量                         │
└────────────────────────────────────────┘

3.4 组件3:Mask Decoder(掩码解码器)

作用:把"图像理解" + "用户意图" → 精确掩码

架构:
  输入1:图像特征 [256, 64, 64]
  输入2:提示查询 [N, 256](N=提示数量)
  
  处理:
    1. 提示查询做自注意力(多个提示之间交互)
    2. 提示查询与图像特征做交叉注意力
    3. 上采样到原始分辨率
    4. MLP预测每个像素的"前景概率"

  输出:3个候选掩码 + 置信度分数

为什么输出3个?
  解决"歧义性"!
  
  例子:你点了一个点,但这个点在"杯子把手"上
    掩码1:只分手把(局部)
    掩码2:分整个杯子(整体)
    掩码3:分杯子和手(如果手在旁边)
  
  让用户选最符合意图的那个!

四、SAM 2:从图片到视频

4.1 视频分割的挑战

图片分割:
  点一下 → 出掩码 → 结束

视频分割:
  第1帧:点一下 → 出掩码
  第2帧:对象移动了!掩码怎么跟过去?
  第3帧:对象被遮挡了!怎么记住它?
  第100帧:对象变形了!怎么适应?

4.2 SAM 2的记忆机制

SAM 2的核心创新:记忆编码器 + 记忆库

┌─────────────────────────────────────────┐
│ 第1帧处理                               │
│ 输入:图像 + 提示                        │
│ 输出:掩码 + 记忆特征                    │
│         ↓                              │
│    存入记忆库                            │
└─────────────────────────────────────────┘
            ↓
┌─────────────────────────────────────────┐
│ 第2帧处理                               │
│ 输入:新图像 + 记忆库(第1帧的信息)      │
│ 模型:"根据上一帧的记忆,找同一个对象"     │
│ 输出:新掩码 + 更新记忆                  │
│         ↓                              │
│    更新记忆库                            │
└─────────────────────────────────────────┘
            ↓
         ...循环...

记忆库组成:
  1. 对象记忆:目标对象的视觉特征
  2. 位置记忆:对象在帧间的运动轨迹
  3. 外观记忆:对象的不同角度/姿态

通俗理解

SAM像"追踪侦探":第1帧记住嫌疑人的脸,之后每帧都翻档案对比,即使嫌疑人换了衣服、戴了帽子,也能认出来。


五、动手实验:用SAM做分割

5.1 环境准备

# 安装SAM
pip install git+https://github.com/facebookresearch/segment-anything.git

# 安装SAM 2(如果需要视频分割)
pip install git+https://github.com/facebookresearch/segment-anything-2.git

# 下载预训练权重
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth  # Huge
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth  # Large
wget https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth  # Base

5.2 实验1:自动分割一切(Everything Mode)

import numpy as np
import torch
import matplotlib.pyplot as plt
from PIL import Image
import cv2

# 导入SAM
try:
    from segment_anything import sam_model_registry, SamAutomaticMaskGenerator, SamPredictor
    SAM_AVAILABLE = True
except ImportError:
    SAM_AVAILABLE = False
    print("SAM未安装,请先安装:pip install segment-anything")

if SAM_AVAILABLE:
    print("=" * 60)
    print("【实验1】SAM自动分割所有对象")
    print("=" * 60)
    
    # 加载模型
    model_type = "vit_h"  # 可选: vit_b, vit_l, vit_h
    checkpoint = "sam_vit_h_4b8939.pth"
    
    device = "cuda" if torch.cuda.is_available() else "cpu"
    sam = sam_model_registry[model_type](checkpoint=checkpoint)
    sam.to(device)
    
    print(f"✅ 加载SAM-{model_type.upper()},设备:{device}")
    print(f"参数量:{sum(p.numel() for p in sam.parameters())/1e6:.0f}M")
    
    # 创建自动分割器
    mask_generator = SamAutomaticMaskGenerator(
        model=sam,
        points_per_side=32,      # 每边采样32个点
        pred_iou_thresh=0.9,     # IoU阈值
        stability_score_thresh=0.95,
        crop_n_layers=1,         # 多层裁剪(处理不同尺度)
        crop_n_points_downscale_factor=2,
        min_mask_region_area=100, # 最小掩码面积
    )
    
    # 加载图片(替换为你的图片路径)
    # 这里用随机生成的演示图
    np.random.seed(42)
    image = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
    
    # 实际使用时:
    # image = cv2.imread("your_image.jpg")
    # image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    print(f"\n输入图像形状: {image.shape}")
    
    # 生成所有掩码
    print("正在生成掩码(可能需要几秒到几分钟)...")
    masks = mask_generator.generate(image)
    
    print(f"✅ 生成了 {len(masks)} 个掩码!")
    
    # 可视化
    def show_anns(anns, image):
        if len(anns) == 0:
            return image
        
        sorted_anns = sorted(anns, key=(lambda x: x['area']), reverse=True)
        
        # 创建叠加图
        overlay = image.copy().astype(np.float32) / 255.0
        
        for ann in sorted_anns:
            m = ann['segmentation']
            color_mask = np.random.random(3)
            
            # 创建彩色掩码
            img_mask = np.zeros_like(overlay)
            for c in range(3):
                img_mask[:, :, c] = color_mask[c]
            
            # 叠加
            overlay[m > 0] = overlay[m > 0] * 0.5 + img_mask[m > 0] * 0.5
        
        return (overlay * 255).astype(np.uint8)
    
    result = show_anns(masks, image)
    
    # 显示
    fig, axes = plt.subplots(1, 2, figsize=(14, 6))
    
    axes[0].imshow(image)
    axes[0].set_title('Original Image')
    axes[0].axis('off')
    
    axes[1].imshow(result)
    axes[1].set_title(f'SAM Auto-Mask: {len(masks)} objects')
    axes[1].axis('off')
    
    plt.tight_layout()
    plt.savefig('/mnt/agents/output/sam_auto_mask.png', dpi=150)
    plt.show()
    
    # 打印掩码信息
    print(f"\n掩码信息示例(前3个):")
    for i, mask in enumerate(masks[:3]):
        print(f"  掩码{i+1}:")
        print(f"    面积: {mask['area']} 像素")
        print(f"    边界框: {mask['bbox']}")
        print(f"    置信度: {mask['stability_score']:.3f}")
        print(f"    预测IoU: {mask['predicted_iou']:.3f}")

print("\n📊 自动分割结果已保存!")

5.3 实验2:交互式分割(点提示)

if SAM_AVAILABLE:
    print("\n" + "=" * 60)
    print("【实验2】交互式分割:用点击选择对象")
    print("=" * 60)
    
    # 创建预测器
    predictor = SamPredictor(sam)
    
    # 设置图像
    predictor.set_image(image)
    
    # 模拟点击:选择图像中心点
    h, w = image.shape[:2]
    input_point = np.array([[w//2, h//2]])  # 中心点
    input_label = np.array([1])  # 1=前景点,0=背景点
    
    print(f"点击位置: ({w//2}, {h//2})")
    print(f"标签: 前景点(要分割的对象)")
    
    # 预测掩码
    masks, scores, logits = predictor.predict(
        point_coords=input_point,
        point_labels=input_label,
        multimask_output=True,  # 输出3个候选掩码
    )
    
    print(f"\n生成了 {len(masks)} 个候选掩码,置信度:")
    for i, score in enumerate(scores):
        print(f"  掩码{i+1}: {score:.3f}")
    
    # 可视化
    fig, axes = plt.subplots(1, 4, figsize=(16, 4))
    
    # 原图+点击点
    axes[0].imshow(image)
    axes[0].scatter(input_point[:, 0], input_point[:, 1], 
                   c='red', s=200, marker='*', edgecolors='yellow', linewidths=2)
    axes[0].set_title('Click Point')
    axes[0].axis('off')
    
    # 3个候选掩码
    for i in range(3):
        ax = axes[i+1]
        ax.imshow(image)
        
        # 显示掩码轮廓
        mask = masks[i]
        contours, _ = cv2.findContours(
            mask.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
        )
        ax.contour(mask, colors=['yellow'], linewidths=2)
        
        # 填充半透明
        colored_mask = np.zeros_like(image)
        colored_mask[mask > 0] = [255, 0, 0]  # 红色
        ax.imshow(colored_mask, alpha=0.3)
        
        ax.set_title(f'Mask {i+1}\nScore: {scores[i]:.3f}')
        ax.axis('off')
    
    plt.tight_layout()
    plt.savefig('/mnt/agents/output/sam_interactive_point.png', dpi=150)
    plt.show()
    
    print("\n📊 交互式分割结果已保存!")
    print("""
解读3个候选掩码:
  掩码1(高分):通常是最合理的整体分割
  掩码2(中分):可能是局部部分(如只分手把)
  掩码3(低分):可能是更大范围(如包含相邻对象)
  
用户可以根据意图选择最合适的!
    """)

5.4 实验3:框提示 + 多点提示

if SAM_AVAILABLE:
    print("\n" + "=" * 60)
    print("【实验3】框提示与多点提示")
    print("=" * 60)
    
    # 框提示
    input_box = np.array([w//4, h//4, 3*w//4, 3*h//4])  # 中心区域
    
    masks_box, scores_box, _ = predictor.predict(
        point_coords=None,
        point_labels=None,
        box=input_box[None, :],  # [1, 4]
        multimask_output=True,
    )
    
    print(f"框提示: [{input_box[0]}, {input_box[1]}, {input_box[2]}, {input_box[3]}]")
    print(f"置信度: {scores_box}")
    
    # 多点提示(前景+背景)
    input_points = np.array([
        [w//2, h//2],      # 前景点:中心
        [w//8, h//8],      # 背景点:左上角(排除区域)
        [7*w//8, 7*h//8], # 背景点:右下角(排除区域)
    ])
    input_labels = np.array([1, 0, 0])  # 1=前景, 0=背景
    
    masks_multi, scores_multi, _ = predictor.predict(
        point_coords=input_points,
        point_labels=input_labels,
        multimask_output=True,
    )
    
    print(f"\n多点提示:")
    print(f"  前景点: ({w//2}, {h//2})")
    print(f"  背景点: ({w//8}, {h//8}), ({7*w//8}, {7*h//8})")
    print(f"  置信度: {scores_multi}")
    
    # 可视化对比
    fig, axes = plt.subplots(2, 3, figsize=(15, 10))
    
    # 框提示结果
    for i in range(3):
        ax = axes[0, i]
        ax.imshow(image)
        
        # 画框
        rect = plt.Rectangle(
            (input_box[0], input_box[1]), 
            input_box[2]-input_box[0], 
            input_box[3]-input_box[1],
            fill=False, edgecolor='green', linewidth=2
        )
        ax.add_patch(rect)
        
        if i < len(masks_box):
            mask = masks_box[i]
            colored_mask = np.zeros_like(image)
            colored_mask[mask > 0] = [0, 255, 0]
            ax.imshow(colored_mask, alpha=0.3)
            ax.set_title(f'Box Prompt\nMask {i+1}: {scores_box[i]:.3f}')
        else:
            ax.set_title('Box Prompt\n(No mask)')
        ax.axis('off')
    
    # 多点提示结果
    colors_pt = ['red', 'blue', 'blue']  # 前景红,背景蓝
    for i in range(3):
        ax = axes[1, i]
        ax.imshow(image)
        
        # 画点
        for pt, label, color in zip(input_points, input_labels, colors_pt):
            marker = '*' if label == 1 else 'x'
            ax.scatter(pt[0], pt[1], c=color, s=200, marker=marker, 
                      edgecolors='white', linewidths=2)
        
        if i < len(masks_multi):
            mask = masks_multi[i]
            colored_mask = np.zeros_like(image)
            colored_mask[mask > 0] = [255, 165, 0]  # 橙色
            ax.imshow(colored_mask, alpha=0.3)
            ax.set_title(f'Multi-Point\nMask {i+1}: {scores_multi[i]:.3f}')
        else:
            ax.set_title('Multi-Point\n(No mask)')
        ax.axis('off')
    
    plt.tight_layout()
    plt.savefig('/mnt/agents/output/sam_box_multipoint.png', dpi=150)
    plt.show()
    
    print("\n📊 框提示与多点提示结果已保存!")

print("\n" + "=" * 60)
print("【总结】SAM提示类型对比")
print("=" * 60)
print("""
点提示:
  ✅ 最快速,单次点击
  ⚠️ 可能有歧义(点在手把 vs 杯子)

框提示:
  ✅ 明确范围,减少歧义
  ✅ 适合对象边界清晰
  ⚠️ 需要画框,稍慢

多点提示:
  ✅ 最精确,可以排除区域
  ✅ 前景+背景点组合
  ⚠️ 需要多次点击

文本提示(SAM 3/GLIP):
  ✅ 最自然,说就行
  ⚠️ 需要额外的文本编码器
""")

5.5 实验4:SAM 2视频分割(概念演示)

print("\n" + "=" * 60)
print("【实验4】SAM 2视频分割原理(代码框架)")
print("=" * 60)

print("""
SAM 2视频分割流程:

步骤1:初始化
  from sam2.build_sam import build_sam2_video_predictor
  
  predictor = build_sam2_video_predictor(
      "sam2_hiera_l.yaml", 
      "sam2_hiera_large.pt"
  )

步骤2:加载视频
  video_path = "your_video.mp4"
  inference_state = predictor.init_state(video_path=video_path)

步骤3:第1帧加提示
  frame_idx = 0
  obj_id = 1  # 对象ID
  
  predictor.add_new_points_or_boxes(
      inference_state=inference_state,
      frame_idx=frame_idx,
      obj_id=obj_id,
      points=[[x, y]],  # 点击位置
      labels=[1],       # 前景点
  )

步骤4:传播到整个视频
  video_segments = {}  # 存储每帧的掩码
  
  for out_frame_idx, out_obj_ids, out_mask_logits in predictor.propagate_in_video(
      inference_state
  ):
      masks = (out_mask_logits > 0.0).cpu().numpy()
      video_segments[out_frame_idx] = {
          obj_id: masks[i] for i, obj_id in enumerate(out_obj_ids)
      }

关键机制:
  1. 记忆编码器:把每帧的特征存入记忆库
  2. 记忆注意力:当前帧查询记忆库,找相似对象
  3. 对象指针:跟踪多个对象(obj_id区分)
  4. 自适应更新:对象外观变化时更新记忆
""")

# 由于SAM 2需要特定环境,这里提供伪代码框架
# 实际使用时参考官方仓库

print("\n✅ SAM 2视频分割框架说明完成!")

六、应用场景

6.1 医学影像

任务:分割肿瘤、器官、病灶

传统方法:
  需要大量标注数据,且只能分割预定义类别
  "这个罕见肿瘤类型?模型不认识。"

SAM方案:
  医生点一下肿瘤区域 → SAM自动分割
  不需要训练!零样本分割!

应用:
  - CT/MRI中的器官分割
  - 病理切片中的细胞分割
  - 内镜视频中的病灶追踪

6.2 自动驾驶

任务:分割道路、车辆、行人、障碍物

挑战:
  - 开放世界:总有没见过的物体(新型滑板车、掉落货物)
  - 实时性:需要30FPS+

SAM应用:
  数据标注:自动生成分割掩码,人工只需检查修正
  训练效率提升10倍!

  在线检测:结合SAM 2做视频对象追踪
  即使对象被遮挡,也能记住并重新找到

6.3 图像编辑

任务:抠图换背景、对象移除、风格迁移

传统Photoshop:
  魔棒工具 → 调整边缘 → 蒙版细化 → 1小时

SAM方案:
  点一下对象 → 3秒出精确掩码 → 直接编辑

应用:
  - 电商:商品自动抠图换白底
  - 影视:绿幕替换
  - 设计:对象提取重组

七、核心总结

概念 一句话解释
SAM 提示驱动的任意分割模型,点/框/文本/掩码都能用
Image Encoder ViT-Huge提取图像全局特征
Prompt Encoder 把用户提示变成查询向量
Mask Decoder 融合特征+查询,输出精确掩码(3个候选)
歧义性解决 输出3个掩码供选择:局部/整体/相关
SAM 2 加入记忆机制,支持视频分割和对象追踪
零样本 没见过也能分,不需要任务特定训练

八、面试高频题

Q1:SAM和传统分割模型(如U-Net)的区别?

:U-Net等是"封闭式"模型:预定义类别,只能分割训练时见过的类。SAM是"开放式"模型:通过提示(点/框/文本)指定分割目标,零样本分割任何对象。SAM把"分割什么"的决策权交给用户,而不是模型自己决定。

Q2:SAM为什么输出3个掩码?

:解决提示的歧义性。一个点或框可能对应多个合理分割(如手把 vs 整个杯子)。3个掩码分别代表局部、整体、相关区域,让用户选择最符合意图的。这体现了SAM对"用户意图不确定性"的设计考虑。

Q3:SAM 2的记忆机制怎么工作?

:SAM 2维护一个记忆库,存储已处理帧的对象特征、位置、外观。新帧处理时,通过记忆注意力查询记忆库,匹配同一对象。即使对象移动、变形、短暂遮挡,也能持续追踪。记忆会自适应更新,适应对象外观变化。

Q4:SAM在工业部署中的挑战?

:1)Image Encoder太大(ViT-Huge,632M参数),推理慢;2)高分辨率输入(1024×1024)计算量大;3)提示编码和掩码解码需要多次前向传播。优化方向:模型蒸馏(MobileSAM)、量化、TensorRT加速、分辨率自适应。


九、课后作业

作业1:多提示组合实验

# 尝试组合提示:
# 1. 先点前景,再加背景点排除误分区域
# 2. 先用框提示大致范围,再用点提示精确调整
# 3. 对比单点 vs 多点 vs 框的精度差异

作业2:SAM辅助标注

# 用SAM自动生成COCO格式的分割标注
# 人工只需点击检查,大幅节省标注时间
# 目标:把标注效率提升10倍

作业3:思考SAM的局限

问题:SAM有什么做不到?

提示:
  1. 非常细小的结构(如头发丝)?
  2. 透明/反光物体(如玻璃、镜子)?
  3. 需要语义理解的分割(如"分割所有红色的东西")?
  4. 3D场景的分割?

十、下讲预告

第8讲:自监督视觉大模型——DINO与DINOv2

我们将:

  • 理解"自己教自己"的自监督学习
  • 探索知识蒸馏和动量编码器
  • 用DINOv2提取特征做相似度检索
  • 了解无标签数据训练的威力
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐