Kaggle卵巣がんコンペで銀メダル取りました!

Yusuke Sasaki
JDSC Tech Blog
Published in
Feb 29, 2024

JDSCでデータサイエンティストをしています、佐々木です。
今日は同じDS部門のインターンである辻さんとkaggleの卵巣がんコンペに出場し、銀メダルを獲得しましたので解法等について記載していこうと思います。

【タスク】

医用画像から画像を5種類の卵巣がんの種類を分類するコンペです。特筆すべきポイントは3つです。

1つ目は画像データには2種類ある点です。倍率20倍のWhole Slide Images(WSI)と呼ばれる画像と倍率40倍のTissue Micro Array(TMA)と呼ばれる画像の2種類あり、train dataの99%近くがWSI画像です。一方でtest dataはWSIとTMAがおよそ半分ずつとなっており、TMAの精度が検証できない(CVと連動しにくい)点が、本コンペのポイントの1つでした。

そもそも医用画像を扱ったことがなかったため、WSI/TMAの理解やガンの種類によって画像がどう変わるのかを捉えることに苦労しました。そもそもTMAは切り抜いたものを並べて利用するものらしいのですが、本コンペではその1つだけを撮影しているようでしたが、この辺りを「そういうものだ」と受け入れられたのは、逆に医用画像素人だったからかもしれません。

本コンペのデータのイメージ

2つ目はWSI画像の画像サイズが非常に大きい点です。数万*数万ピクセルの画像もあり、サイズはバラバラでした。この容量の大きい画像をどう扱うかが、本コンペのポイントの1つでした。train dataとしてフルサイズのWSI画像と同時に、横幅を3000pxに統一縮小されたthumbnail画像も用意されていました。

最後にtest dataにしか含まれないoutlierが含まれる点です。評価指標がbalanced accuracy(各クラスのrecall平均)であったため、Trainデータでの5値分類のままのモデルとするとTestデータで精度が5/6倍になってしまいます。このようにOthersをどう扱うかも本コンペのポイントの1つでした。

【解法】

まず1つ目のポイントに対して、WSIとTMAでモデルを分けました。幸いにもWSI/TMAはファイルサイズを見れば分離できたのでそれぞれモデルを構築しました。

WSIモデル

2つ目のポイントにも記載の通り、かなり画像サイズが大きいです。このような画像にはMultiple Instance Learning (MIL) と呼ばれる手法を使うことが多いです。元画像をresizeしてしまうと情報が失われてしまう可能性があります。一方でcropした場合に病変箇所がcrop画像に映っていない場合もあります。MILでは画像をタイルごとに分割した上で、複数枚のバッチを作成し、そのバッチ単位で分類していきます。Prefered Netowkrs様のブログ[1]などを参考にしながら、attention basedなMIL手法などを複数実験していきました。
一方でMIL手法ではなかなか精度が上がらない日々が続きました。ChatGPTにも何度も医用画像を見るポイントについて聞く中で、縮小画像を9~16タイル程度の大まかなタイルに分けて予測する手法が最も精度高く予測できることがわかりました。この辺りは根拠があってというよりは検証を重ねた結果です。モデルのbackboneはConvNeXtなど色々な種類を試しましたが、最終的なタイル戦略においてはSwinTransformerが最も精度高く予測できました。この辺りは論文の通説よりも逆だったりするので、さまざま試してみるしかないという印象を受けました。

TMAモデル

TMAに関しては、学習データがそもそも少なかったため、WSI画像からTMAを生成するアプローチをチャレンジしました。WSI画像をTMA画像と同倍率同サイズにcropし生成するアプローチなのですが、ここでWSIは映っている全てが病変部位ではないという課題があります。今回のコンペではこれをみかねたのか運営側から途中でsegmentation maskが数枚だけ配布されました。そこでsegmentation maskから、病変部位であるかの0/1モデルを作成し、病変部位と判定されたTMAサイズのcrop画像をpseudo-TMA画像として扱うことでデータを増やしました。
TMAに対するモデルパイプラインは、試行錯誤の結果12枚のパッチを利用したMIL戦略が最も精度高く判定することができました。ただTMA画像が少ないこともありLB/CV差が大きかったのも事実です。モデルのBackBoneはConvNeXtを利用しました。

Outlierデータに対して

ある程度のところでCVでの予測精度が頭打ちになってきたため、最後の最後でOutlierデータの扱いに着手しました。最初は5subtypeごとに構築した2値分類モデルによって確率を出してその最大値によってOutlier判定をするなど、2段階なモデル構えで判定しようとしましたがあまりうまくいきませんでした。
試行錯誤した中で、Logitの最大値で学習データに存在しない外れ値を検出する方法が最も精度向上に寄与するということがわかり、終了まであと3日にして最後の精度向上を達成しました。

【コンペを追えて】

医用データを扱った経験の少ないメンバーでのkaggleチャレンジで、はじめは業界知見を収集するのに苦労しましたが、一度タスクに落とせてしまえば試行錯誤を楽しむことができたかなと感じております。また辛い時も苦しい時もいつもそばに仲間がいてくれる喜びを感じることができました。解法を工夫すればするほど、思わぬerrorやメモリerrorが起こります。Submitが通らずしんどい時こそチームで働く意義を感じることができました。

submission errorの数々

今後の業務にも生かしていきたいです。

【参考文献】

[1] https://tech.preferred.jp/ja/blog/extending-multiple-instance-learning-using-lesion-annotation/
[2] How the Softmax Activation Hinders the Detection of Adversarial and Out-of-Distribution Examples in Neural Network

--

--