Kaggle HuBMAP2023 上位解法まとめと復習
Kaggleにて、人間の血管細胞を見分ける画像コンペティションHuBMAP - Hacking the Human Vasculatureが開催されていました。
受賞者の皆様おめでとうございます!そして参加者の皆様お疲れ様です!
こちらに筆者も短い期間ですが、参加して楽しみました。上位解法を勉強と復習のためにまとめます。
コンペ概要
与えられた画像の中の指定された細胞を検知するのが目的です。
精度指標は IoU: 0.6 の Average Precision です。
細胞ごとの領域を求める検知のため、COCO Instance Segmentation の Mask mAP の領域の重なり具合が IoU: 0.6 で計算されると考えるとわかりやすいかもしれません。
人によるアノテーションは禁止された9時間制限のノートブックコンペです。
なので割とインターナルな戦いになったと思います。
コンペの特色
このコンペでは以下の点が特徴としてあります。
- アノテーターの成熟度
- スライス情報
- 検知すべき細胞以外のラベル
- 画像データの座標情報
- アノテーションされていないデータ
1. アノテーターの成熟度
アノテーションには種類として dataset
: 1 dataset
: 2 の2種類があります。
-
dataset
: 1 は専門の人がラベル付けしたアノテーション -
dataset
: 2 はそこまで専門ではない人がラベル付けしたアノテーション
となっています。実際に学習に使用すると 1 の方が効果的なんですが使い所や汎化性能の確認や、データの違いが鍵になります。
2. スライス情報
同一のスライドの画像かどうかの情報として WSI
: Whole Slide Images があります。
同一スライド内の画像は定性的に分布などが似ているため、検証データの扱いに関わってきます。
さらに、 public データまではどのデータが利用されるかが公開されています。
- の情報も加味すると、未知の
WSI
: 5 での汎化性能を高めるようなモデルを、CV と public LB のdataset
:2 のデータから判断しないといけないという課題が出てきます。
3. 検知すべき細胞以外のラベル
検知すべきクラスは blood_vessel だけなんですが、与えられているデータには、
- blood_vessel
- glomerulus
- unsure
の3種類が付与されていて、特にglomerulus
に関しては、提出時の Private ノートブックにも提供されるアノテーションになります。 blood_vessel と重なっている部分もあったりするので闇雲に消して良いのか?や、Nクラスで学習させるモデルが一番精度が良いのかなどが分析項目としてあります。
4. 画像データの座標情報
画像は単一のパッチだけでなく、大きな画像での座標が与えられているのでその情報を使用すべきか、または白抜きの部分はパッチ画像だけを見ても判断できないので、周囲の画像も使用すべきか?などが議論として現れました。
Kaggle Discussionより引用
5. アノテーションされていないデータ
画像は提供されているがアノテーションが付与されていないデータあります。
基本的には WSI
: 5 以降のデータです。機械学習には、pseudo labeling などの教師なし系の精度向上方法もあるので使い方については工夫の余地があります。
解法紹介
解法概要
主に以下などのアプローチがあったと思っています。
- Instance Segmentation
- Detection + Segmentation
- Semantic Segmentation + Instance Post Process
多かったものは Instance Segmentation
の手法でした。
それに加えて、TTA(Test Time Augmenation)と Ensemble(WBF, NMS)が基本構成だったと思います。
特に一貫していえるのは、Dataset
: 1 の信頼性を分析から見極めて、それを保持しつつも汎化性能を高めるような工夫が垣間見えたことです。それによって議論が多い、 dilation
を使用しないモデルが結構あります。
以下は上位者と一般解法との差異について
1th
- 指標はマスクでの mAP だが BBox mAP にて最適化した
- 理由は BBox での NMS などでほとんどが Mask mAP も決まるから
- EMA(Exponential Moving Average)
- mmdet の YOLOX などでは実装がある
- 単一モデルでタイミングさの EMA アンサンブル
- モデルは
RTMDet
,YOLOX
,MaskRCNN
- Augmentation は幾何系の激しいものを使用
- TTA なし
- Dilation はなし
- CV 戦略は WSI2 と DS2, WSI1 と DS1 を信頼してその中で分割
- それに対してデータ追加で精度向上を確認
個人的にちょっと驚いたのは推論 Notebook で Mask 生成は MaskRCNN の ROI Head にアンサンブルした画像パッチに対しての推論をしている部分です。可能ではあるんでしょうが、 MMを使いこなしてる感がすごいです
Github: https://github.com/tascj/kaggle-hubmap-hacking-the-human-vasculature
学習コードも mmベースでの公開なので再現性も高く、助かりますね
2nd
- CV 戦略は DS1 を選択
- そのうち、領域ごとに偏りがないように分割
-
staintools
の使用で Pre Augmnetation(静的な拡張) - タイル問題の利用として学習データに 128pix でパッディングして画像サイズ拡張
- 激しめの Augmentation (幾何と色共に)
- DS1 で Finetune
- Cascade Mask-RCNN
- backbone: convnext, coat, swin
- Daliation 有無のアンサンブル
- CV で全くきかないためなしを検討のこと
- 後処理
-
Glomeruli
の削除 - 信頼度 0.01 以下を削除(mAP 指標ではめずらしい?)
- 64pix 以下のマスクの削除
-
推論: https://www.kaggle.com/code/phamvanlinh143/hubmap-2nd-place-inference
Github: https://github.com/phamvanlinh143/HubMap_2023_2nd_Place_Solution
3rd
- モデル
- ViT-Adapter-L
- CBNetV2 Base
- Detectors
- ResNeXt, ResNet
- 外部データなし
- アンサンブル使用での Pseudo Label
- これによって DS3 などの活用
- 画像サイズ 1400, 1600, 2048 の大きめ
- Dilation はあり
- WBF アンサンブル
4th
- モデル
- CascadeRCNN (ResNeXt、Regnet)
- MaskRCNN (swint)
- HybridTaskCascade (Re2Net)
- Yolov6m
- CV戦略は DS1 の一部を選択
- 重複したアノテーションを削除(4.5%)
- ROI レベルで Detection モデルの検知結果を入れたアンサンブル
4th Place Solution [SDSRV.AI] GoNより引用 - 80pix 以下のインスタンスの削除
5th
- DS1 だけの学習(5 Fold)
- モデル
- detectoRS-r101
- htc-db
7th
- pseudo labels を
Dataset
: 2,3 で付与したこと - Mask R-CNN (Swin Transformer backbone, HTC RoI head)
- 大きめのサイズスケール(Random resize (768-1536))
-
region proposal
とRoI head
の両方でのアンサンブル - ランダム F-Fold の分割
- 後処理
- 小さい物体の削除
- 公開されている
glomerulus
の領域の削除
8th
- モデル
- YOLOv8 Seg X
- 3 クラス
- CV戦略
- wsiごとの fold
- 画像サイズ 768 (512 より良い)
9th
- Detection + Segmentation のアプローチ
- Detection
- YOLOv5
- YOLOv7
- YOLOv8
- Segmentation
- EfficientNetB1-Unet
- EfficientNetB2-Unet
- Detection
-
Dataset
:2 のバウンディングボックスの付け直し - Detection での候補出しに多くのモデルのアンサンブルとTTの使用
- モデル単体の NMS IoU 閾値: 0.6
- WBF の IoU 閾値: 0.7
-
unsure
ラベルも学習に混ぜていること
10th
-
Dataset
:2,3 への pseudo labeling - Dilation なし
- 解像度の向上(512 -> 640)
12th
- モデル
- Detection: Cascade Mask RCNN
- Backbone: Convnext v2 large
- Loss: FocalLocc
- pseudo labeling からの Dataset3 のみからの学習
- Augmentation
- GridDistortion の有効性
- AutoAugment, MixUp, Mosaic, RandomErasing
- Fine Tune
-
Dataset
:1 のみでの最適化
-
19th
- モデル
- Cascade Mask R-CNN (Backbone: ConvNeXt-tiny)
- シングルモデル
- 繰り返しによる Pseudo Labaling
- 多くの Multi Scale
-
dilation
を使用しない
効果的だった方法の答え合わせ
最重要
まずは何といってものこのコンペで重要だったことは以下の点だと思います。
Dalation
の使用の有無- どの
Dataset
を信じるか
1 の問題が Public LB でだけなぜか絶大に有効だったため、多くの人が罠にはまったのではないかと思います。いわゆる shape
ですね。
その理由も議論されていて、それに対して各が独自の分析をして結論を導いたようですがその分析の甘さなどが勝敗を分けたように感じます。全体を通して、dilation
はそこまで有効ではなかったようでした。
以下の公開ノートブックなどでもある程度のスコアが確認できます。
有効だったシーンは Detection
は画像の端での漏れがあったりするため、タイルでの繋がりを保管するために効いているとCVを可視化比較した時点思いましたが皆さんはどのような理由でしたか?
2 については、 1 を引き起こす説明付けにもなったりしたため、特に重要だったと思います。
上位陣は、Dataset
:2 の不確かさを正しく見極める分析を行なっているように感じます。そのため、解法にも Dataset
:2 を Dataset
:1 で学習したモデルの推論と比較したり、Pseudo Labaling(擬似ラベル)で付け直すなどの処理が現れています。
全体的には、Public:Private どちらも有効な Clean Data(Dataset
) を見つけることで、Dilation
の有無に関わらず、安定して高いスコアを出すようなモデリングができるかが勝敗を握っていました。
細かい実装
画像サイズ
大きい方が有効であるとの情報が多く、筆者も 2倍あたりが有効でした。
これは拡大する過程で情報増えてない?と思うかもしてませんが、拡大パターンによっては認識パターンに誤差が現れているからだと思っています。このコンペに限らず、最適な解像度の模索は必要だと思います。
TTA(Test Time Augmentation)
今回の精度指標が Average Precision
であるため候補を多く出すこともスコア向上に繋がります。
なので定番の Flip
, Rotate90
や Multi Scale(複数の画像サイズ)による推論が使用されている印象です。
加えて、Detection のタスクだと、バウンディングボックスの安定化のためにいくつかの候補だしに使用されていました。
Ensemble
このコンペでは以下の2つしか見ていません。
- NMS
- WBF
単体モデルの後処理で NMS からの WBF みたいな基本は良く見ますが、上位の工夫されている方は、この辺りでの集約するタイミングが異なったりしています。TTA で多くの候補だしをした場合は、NMS で、安定した候補であれば、WBF のような使い方でしょうか
Mask のアンサンブルも平均をとるか、投票をとるかなどがあります。このコンペでは単純平均が多く見られました。
モデル
モデルサイズ
とても大きいモデルが Public では有効では?みたいな情報でしたが Private
ではそこまで変化はありませんでした。(議論の余地あり?)
Ensemble での多様性を向上させるためが多いように感じました。
アーキテクチャー
こちらもある特定の種類がとても有効ではなかったように感じます。
- Detection
- YOLO
- Mask RCNN
- HTC
- Backbone
- Swin
- Efficientnet
- Convnext
新しいまたは、定番のもで色々と登場しています。
- Cascade
- Mask2Former
が上位ではないので気になったので使用して見ましたが公開ノートブックと同じような結果だったので大差はないのではと思いました。
しかし、Mask2Former
は CV が異常に高く、高速収束するので不安になった人が多いのではないでしょうか
NoteBook コンペ
このようなコンペをあまり理解していなかったため、最初は驚いた部分があります。
提出した先でのファイルが変更される(*.jsonl
)や、タイル情報(csv)が変更されるため、WSI
などの付加情報で推論時に Dilation
をかけたりかけなかったりが可能です。
それに実装もそれに合わせたようにしなければならないです。(慣れかもしれません)
筆者はそこで分析結果間違えていたので注意です。
最後に
最後まで読んでくださりありがとうございます!
Kaggle はほぼ初心者かつ英語は母語ではないので間違いがあれば教えていただけると幸いです。
Instance Segmentation
などで実装で何かの役にたつと嬉しいです
2週間の短い期間でもすごく楽しめたので上記の反省などを踏まえて、RSNA 2023 Abdominal Trauma Detectionに参加しようと思います。
この程度の分析など提供でも組んでくださる方いてると嬉しいです。
今回のようなことをにチームで答え合わせしつつ、議論できたらさらに面白いですね!
余談
1年前に登録してちょいちょいかじる程度でしたがコンペにも興味を持ったので Kaggle に本格参戦です。
盛り上がってないとのお話などを伺いましが全然だと感じています。1000名以上参加してますし、Discussion や Notebook も豊かな印象です。
参加するにあたって、少しばかり過去のコンペも調査したのですが、Hubmap 系列は結構不安定なコンペであるとわかってきました。皆さんも最高に Shake したのではないでしょうか?
著者も最高に金圏手前から 200位
くらい吹っ飛んだ一人です(いえーい!)
手元を見ると銀圏のある程度良いスコアがゴロゴロあるんですよね、、、皆さんもこんな感じで悔しい思いをされていると思います
後から答えわかって、高いスコアを選択するのは誰でもできますからね><
Dilation
については怪しいと思い、なし調整などもして見ましたが実装で間違えてましたね。
Trust CV もそこまでできなっかったので反省です。
private
はスコアのデバッグもできないので難しいと感じました。推論時間による学習なんかは尚更、難しいのではと思います。
I/O の高速化やメモリ管理、並列処理など小さな差ですが、学ぶことが多いと感じました。
今回の反省をしっかり活かして、Shake
少なそうな RSNA2023 に参加したいと思います(笑)
Discussion
kaggleの上位解法はどのように調べるのでしょうか?discussionのところにのってる、上位n位というタイトルの記事を上から順に読んでいくのでしょうか?
基本的にはそうですね。solution などで絞るともっと見やすいかもしれません。
回答有難うございます!solutionでfilterかけたら見やすくなりました。