状態:下書き(2026-10-13)、一部実測。 マスク損失の例はノートPCのCPUで直接計測した値です(
code/09_mask_losses.py、1秒以内)。オリジナルのSAMは我々の環境では動かしておらず(未実測)、速度については後継版のSAM 2.1 tinyの実測値を『TT Score モデル解剖』第3編から引用しています。論文の数値は原典を開き、条件とともに転記しました。 作成ルール:実測データを基本とし、計測できなかったものは「未実測」と表記します。
Segment Anything
目次
- 1. セグメンテーションの問いを変える
- 2. 構造:重い処理は1回、軽い処理は複数回
- 3. 学習の損失関数:focal + dice
- 4. データエンジン:モデルがデータを作り、データがモデルを育てる
- 5. 制限事項
- 6. 我々のプロジェクトとのつながり
- 参考文献
1. セグメンテーションの問いを変える
セグメンテーションとは、ピクセルごとに「このピクセルは何に属するか」を塗り分ける作業です。第3編のU-Netのように、これまでのセグメンテーションモデルは 何を塗るかが学習時に決まっていました。 細胞を学習したモデルは細胞だけを、人を学習したモデルは人だけを塗り分けます。
KirillovらのSAM(Segment Anything Model)はその問いを変えます。人間が プロンプト(点クリック、ボックス、大まかなマスク)を与えると、その場所の物体を切り抜く プロンプトセグメンテーションです。「何」を塗るかは学習時ではなく使用時に決まります。言語モデルが次トークン予測という1つのタスクで大規模学習を行った後にプロンプトで多様なタスクをこなすように、セグメンテーションにおいてもそのような「基盤モデル」を作ろうとする試みです。
2. 構造:重い処理は1回、軽い処理は複数回
SAMは3つのパーツで構成されています。
- 画像エンコーダー:MAEで事前学習したViT-H/16(第7編)。1024×1024にリサイズした画像を64×64の特徴マップ(16分の1に縮小)に変換し、1×1・3×3の畳み込みでチャンネルを256に減らします。解像度が高いため、ほとんどの層は14×14のウィンドウ内でのみアテンションを行い、グローバルアテンションは4つの層にのみ適用します(第7編3節のN²問題)。
- プロンプトエンコーダー:点やボックスの座標を位置エンコーディングにより小さなベクトルに変換します。大まかなマスクは畳み込みによって縮小し、画像特徴に加算します。
- マスクデコーダー:2層の軽量なトランスフォーマー。プロンプトトークンが画像特徴を参照し(プロンプト→画像)、画像特徴がプロンプトトークンを参照する(画像→プロンプト)双方向のクロスアテンションを行った後、マスクを出力します。
設計の核心は 計算の非対称性です。デコーダーはエンコーダーの計算量の1%をも消費せず、画像特徴をあらかじめ計算しておけば、プロンプトエンコーダーとマスクデコーダーは ウェブブラウザのCPU上で約50ms で動作すると論文で報告されています。人間がクリックを変更しながらマスクを修正する画面では、エンコーダーを画像ごとに1回だけ実行し、クリックのたびにデコーダーだけを再実行すればよいのです。
曖昧さ:3つの答えを出す
ラケットのラバー上の1点は、「ラバー」なのか「ラケット全体」なのか「ラケットを持った人」なのかが曖昧です。どれももっともらしい答えです。出力を1つだけにするよう強制すると、モデルは3つの答えの平均、すなわちどれでもないぼやんだマスクを学習してしまいます。SAMは1つのプロンプトに対して 3つのマスクとそれぞれの 予測IoU(このマスクがどれほど正しいかに対するモデル自身のスコア)を出力します。学習時は正解に 最も近い1つだけ が損失を受け取ります。
3. 学習の損失関数:focal + dice
マスクの損失関数はfocal loss(第4編)とdice lossを20:1の比率で混合します。diceは重なった面積の割合で採点します。
dice 손실 = 1 − 2·|예측 ∩ 정답| / (|예측| + |정답|)
なぜ画素平均の損失(BCE・focal)だけを使わないのでしょうか。256×256のマスクにおいて、小さなボール(81画素)と大きな卓球台(29,885画素)をそれぞれ 半分だけ塗った 予測の損失を測定してみました(実測)。
| 正解 | 画素数 | BCE | focal | dice |
|---|---|---|---|---|
| ボール | 81 | 0.0066 | 0.0065 | 0.449 |
| 卓球台 | 29,885 | 2.1215 | 2.1094 | 0.358 |
同じ「半分のがし」であるにもかかわらず、画素平均の損失はボールのミスを卓球台の約1/300として評価します。画像全体の画素数で割るため、小さな物体のミスが希薄化されてしまうのです。diceは物体自体の面積で割るため、両者を同程度に(0.45、0.36)罰します。大きさがバラバラな「何でも」をセグメンテーションしなければならないSAMにdiceを混ぜる理由はここにあります。
曖昧なクリックに対する「最も近い1つだけに勾配を伝える仕組み」も同じ例で確認しました。3つの出力(ラバー・ラケット・人の形状)に対して、正解がラバーであれば0番目、ラケットであれば1番目、人であれば2番目の出力を損失が最小となり、その1つだけが学習シグナルを受け取ります。出力を1つだけにして全てに合わせようとすると、その平均はラバー0.90、持ち手0.60、体0.30のような、どれでもないぼやけたマスクになってしまいます(code/09_mask_losses.out.txt).
4. データエンジン:モデルがデータを作り、データがモデルを育てる
「何でも」セグメンテーションするためには、何でもセグメンテーションされたデータが必要です。しかし、そのようなデータは存在しませんでした。SAMチームはモデルとデータを交互に成長させる データエンジンを稼働させました。
| 段階 | 方式 | 規模(論文) |
|---|---|---|
| 1. アシスト付き手動 | 人間がSAMで塗り分けて修正する。新しいデータでモデルを6回再学習(途中でエンコーダーをViT-BからViT-Hへ大型化) | 画像12万枚、マスク430万個。1マスクあたり34秒→14秒、画像あたりマスク20個→44個 |
| 2. 半自動 | SAMが自信のあるマスクを先に埋め、人間は 見落とされた部分だけを塗る | 画像18万枚からマスク590万個を追加(累計1020万個)。画像あたり44個→72個 |
| 3. 完全自動 | 32×32グリッドの1024個の点をプロンプトとして与え、予測IoU・安定性(閾値を少し変えても同じマスクになるか)・NMSでフィルタリングして残す | 画像1100万枚、マスク11億個 |
このようにして作成された SA-1B のマスクは 99.1%が完全自動生成されたものです。第2段階で1つのマスクに再び34秒かかった理由は、目につくものをモデルがすべて埋め、人間には目立ちにくい難しい物体だけが残ったためであると論文では説明されています。人間の時間を、モデルが苦手とする部分に集中させるための設計です。
画像の平均解像度は3300×4950であり、公開版では短辺を1500pxに縮小しています。モデルはデータセンター用GPU256基で68時間かけて学習されました(モデルカード)。コードと重みはApache-2.0、SA-1Bデータは研究用ライセンスです。
評価は、学習に使用していない23個のセグメンテーションデータセットにおいて、1つの点からマスクを出力する「ゼロショット」方式で行われました。論文では自動評価指標と人間による評価を併せて報告していますが、本記事ではデータセットごとの数値は省略しています。
5. 制限事項
- 名前を知らない。 SAMのマスクには「これが何であるか」という情報はありません。点を打った場所の物体を切り抜くだけです。「卓球台を探せ」というようにテキストで指定するには、第11番目のSAM 3や第12番目のオープンボキャブラリー検出器が必要です。
- エンコーダーが重い。 ViT-Hの1024×1024エンコーディングはデコーダーとは異なり軽量ではありません。リアルタイム映像のすべてのフレームに対して実行することは困難です(エンコーダーの速度はこの記事では検証できていません)。
- 動画を認識しない。 フレームごとに独立して処理するため、次のフレームで同じ物体を追跡して塗り続けるには、再びプロンプトを与える必要があります。これを解決したのが第10番目のSAM 2です。
- 曖昧さは3つでは終わらない。 「ラバー・ラケット・人」の3つを超える階層(ラケットの持ち手だけ、選手2人など)については、さらにプロンプトを追加する必要があります。
6. 我々のプロジェクトとのつながり
TT Scoreの卓球台検出において、 人間が卓球台を指定するタップがそのままプロンプトになります。「何を塗るか」を学習させる必要なく、人間が一度指し示すだけでよいという点こそ、この記事で紹介したプロンプトセグメンテーションそのものです。そして「1度のエンコーダー、複数回のデコーダー」という構造のおかげで、タップを修正しても再描画に時間がかかりません。後継版SAM 2.1 tinyの実測値(サーバーGPU、他のタスクと共有していた時期)は、画像エンコーディングが40ms、プロンプト予測が26msでした(『TT Score モデル解剖』第3編)。
ただし、1回のタップで描画されたマスクがテーブルの 上面だけでなく側面や脚まで含めてしまったり、ネットに遮られて片側半分しか描画されないケースがありました。そのため、タップを2回(ネットで区切られた2つの半分にそれぞれ1回ずつ)行い、マスクから四辺の直線再フィッティングを行って角を取得しています。モデルが描画した結果をそのまま使用するのではなく、幾何学的処理をもう一度加えることで精度を担保しました(同記事第3節)。
ティティの一言。 重いエンコーダーは画像ごとに1回、軽いデコーダーはタップごとに。だから卓球台を指し直してもすぐに再描画されるよ。
参考文献
- Kirillov, A. et al. (2023). Segment Anything. ICCV 2023. https://arxiv.org/abs/2304.02643, リポジトリ https://github.com/facebookresearch/segment-anything (Apache-2.0)
- He, K. et al. (2022). Masked Autoencoders Are Scalable Vision Learners. CVPR 2022. https://arxiv.org/abs/2111.06377 (SAMエンコーダーの事前学習。原理は姉妹シリーズ(自己教師あり・動画・姿勢・スポーツ))
- Milletari, F., Navab, N., Ahmadi, S.-A. (2016). V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation. 3DV 2016. https://arxiv.org/abs/1606.04797 (dice損失)
- 我々の測定:『TT Score モデル解剖』第3編(SAM 2.1 tiny)、リポジトリ
docs/tt/PERFORMANCE.md2.4 - サンプルコードと出力:このフォルダの
code/09_mask_losses.py,code/09_mask_losses.out.txt