SAM(Segment Anything Model)算法

发布时间:2026/6/4 16:16:32

SAM(Segment Anything Model)算法 SAM Segment Anything Model学习笔记一、SAM 是什么二、SAM 能做什么2.1 三种分割模式2.2 零样本迁移任务2.3 在医学图像领域的应用三、模型核心组件3.1 Image Encoder图像编码器3.2 Prompt Encoder提示编码器3.3 Mask Decoder掩膜解码器3.4 Image Encoder 原理ViTVision Transformer3.5 Prompt Encoder 原理四种 Prompt 统一编码1点Point的编码2框Box的编码3Mask 的编码4文本的编码需 CLIP 版 SAM3.6 Mask Decoder 原理从 Embedding 到掩膜3.7 训练目标三大损失函数1Focal Loss掩膜损失2IoU Loss交并比损失3判别损失Prompt 判别损失四、关键技术亮点4.1 Promptable Segmentation可提示分割4.2 模糊歧义处理4.3 高效实时推理4.5 数据引擎Data Engine如何用模型自己生成训练数据4.6 推理完整流程4.7 与其他分割方法的本质区别五、实验代码与结果5.1 实验环境5.2 完整实验代码SAM COCO 实例分割5.3 核心实验流程图5.4 实验结果分析5.5 实验结果5.5.1 分割效果图5.5.2 全局分数统计六、模型优缺点6.1 优点6.2 缺点6.3 SAM vs 其他分割模型对比七、应用流程总结一、SAM 是什么SAMSegment Anything Model是 Meta AI 发布的通用图像分割基础模型就像 NLP 领域的 GPT 一样——一个万物皆可分割的统一模型给任意图片中的任意物体生成高质量分割掩膜。一句话理解一个 prompt提示驱动的分割模型给点给框就能分割给整张图自动分割图中所有物体无需重新训练即可泛化到任意分割任务。二、SAM 能做什么2.1 三种分割模式模式输入输出典型场景点分割图片 任意一个点前景/背景该点所属物体的掩膜交互式分割框分割图片 任意一个框框内物体的掩膜目标检测后续处理万物分割图片无提示图中所有物体的掩膜预处理、全图分割2.2 零样本迁移任务SAM 在 SA-1B 数据集上预训练后无需微调即可直接用于边缘检测→ 直接在全图模式输出所有物体轮廓目标检测框→ 万物分割后提取外接矩形实例分割→ 对每个物体独立输出掩膜语义分割→ 对万物分割结果做类别映射指代分割Referring Segmentation→ 结合文本 prompt 实现说说哪个物体2.3 在医学图像领域的应用方向说明超声图像分割分割器官、病灶、肿瘤区域CT/MRI 分割零样本或微调后分割解剖结构息肉/病变检测消化道内镜图像分割细胞/组织分割病理图像分析手术器械分割介入手术实时分割引导三、模型核心组件SAM 由三个核心部分组成输入图像 │ ▼ ┌─────────────────────────────────────┐ │ Image Encoder图像编码器 │ ← 计算量大一次性处理 │ ViTVision Transformer │ └─────────────────────────────────────┘ │ ▼ image embedding ┌─────────────────────────────────────┐ │ Prompt Encoder提示编码器 │ ← 轻量级多种 prompt 融合 │ 点/框/Mask/文本编码 │ └─────────────────────────────────────┘ │ ▼ embedding 融合 ┌─────────────────────────────────────┐ │ Mask Decoder掩膜解码器 │ ← 输出多尺度候选掩膜 │ 轻量级 Transformer × 2 blocks │ └─────────────────────────────────────┘ │ ▼ 多个候选分割掩膜 置信度分数3.1 Image Encoder图像编码器作用将输入图像编码为特征向量image embedding是 SAM 中计算量最大的部分。架构预训练的MAE 视觉TransformerViT将图像分块16×16 patch通过 Transformer 多层编码。配置模型参数量特点SAM ViT-BViT-B/16~75M最快适合移动端SAM ViT-LViT-L/16~308M平衡精度与速度SAM ViT-HViT-H/14~636M精度最高计算量最大关键特性同一张图只编码一次所有后续 prompt 复用这个 embedding。3.2 Prompt Encoder提示编码器作用将用户的分割提示编码为向量。Prompt 类型编码方式点Point位置编码 正/负标签1/0→ 点向量框Box左上角 右下角点坐标 → 框向量Mask掩膜与 image embedding 逐元素卷积融合 → 低层特征补充文本TextCLIP 文本编码器 → 文本向量需 CLIP 版本 SAM特点轻量级几乎不增加计算量。3.3 Mask Decoder掩膜解码器作用将 image embedding prompt embedding 转换为分割掩膜。架构两阶段双向 Transformer 三尺度输出头[image embedding] [prompt embedding] │ ▼ ┌─────────────────┐ │ Transformer │ ← 双向 attention更新 embedding │ Block × 2 │ └─────────────────┘ │ ▼ ┌─────────────────┐ │ Output Head │ ← 生成 3 个不同尺度的掩膜 │ 高/中/低分辨率│ └─────────────────┘ │ ▼ 3 个候选掩膜 → 取 score 最高 → 最终掩膜多候选设计multimask_output同一 prompt 可能对应多个物体输出多个候选让用户选择。3.4 Image Encoder 原理ViTVision Transformer输入图片HxWx3输出特征图H/16 × W/16 × 嵌入维度处理流程图片HxW×3 │ ▼ 切分为 16×16 的 patch patch 数量 (H/16) × (W/16) 个 │ ▼ 每个 patch → 线性投影 → 嵌入维度向量 │ ▼ 加入位置编码Position Embedding │ ▼ 通过 N 层 Transformer Encoder │ 每层Multi-Head Self-Attention MLP │ ▼ 输出H/16 × W/16 × d 的特征图为什么用 Transformer 而非 CNN方式长距离依赖建模计算方式CNN卷积需要多层堆叠才能建立感受野有限局部卷积逐步扩大TransformerSelf-Attention 一步到位任意两个位置直接交互全局并行注意力三种规格对比规格patch 大小层数隐藏维度参数量推理速度ViT-B16×1612768~86M快ViT-L16×16241024~304M中等ViT-H14×14321280~632M慢3.5 Prompt Encoder 原理四种 Prompt 统一编码1点Point的编码点坐标 [x, y] 标签 [1前景 / 0背景] │ ▼ 位置编码sin/cos 正余弦编码 │ ▼ 与标签嵌入 concat → 点向量 │ ▼ 与 image embedding 做 Cross-Attention → 融合2框Box的编码框 [x1, y1, x2, y2] │ ▼ 角点位置编码分别对 x1,y1,x2,y2 做位置编码 │ ▼ 两个角点向量 → 与 image embedding 融合3Mask 的编码已知掩膜低级先验 │ ▼ 降采样到与 image embedding 相同分辨率 │ ▼ 与 image embedding 逐像素做卷积融合 │ ▼ 输出融合了先验信息的 embedding4文本的编码需 CLIP 版 SAM文本字符串 a cat │ ▼ CLIP 文本编码器预训练语言-图像对齐模型 │ ▼ 文本向量 → 与 image embedding 对齐融合3.6 Mask Decoder 原理从 Embedding 到掩膜输入image embedding prompt embedding输出多个候选分割掩膜阶段 1双向 Transformer 融合 ┌────────────────────────────────────────────┐ │ image embedding来自 ViT │ │ prompt embedding来自 Prompt Encoder │ │ ↓ │ │ Self-Attention双向image↔prompt │ │ Cross-Attentionimage↔prompt │ │ MLP 前馈网络 │ │ ↓ │ │ 更新后的融合 embedding │ └────────────────────────────────────────────┘ │ ▼ 阶段 2轻量级解码重复 2 次 ┌────────────────────────────────────────────┐ │ 对融合 embedding 做 │ │ · Token 解码读取 prompt 信息 │ │ · 上采样从低分辨率恢复到原始分辨率 │ │ · 输出 3 个尺度的掩膜预测 │ └────────────────────────────────────────────┘ │ ▼ 3 个候选掩膜 [H×W] 3 个置信度分数为什么输出 3 个尺度小物体 → 高分辨率掩膜更好大物体 → 低分辨率掩膜更稳定三选一取置信度最高的3.7 训练目标三大损失函数SAM 的训练是多任务联合训练核心有三个损失1Focal Loss掩膜损失L m a s k − 1 N ∑ i 1 N w i ⋅ log ⁡ ( p ^ i ) \mathcal{L}_{mask} -\frac{1}{N}\sum_{i1}^{N} w_i \cdot \log(\hat{p}_i)Lmask​−N1​i1∑N​wi​⋅log(p^​i​)作用像素级交叉熵损失对难分割的像素边缘、遮挡处加大权重让预测掩膜与真实掩膜尽量一致。2IoU Loss交并比损失L i o u 1 − I o U ( m ^ , m ) \mathcal{L}_{iou} 1 - IoU(\hat{m}, m)Liou​1−IoU(m^,m)作用直接优化整体重叠质量Focal Loss 管像素精度IoU Loss 管整体质量两者互补。3判别损失Prompt 判别损失L d i s c CrossEntropy ( s c o r e c o r r e c t , s c o r e w r o n g ) \mathcal{L}_{disc} \text{CrossEntropy}(score_{correct}, score_{wrong})Ldisc​CrossEntropy(scorecorrect​,scorewrong​)作用训练模型区分正确 prompt高分和错误 prompt低分对同一张图给出多个 prompt监督模型正确识别有效 prompt。四、关键技术亮点4.1 Promptable Segmentation可提示分割传统分割每张图、每个任务都需要专门训练一个模型。SAM一个大模型 prompt → 泛化到任意分割任务。4.2 模糊歧义处理同一个点可能属于多个物体如人和背景重叠处SAM 的解决方案输出多个候选掩膜而非单一结果。4.3 高效实时推理尽管是 Transformer 架构通过以下方式实现实时图像编码器只运行一次embedding 可复用轻量级 prompt encoder轻量级 mask decoder仅 2 层 TransformerViT-B 在 CPU 上即可实时运行4.5 数据引擎Data Engine如何用模型自己生成训练数据SAM 最有创新性的部分——自举Bootstrapping数据生成Step 1: 用少量标注数据训练初始模型 12 万张图学会基本的点/框→掩膜映射 Step 2: 用初始模型对大量无标注图片做分割 → 自动生成伪标签分割掩膜 Step 3: 用伪标签训练模型自身 Step 4: 用训练后的模型重新标注 → 生成更高质量的伪标签 → 再训练 → 再标注 → 循环迭代阶段数据量标注方式初始12 万张人工标注第1轮120 万张模型自动生成第2轮610 万张模型自动生成最终SA-1B1100 万张模型自动生成本质上用模型生成的数据训练自己逐步提升最终比纯人工标注快了 100 倍数据量大了 100 倍。4.6 推理完整流程以 SAM COCO 代码为例完整推理流程如下输入COCO val2017 中的任意一张图片 │ ▼ Step 1: read_image() → 图片读取 BGR 格式 → RGB 格式转换 │ ▼ Step 2: predictor.set_image() → 图像编码耗时主要在这里 ViT-B 编码器前向传播一次 输出image embeddingH/16 × W/16 × 768 ⚠️ 同一张图只执行一次所有 bbox 共享 │ ▼ Step 3: 对每个 COCO bbox → 构造 input_box [x1,y1,x2,y2] → predictor.predict(boxinput_box) │ ├── Prompt Encoder对 bbox 编码 → prompt embedding ├── Mask Decoder融合 image prompt embedding ├── 输出 3 个候选掩膜 3 个 scores │ ▼ np.argmax(scores) → 选分数最高的掩膜 │ ▼ Step 4: 掩膜二值化bool → uint8×255→ 保存 PNG时间分布估计步骤时间占比说明set_image()ViT 编码~80–90%主要瓶颈predict()每个 bbox~5–10%轻量级 prompt decoder后处理保存文件~5%很小关键设计Image Encoder 只跑一次、然后所有 bbox 共享 embedding这使得多物体分割的整体效率大幅提升。4.7 与其他分割方法的本质区别维度传统语义分割U-Net目标检测YOLOSAM训练方式每个任务单独训练每个任务单独训练一个模型干所有任务输入方式整张图进来直接分割bbox 由检测器内部生成外部给 prompt输出范围固定类别集合固定类别集合任意物体新类别❌ 需重新训练❌ 需重新训练✅ 直接分割SAM 的本质突破把分割什么的决定权从模型内部转移到了用户输入prompt。五、实验代码与结果5.1 实验环境importos,cv2,numpyasnp,torchfrompycocotools.cocoimportCOCOfromsegment_anythingimportsam_model_registry,SamPredictor5.2 完整实验代码SAM COCO 实例分割importosimportcsvimportcv2importnumpyasnpimporttorchfromtqdmimporttqdmfrompycocotools.cocoimportCOCOfromsegment_anythingimportsam_model_registry,SamPredictor# 配置 project_rootrE:\学习资料\研究生资料\机器学习\深度学习\segment-anything-maincheckpointos.path.join(project_root,sam_vit_b_01ec64.pth)image_diros.path.join(project_root,val2017)ann_fileos.path.join(project_root,annotations,instances_val2017.json)output_diros.path.join(project_root,sam_coco_output)mask_diros.path.join(output_dir,masks)os.makedirs(mask_dir,exist_okTrue)model_typevit_bdevicecudaiftorch.cuda.is_available()elsecpu# 工具函数 defread_image(path):datanp.fromfile(path,dtypenp.uint8)returncv2.imdecode(data,cv2.IMREAD_COLOR)defwrite_image(path,image):extos.path.splitext(path)[1]ok,encodedcv2.imencode(ext,image)ifnotok:raiseRuntimeError(fFailed to encode image:{path})encoded.tofile(path)# 主循环 cocoCOCO(ann_file)samsam_model_registry[model_type](checkpointcheckpoint)sam.to(devicedevice)sam.eval()predictorSamPredictor(sam)img_idscoco.getImgIds()csv_pathos.path.join(output_dir,results.csv)withopen(csv_path,w,newline,encodingutf-8)asf:writercsv.writer(f)writer.writerow([image_id,file_name,annotation_id,category_id,category_name,score,mask_path,])forimg_idintqdm(img_ids,descRunning SAM on COCO val2017):img_infococo.loadImgs(img_id)[0]image_pathos.path.join(image_dir,img_info[file_name])image_bgrread_image(image_path)ifimage_bgrisNone:continueimage_rgbcv2.cvtColor(image_bgr,cv2.COLOR_BGR2RGB)predictor.set_image(image_rgb)# Image Encoder只跑一次ann_idscoco.getAnIds(imgIdsimg_id,iscrowdFalse)annscoco.loadAnns(ann_ids)foranninanns:x,y,w,hann[bbox]ifw1orh1:# 过滤无效框continue# COCO bbox [x,y,w,h] → SAM box [x1,y1,x2,y2]input_boxnp.array([x,y,xw,yh])withtorch.no_grad():masks,scores,logitspredictor.predict(boxinput_box,multimask_outputTrue,# 多候选取最优)best_indexint(np.argmax(scores))best_maskmasks[best_index]best_scorefloat(scores[best_index])categorycoco.loadCats([ann[category_id]])[0]category_namecategory[name]mask_namef{img_id}_{ann[id]}_{category_name}_{best_score:.3f}.pngmask_pathos.path.join(mask_dir,mask_name)mask_uint8best_mask.astype(np.uint8)*255write_image(mask_path,mask_uint8)writer.writerow([img_id,img_info[file_name],ann[id],ann[category_id],category_name,best_score,mask_path,])print(done)5.3 核心实验流程图COCO val2017 数据集约 5000 张图片 │ │ 每张图遍历所有非 crowd 标注 ▼ Step 1: 读取图片 BGR → RGB 转换 │ ▼ Step 2: predictor.set_image() → Image EncoderViT-B │ ⚠️ 每张图只执行一次所有 bbox 共享 embedding ▼ Step 3: 对每个 COCO bbox → SAM prompt → 分割掩膜 │ ▼ Step 4: 多候选掩膜 → 取 scores.argmax() 最优 │ ▼ Step 5: 保存 mask PNG 结果 CSV5.4 实验结果分析# 按类别统计 SAM 分割置信度importnumpyasnpfromcollectionsimportdefaultdict results[]# 从 CSV 读取category_scoresdefaultdict(list)forrowinresults:category_scores[row[category_name]].append(float(row[score]))print(\n 分类别 SAM 置信度统计 )forcat,scoresinsorted(category_scores.items(),keylambdax:np.mean(x[1]),reverseTrue):print(f{cat:20s}: mean{np.mean(scores):.3f}, fstd{np.std(scores):.3f}, n{len(scores)})5.5 实验结果5.5.1 分割效果图COCO数据集图片分割原图分割效果5.5.2 全局分数统计指标数值总预测样本数36,334处理图片数4,952类别数量80平均分数0.9315标准差0.0546最低分数0.4909最高分数1.0268分数 0.9 占比78.5%28,537/36,334分数 0.8 占比96.9%35,215/36,334分数 0.7 占比99.6%36,175/36,334六、模型优缺点6.1 优点优点说明✅通用性极强一个模型分割任意图像的任意物体无需针对任务微调✅Prompt 驱动支持点、框、文本、全图多种交互方式✅零样本迁移预训练后直接用于边缘检测、实例分割等下游任务✅高效实时Image Encoder 只跑一次prompt 推理极快✅模糊歧义处理多候选掩膜输出覆盖多种分割可能✅大规模预训练1100 万张图、10 亿掩膜泛化能力极强✅开源可用代码、模型、数据全部开源社区活跃6.2 缺点缺点说明❌计算资源要求高ViT-H 参数量大边缘设备部署困难❌分割精度有限对小目标、遮挡严重物体的分割精度不如专用模型❌语义信息缺失本身只输出掩膜不包含类别标签需额外分类器❌视频处理能力弱SAM 只处理单帧图像时序信息需配合 SAM 2❌医学图像精度不足通用 SAM 直接用于医学图像精度较低需 MedSAM 等微调版本❌依赖高质量 bbox用 COCO bbox 作为 prompt 时bbox 质量直接影响分割效果❌多候选增加计算multimask_outputTrue 输出多个候选增加后处理负担6.3 SAM vs 其他分割模型对比对比维度传统分割模型U-Net等SAM原生SAM 微调MedSAM训练数据小规模专用数据集1100万张大规模少量医学数据泛化能力只对训练类别有效零样本分割任意物体专精医学任务Prompt 驱动❌ 不支持✅ 支持✅ 支持需微调必须微调可零样本直接用少量数据微调计算量较小中等ViT-H 大中等医学图像精度高专用中等需微调高专用微调七、应用流程总结1. 加载 SAM 模型基础版或 MedSAM 版 ↓ 2. 输入图像 ↓ 3. 提供 prompt点/框/文本/无提示 ↓ 4. SAM 生成高质量分割掩膜 ↓ 5. 后处理 · 提取轮廓 → 边缘检测 · 计算面积 → 尺寸测量 · 三维重建 → 体数据建模 · 类别映射 → 语义分割

相关新闻