Kaggle Biohub 振り返り
はじめに
今回,Kaggle Biohub コンペティションに参加しました.個人的な順位は残念ながらメダル圏内には入れませんでした.
そのため,次回に活かすために,上位陣の write-up の手法をまとめます.
今回のまとめでは,各 write-up の詳細をまとめるのではなく,使われたアプローチ・技術・手法について整理・理解することを目的としています.
コンペ概要
- Biohub - Cell Tracking During Development
- タスク:ゼブラフィッシュ胚の 3D タイムラプス顕微鏡動画から細胞核を検出し,フレーム間でつないで,分裂も含めた系譜グラフ(lineage graph)を出力する.
- 入力:1 動画 100 フレーム,各フレーム 64 × 256 × 256 voxel(z 方向だけ解像度が粗い).
- 出力:1 細胞 1 フレームにつき 1 ノードと,フレーム間のエッジ.子を 2 つ持つノードが分裂.
- 評価指標:ノード数で補正したエッジ Jaccard + 0.1 × 分裂 Jaccard.
- アノテーションのない細胞どうしのエッジは基本的に減点されない.ただし推定細胞数より多くノードを出すと減点される.
- データの特徴
- アノテーションは約 13.3 万ノードで,全細胞の 1〜3% 程度しかなく,分裂は学習データ全体で 151 件だけ.
- 学習用の動画は 2 つの胚から切り出したもの.public LB と private LB は,それぞれ学習にない別の胚で,細胞の密度も大きく違う.
- 学習データには,同じフレームの重複や,画像全体が大きくずれる(ドリフト)箇所がある.
上位解法の全体像
このコンペでは tracking-by-detection(先に細胞を検出し,検出点どうしをつなぐ)が標準的な形で,上位 5 チームの解法も大まかな流れは共通しています.
- 検出:各フレームで細胞核の中心を見つける.
- リンク:隣り合うフレームの検出点どうしの対応をスコア化する.
- 分裂判定:どの細胞が分裂するか,娘細胞はどれかを判定する.
- 全体の決定:ILP / LP(整数計画・線形計画)でまとめて最適化するか,greedy(良い候補から順に確定)でトラック全体を決める.
- 後処理:ギャップ補完,短いトラックの削除,座標の平滑化など.
| 順位 | Private | Public | 検出 | リンク | 分裂 | 全体の決定 |
|---|---|---|---|---|---|---|
| 1st | 0.977 | 0.976 | 3D U-Net + Cellpose 風ヘッド | LightGlue 風 Transformer | Soon Net + fork ヘッド | greedy decode(貪欲法) |
| 2nd | 0.970 | 0.968 | temporal 3D U-Net(主モデル+補助モデル) | 動きの予測 + 学習したスコアラー | 親と娘 2 つを評価するスコアラー | 候補選択と修復の多段処理 |
| 3rd | 0.967 | 0.977 | 2.5D U-Net(EfficientNetV2-L / B7)+ 3D SegResNet | dense flow + Transformer matcher | 位置合わせした画像を入れる親モデル + pre / post | LP / MILP(HiGHS) |
| 4th | 0.962 | 0.969 | Cellpose 風の 3D Net(フレーム差分も入力) | LightGBM(幾何・Transformer・埋め込み) | 分裂 CNN + 勾配ブースティング | ILP(SCIP),ノードごとの分裂コスト |
| 5th | 0.955 | 0.972 | 公開ベースラインの temporal 3D U-Net | Transformer(新規細胞も出力,同一性ベクトルも学習) | リンカーの分裂ヘッド | 多段 ILP |
1st place
- 1st Place Solution
- 一言でいうと:手作り特徴だけに頼らず,3フレームの局所画像から,対象細胞の分裂状態と,前後フレームでの同一細胞・母娘の位置を推定するモデル(Soon Net)を作り,その出力を幾何特徴と組み合わせて学習リンカーに渡した.
パイプライン:検出(3D U-Net)→ Soon Net → 学習リンカー → greedy decode → 後処理
検出:3D U-Net + Cellpose 風ヘッド
- 前景確率と「細胞中心へのフロー」を出し,フローをたどって同じ中心に集まった voxel を1つの細胞にまとめる(Cellpose 風の方式).マスクが得られるので,体積や形をリンカーの特徴に使える.
- 学習の流れ:
- 事前学習:軽い MAE(入力の一部を隠して復元させる自己教師あり学習).細胞全体が隠れないよう,小さなブロックでマスクする.
- 学習:手作業で描いたマスクと,GT ノードに置いた小さなスタンプを教師にする.
- 再学習:2 の予測を,検出信頼度とトラックの継続長で絞り,擬似ラベルとして使う.
- 外部データ:Ultrack(細胞追跡ツール)の公開ゼブラフィッシュ胚データも,事前学習と擬似ラベルによる再学習に使う.
Soon Net:細胞ごとに分裂状態と対応位置を当てる(この解法の肝)
- 入力:細胞ごとに
t−1,t,t+1の3フレームを切り出し,tの対象細胞位置を示す Gaussian の目印を加える.これで「どの細胞について答えるか」を指定する.t+1の画像も見ているので,未知の未来を予測するのではなく,前後の画像内で対応する細胞を見つける. - 構成:小さな3D CNN でトークン化し,Transformer に通す.Primus の設計を参考に CNN tokenizer を小型化し,Transformer には EVA-02 のブロックを使う.
- 出力:分裂状態の3クラス(間期/もうすぐ分裂/分裂直後)と,FPN ヘッドから各フレームについて出す2種類の occupancy map.
- Continuation map:同一細胞の前後フレームでの位置を示す.
- Division map:母細胞から見た娘2つの位置や,娘から見た母細胞の位置を示す.
- 学習の工夫:
- 切り出し位置を大きくずらす.中央の細胞を答えるだけのズルを防ぎ,Gaussian の目印を使わせる.
- 間期の細胞には時間方向の augmentation を使う.
t−1の代わりにt−2,t−3,t+1の代わりにt+2,t+3も使い,大きな移動を学ばせる. - 初期モデルで分裂候補を掘り起こし,目視確認して学習データを増やす.
- OOF 予測から,間期なのに分裂前後と誤判定された hard negative を集める.
リンカー:LightGlue 風の Transformer
-
LightGlue(2枚の画像の特徴点を対応付ける Transformer)の考え方を参考にする.体積・形・位置などのノード特徴で各検出をトークン化し,フレーム
tとt+1の近傍細胞間で cross-attention をかける. - ペア特徴には,移動量や形状変化に加え,Soon Net の occupancy map を相手の位置で読んだ値を使う.親の次フレームのマップを子候補の位置で,子候補の前フレームのマップを親の位置で読み,双方向の対応の強さを見る.
- Pair ヘッド:2つの細胞の埋め込みとペア特徴から,各候補リンクを採点する.
- Fork ヘッド:各親について「子なし/子1つ/子2つ」を評価する.分裂は「分裂するか(kind)」と「どれが娘か(who)」に分け,
p(kind) × p(who | kind)とする.1つの softmax にまとめると,多数の娘の組み合わせに稀な分裂判断が埋もれ,誤分裂が増えたため.
デコード・後処理
- ILP は使わず greedy decode.各親の選択肢(子 1 つにつなぐ,分裂する)を「子なし」と比べ,「子なし」より有力なものだけを,差が大きい順に採用する.
- 各親は最大1つの選択肢,各子は最大1つの親という制約を守る.親が割り当てられなかった細胞は,新しいトラックの開始点にする.
- 後処理は最小限:分裂をまたいで娘が母側へ引っ張られない line-fit 平滑化,生まれた娘の次フレームでの再分裂禁止,1フレームのギャップ補完,3フレーム未満のトラック削除.
2nd place
- 2nd Place Solution
- 一言でいうと:弱い検出もすぐには捨てず,時間方向につながるかどうかで判断する.
パイプライン:temporal 3D U-Net(主モデル+補助モデル)→ 候補選択・リンク・分裂判定 → 補助トラックで修復 → 薄いトラックの復元
検出:temporal 3D U-Net
- 前処理:XY だけをブロック平均で 1/4 に縮小し,Z と同じ間隔(等方)のボリュームにする.
- モデル:
t−1,t,t+1の3フレームを入れる residual 3D U-Net(5フレーム版も併用). - 出力は4つ.
- 中心ヒートマップ:細胞の中心の候補.
- オフセット:縮小した粗いグリッドの中で,中心の位置を細かく補正する.
- 前フレームへの動き(不確かさ付き):前のフレームのどの細胞から来たかの候補を出すのに使う.
- 特徴ベクトル(descriptor):細胞の見た目を表すベクトル.リンクの判定に使う.
- 疎ラベル対策:「アノテーションあり/画像から背景と判断できる領域/不明」に分け,不明な領域はヒートマップの loss から除外する.
- 合成の薄い細胞:アノテーション付きの実細胞の短いトラックを切り出し,背景を引いてから暗く・ぼかして,同じ動画の別の場所に貼り付ける.
- TTA などで平均すると消えてしまうピークも,元の向きの予測から候補に戻す.
- 補助の検出器は主検出器と単純に平均せず,別にトラックを作って,抜けたトラックの補完とリンク・分裂の確認に使う.
トラッキング
- 候補選択:検出器は残す数より多めに候補を出すので,その中から残す細胞を選ぶ.
- セル数推定モデル:フレームごとに,残す細胞数の目安を予測する.
- LightGBM 2つ:候補ごとに「暗い細胞か」「細胞らしいか」を推定して順位を調整し,元の候補群を残したまま,既存の候補と離れた位置にある候補を追加する.
- 最終的な選択は,検出の確信度だけでなく,前後のフレームの細胞とつながりそうかも見て決める(近くの重複は除く).そのため,暗くても前後とつながる点が,明るいが孤立した点に勝つことがある.
- リンク:検出器が予測した「前フレームへの動き」から,前のフレームのどの細胞から来たかの候補を出す.それを学習したスコアラーが,距離・動き・検出の確信度・トラックの前後関係から採点する.
- 分裂:親1つと娘候補2つの組を,位置関係・見た目・前後のフレームの様子からまとめて採点する別のスコアラー.既存のトラックとの競合も考慮する.
- 修復:補助の検出器で作ったトラックを使って,主トラックに抜けている経路を補い,リンクや分裂が両方で一致するかを確認する.1フレームの抜けもつなぐ.
撮影条件のグループ分け
- 明るさ・コントラストなどの画像の統計量を標準化し,動画を K-means で2グループに分ける(アノテーションや胚の情報は使わない).
- 片方は背景が明るく,弱い細胞のピークが埋もれやすい.後段の補正の一部は,検証で効いたグループにだけ使う.
ポイント:薄いトラックの復元
- トラッカーが捨てた候補から長く続く経路を探し,元画像で「候補中心が周囲の背景より明るいか」を確かめて復元する.検出器は回し直さない.
- 背景が明るい方のグループだけに適用する.
3rd place
- 3rd Place Solution
- 一言でいうと:大きめのモデルのアンサンブルで検出を固め,フロー・対応付け・分裂の各モデルの出力を LP/MILP でまとめて最適化する.
パイプライン:検出 → dense flow → matcher → 分裂判定 → LP/MILP → 後処理
検出:2.5D U-Net + 3D SegResNet
- 2.5D U-Net:隣接する3枚の Z スライスをチャネルとして積み,事前学習済みの2D エンコーダ(EfficientNetV2-L,EfficientNet-B7)で特徴を取り,Z 方向にまとめて3D デコーダに渡す.この3枚は時間方向ではなく,奥行き方向の情報.CZII コンペ 4th place の自分たちのモデル構造を流用.
- 3D 側は MONAI の SegResNet.3種類のモデルのヒートマップを重み付きで平均する.
- 疎ラベル対策:DoG(古典的な blob 検出)の候補のうち,アノテーションと対応しないものの周りを loss から除外する.正例として追加するのではなく,細胞かもしれない場所を背景として学習させないための処理.
Dense flow:フレーム間の3D 変位場
- 連続する2フレームの画像から,各位置が次のフレームでどれだけ動くかを推定する小さな3D encoder-decoder.実データでは,位置合わせ後の画像の整合性などを使った自己教師あり学習,変形が既知の合成データでは教師あり学習を行う.
- matcher の候補探索と,分裂モデルに入れる画像の位置合わせに使う.
Matcher:対応付けの Transformer
- 隣り合う2フレームの検出点について,「どれとどれが同じ細胞か」をスコア化する.ここでは候補を採点し,最終的な接続は後段で決める.
- matcher 専用の2.5D U-Net の特徴を各検出点の位置で取り出し,フローで補正した位置情報とともに,フレーム内(self)とフレーム間(cross)の attention で比べる.
- 「対応する細胞がない」(null)のスコアも出す.
- 学習では,アノテーションのない細胞を「対応相手がいない(null)」の正解にはしない.アノテーションがないだけで,実際には対応する細胞がいるかもしれないため.
分裂判定
- 親モデル:次のフレームで分裂するかを判定する.入力は,元の
t−1,t,t+1の3画像と,前後の画像をtに位置合わせした2画像の計5つ.単一の変位場だけでは1 → 2の分裂を十分に表せないため,元画像も残す. - 補助に,分裂する親のさらに1フレーム前の細胞を識別する pre モデルと,分裂直後の娘を識別する post モデルを使う.それぞれ,判定対象の時刻を中心とする前後3フレームを見る.
LP/MILP:リンクと分裂を同時に選ぶ
- 先にリンクを確定すると,正しい娘が別の親に取られることがある.そこで,親の重複などを許さない制約の下で,残すノード・通常のリンク・娘2つをまとめた分裂イベントを同時に選ぶ.
- 疎ラベル対策として,候補ごとに「評価対象になる確率
a」と「評価対象だった場合に正しい確率q」を推定する.a × qを期待 TP,a × (1 − q)を期待 FP とし,これらとノード数から公式スコアの近似目的関数を作る. - ソルバーは HiGHS(LP 緩和を解き,必要なら MILP).
後処理
- ギャップ補完,小さい連結成分の削除,アフィンな動きのモデルを使った座標補正.座標補正ではリンクを変えず,位置の揺れを抑える.
4th place
- 4th Place Solution
- 一言でいうと:計算資源が少ないので,生物学的な観察(分裂の見た目,核の大きさ,組織のドリフト)を小さなモデルに落とし込む.証拠を組み合わせる部分は CPU の勾配ブースティング.
パイプライン:検出(3D Net)→ リンク確率(LightGBM)→ 分裂スコア → ILP → 後処理
検出:Cellpose 風ベクトル場の 3D Net
- 細胞確率と核中心への単位ベクトルを予測し,ベクトルをたどって核を見つける(1st と同じく Cellpose の考え方).
- dual-encoder の 3D U-Net.片方に現在のフレーム,もう片方に「次フレーム − 前フレーム」の差分を入れる.
- 細胞確率の loss は「アノテーションあり/確実な背景/それ以外」の3段階で重みを変えた BCE.「それ以外」も完全には無視せず,ごく弱く背景へ寄せる.ベクトル場には L1 loss を使う.
- 擬似ラベルで学習したモデル(ZebraHub のアノテーションのない胚も使用)は,半数以上のノードが GT だけで学習したモデルでも裏付けられるトラックだけを採用する.
- DoG で動画ごとの核の間隔を測り,疎な動画では検出の閾値を厳しくする.
リンク:LightGBM のエッジモデル
- 特徴は,幾何特徴,公開ベースラインの構造で再学習したリンカーの確率,InfoNCE(対照学習の loss)で学習した細胞埋め込みの類似度.
- この解法では,OOF の検証でほぼ無価値に見えた Transformer の特徴が,全データで学習した版では LB 改善に効いた.fold 版の性能だけでは,全データ学習版の特徴の価値を過小評価することがあった.
分裂:ノードごとの分裂コストを ILP に入れる(最大の改善)
- 分裂コストが全体で1つだと,「分裂を全く開かない」か「2細胞が近いとどこでも開く」になる.そこでノードごとにコスト
6 − 16·s(疎な動画では5 − 16·s)を設定する.sは,そのノードが次に分裂する母細胞である確率. -
sは分裂 CNN(5フレームの切り出しを見る)と,CatBoost・LightGBM の組み合わせ.特徴は「母細胞が丸く明るくなり,娘2つが現れて離れていく」という生物学に沿って設計する. - ラベルはアノテーション済みトラックからだけ取る.hard negative mining は悪化した(多くがアノテーションのない本物の分裂だった).
- ILP の後に fork verifier で娘2つの動きを確認し,分裂が疑わしい場合は弱い方の娘のエッジを外す.
ILP・後処理
- tracksdata(トラッキング用のライブラリ)+ SCIP(MILP ソルバー).
- 動き補正した平滑化,ギャップ補完,疎な動画では別の検出器による裏付けが少ないトラック区間の削除.
5th place
- 5th Place: 3D U-Net + Transformer Linker + Multi-stage ILP Tracking
- 一言でいうと:公開ベースラインの temporal 3D U-Net に Transformer リンカーを組み合わせ,ZebraHub での事前学習,新規細胞・分裂のヘッド,多段 ILP で強化した.
パイプライン:3D U-Net → Transformer リンカー → 多段 ILP → 後処理
モデル
- 検出:公開ベースラインの temporal 3D U-Net(前後のフレームも入力する3D U-Net).XY を平均プーリングで 1/4 に縮小して入力する.
- リンカー:フレーム
tとt+1の細胞トークンに self / cross attention.学習するのは4つで,出力はリンクスコア・新規細胞・分裂の3つ.新規細胞は「前フレームに対応相手がいない細胞」を指す.残りの同一性は,U-Net の特徴から作る16次元の見た目のベクトルとして学習し,トークンの入力に入れて,近くの別の細胞を区別する. - 事前学習:ZebraHub の公開データで事前学習してから,コンペのデータで fine-tune する.
多段 ILP
検出の確信度,リンクスコア,同一性ベクトルの類似度をコストに反映する.新規細胞スコアが高ければトラックの開始を,分裂スコアが高ければ分岐を選びやすくする.
- ILP1:確信度の高い細胞だけで解く.
- ILP2:細胞を増やして解き直す.ギャップは埋まるが,偽の分裂も増える.
- 新しい分裂の取り消し:1 になかった分裂を取り消す.追加された細胞自体は削除せず,別のトラックとして残す.
- ILP3:細胞と分裂は固定し,リンクだけ解き直す.
- 修復と平滑化:ILP4 で離れたトラックの終点と始点をつないで欠けた位置を補い,曖昧なリンクは見た目で再マッチする.最後にトラックの位置を平滑化する.
参考
| 名前 | どんなものか | 使ったチーム |
|---|---|---|
| Cellpose(Stringer et al., Nature Methods 2021) | 各画素が細胞中心への流れ(flow)を予測し,流れをたどって画素を細胞ごとにまとめる汎用セグメンテーション | 1st,4th(検出ヘッド) |
| MAE(He et al., CVPR 2022) | 入力の大部分を隠して復元させる自己教師あり事前学習 | 1st(小さいブロックで隠す軽い版) |
| Primus(Wald et al., 2025) | 3D 医用画像セグメンテーション用の Transformer.小さな3Dパッチをトークン化し,畳み込みへの依存を抑えて Transformer 主体で処理する | 1st(Soon Net の構造) |
| EVA-02(Fang et al., 2023) | RoPE や SwiGLU を取り入れた ViT の改良版 | 1st(Soon Net の Transformer ブロック) |
| LightGlue(Lindenberger et al., ICCV 2023) | 2 枚の画像のキーポイントを self / cross attention で対応付ける Transformer | 1st(リンカー) |
| Ultrack(Bragantini et al., Nature Methods 2025) | 複数のセグメンテーション候補から,トラックとして整合するものを ILP で選ぶ追跡手法 | 1st(公開胚データを外部データに) |
| CZII 4th place | 2D 事前学習エンコーダで z スライスを処理する 2.5D U-Net | 3rd(検出器) |
| SegResNet(MONAI) | 残差ブロックを用いた encoder–decoder 型のセグメンテーション CNN | 3rd(検出器) |
| EfficientNetV2 / EfficientNet | 計算効率を重視した画像用 CNN のモデル群 | 3rd(検出器・matcher・分裂モデル) |
| ZebraHub | ゼブラフィッシュ胚の公開顕微鏡データ | 4th(擬似ラベル),5th(事前学習) |
| InfoNCE | 同じものを近づけ,違うものを遠ざける対照学習の loss | 4th(細胞埋め込み) |
| DoG(Difference of Gaussians) | ぼかし幅の違う 2 枚の差で blob を見つける古典的な検出 | 3rd(loss の除外領域),4th(密度の判定・裏付け) |
| LightGBM / XGBoost / CatBoost | 勾配ブースティング | 2nd,3rd,4th |