tacoriceの日記

間違い等あれば指摘して頂けたら嬉しいです。

HPAコンペのふり返り


どうも、tacoriceです。

 

 5/12に終了したKaggleのHuman Protein Atlas - Single Cell Classification コンペに参加しました。幸いなことに、銀メダルを獲得できたので、ソリューションについてふり返っておこうと思います。

 

f:id:pino080:20210518021155p:plain

 

コンペ概要

 本コンペでは、顕微鏡画像内の各細胞のタンパク質オルガネラ局在化ラベルを予測します。
 タンパク質は細胞プロセスで重要な役割を果たし、多くの異なるタンパク質が特定の場所に集まってタスクを実行します。このタスクの正確な結果は、どのタンパク質が存在するかによって異なります。1つのタンパク質の細胞内分布が異なると、細胞間に大きな機能的不均一性が生じる可能性があります。そのような違いを見つけ、それらがどのようにそしてなぜ起こるのかを理解することは、細胞がどのように機能するか、病気がどのように進行するか、そして最終的にはそれらの病気のより良い治療法を開発する方法を理解するために重要です。

 単一細胞の研究は、複数細胞の研究では見るのが難しすぎるメカニズムの発見を可能にします。単一細胞を研究することの重要性は、単一細胞分析の技術を中心とした生物学の進行中の革命に反映されています。
 顕微鏡検査は、細胞集団内のタンパク質局在の違いを研究する機会を提供します。顕微鏡画像のタンパク質局在パターンを分類するための現在の機械学習モデルは、細胞の全集団の要約を提供します。
 ただし、生物学における単一細胞の革命には、画像内の個々の細胞のパターンを正確に分類できるモデルが必要です。

 

 本コンペのタスクは、マルチラベル分類です。ただし、予測を行うテストデータには単一セルの変動(SCV)が高い画像が意図的に選択されています。そのため、train画像内に存在する複数の細胞に対し、単体の細胞のラベルを予測する必要があります。単体の細胞に着目した場合必然的に、正しくないラベルも含まれてしまうため、このような問題は弱教師あり学習として扱う必要があります。
 また、Code competitionであるので、推論はkaggleのカーネル上で行う必要があります。なお、結果の提出コードはGPUなら9時間、CPUなら9時間以内に実行されるものである必要があります。

 

データ

 データセットには合計19の異なるラベルが存在します。データセットは、1つのイメージングモダリティ(共焦点顕微鏡)を使用して、高度に標準化された方法で取得されます。ただし、データセットは、さまざまな細胞小器官のタンパク質パターンに影響を与える、非常に異なる形態の17の異なる細胞タイプで構成されています。

すべての画像サンプルは、4つのフィルター(個別のファイルとして保存)、目的のタンパク質(緑)、3つの細胞ランドマーク(核(青)、 微小管(赤)、小胞体(黄色))で表されます。

 したがって、緑色のフィルターを使用してラベルを予測し、他のフィルターを参照として使用する必要があります。ラベルは、以下にマップされる整数として表されます。

 

0. Nucleoplasm : 核質
1. Nuclear membrane : 核膜
2. Nucleoli : 核小体
3. Nucleoli fibrillar center : 核フィブリル
4. Nuclear speckles : 核スペクル
5. Nuclear bodies : 核内構造体
6. Endoplasmic reticulum : 小胞体
7. Golgi apparatus : ゴルジ体
8. Intermediate filaments : 中間径フィラメント
9. Actin filaments : マイクロフィラメント
10. Microtubules : 微小管
11. Mitotic spindle : 紡錘体
12. Centrosome : 中心体
13. Plasma membrane : 細胞膜
14. Mitochondria : ミトコンドリア
15. Aggresome : アグリソーム
16. Cytosol : 細胞質基質
17. Vesicles and punctate cytosolic patterns : 小胞 and 点状の細胞質ゾルパターン
18. Negative : 陰性

 

データは158.36 GBあり、内訳は以下になります。

  • train : トレーニング画像 87.2k枚
  • test : テスト画像(.png)※コンテストのタスクは、このフォルダー内の画像をセグメント化してラベルを付けることです。2236枚(Public only)
  • train.csv:トレーニングセットのファイル名と画像レベルのラベル
  • sample_submission.csv :正しい形式の提出ファイル

 上記以外に、外部データとして、77668 images * 4 channels(2.4TB)が使用できます。※内20%はtrain画像と重複

評価指標

 mAP (mean Average Precision)

 

解法

 下図のように、モデルは大きく分けて、単一セルモデルと画像レベルモデルの2種類使用しました。

f:id:pino080:20210517230823p:plain

 

 1024*1024でResizeした画像とセグメンテーションmaskのbboxを利用して単一セルの画像に切り分けてから、各単一セル画像に対して学習を実施しました。(セグメンテーションを実施するセグメンターはコンペティションのホストから提供されており自由に使用することができます)しかし、このコンペティションには、与えられた画像の中に複数ラベルが存在しており、単一セルに切り分けた場合の各セル画像のラベルには正しくないものが含まれてしまうという弱教師あり学習の側面があります。そのため、上記で分けた各単一セルの画像に対し、正しいラベルを当てはめることは困難です。実際問題として、各単一セルで学習させたモデルはあるepochを超えると予測スコアが減少するという過学習の現象が見られました。

 この問題の解決策としては、ハンドラベリング等力技で再ラベリングする方法もありましたが、膨大な時間と労力が必要なことに加え、AIモデリングによる課題解決という課題の趣旨と外れるため、そのような方法はとらずにスコアをあげる方法に取り組みました。

 また、他の問題として、核が画像からはみ出しているものや、ラベル数の不均衡問題もありました。

 ラベル数の不均衡問題は外部データを使用することで補強することができました(各ラベル10000枚くらいになるようにダウンサンプリングを実施)。これによりLBスコアは+0.01されました。ラベル数が不均衡の場合、loss にfocal lossを使用すると学習がうまくいく例は過去コンペでもありましたが、今回はうまくいきませんでした。

 弱教師あり学習に対する対策として、ピクセル値の違いを利用しました。もし画像内に異なるラベルのセルが存在する場合、染色強度が異なると仮定し、単一セルにcropした時に、画像のピクセルの平均値にばらつきがあると考えました。そこで、1画像あたりの平均値に対し、全画像の平均値の20%を閾値として除去したデータセットを用いることでモデルの精度向上に貢献しました。また、閾値を設けることで、核が画像からはみ出してしまっているものについても一定数取り除くことができました。(残念ながら、時間が足りなかったため閾値の比較検討はできていません)これにより、LBスコアは+0.03~0.04されました。

 

単一セルモデル

Model:ResNet50+EfficientNet B4

Image size:128x128

Loss:BCEWithLogitsLoss

Augmentation

Flip
TTA (n=3)

 

単一セルモデルの学習に用いたデータ

1024*1024でResizeされたtrain+extra画像から単一セルごとに切り分けられた単一セル画像

Train:179.2k枚
Validation:44.7k枚

 

 

画像レベルモデル

画像レベルでの一般的なマルチラベル分類を行ったモデルを単一セルモデルとアンサンブルすることで、LBスコアは+0.06~0.07されました。

 

Model:SEResNeXt50 32×4d+EfficientNet B7

Image size:640x640

Loss

BCEWithLogitsLoss (EfficientNet B7)
FocalLoss (SEResNeXt50 32×4d)

Augmentation:HorizontalFlip(p=0.5)

 

画像レベルモデルの学習に用いたデータ

Trainフォルダにあるgreen チャンネルの画像のみ使用

Train:17.4k枚
Validation:4.4k枚

 

結果 

 有名な研究グループが主催しているコンペということもあり、ほとんどシェイクせずにPublic 37th 、Private 36th(銀メダル獲得)でした。

f:id:pino080:20210517004201p:plain

まとめ

  • 今回のコンペのような弱教師あり学習ではデータ中心の傾向があり、データの前処理が精度に大きく影響した

  • ダウンサンプリング等で各ラベルの数を均一化することが重要である

  • 単一セルレベルと画像レベルそれぞれのモデルのアンサンブルが精度向上に効いた

 

感想

 本コンペは、比較的参加者の少ないコンペでした。データ量が大きいこともありますが、test画像をsegmentationしてからsingle cellに切り分ける処理において、timeoutやOOMが多発していたことが考えられます 。エラーを起こさずに実行することがなかなか難しいコンペでした。Timeoutは小さなモデルを使用することで解決できますが、OOMの問題はsegmentationとsingle cells cropping を batch処理することで解決しました。1batchの中で推論まで行い、終了後に生成したsingle cellsを削除するというものです。以下にUPしてありますので参考にしていただけると幸いです。

github.com

 難しいコンペでしたが、主催者側がセグメンターの提供や外部データ公開、discussionへの迅速かつ的確な回答等、積極的な姿勢がすばらしく、参加できてとても幸いでした。改めて、主催者とKaggle運営陣に感謝申し上げたいです。

 


そして、今回のメダルでKaggle Masterに昇格することができました!!

 

f:id:pino080:20210518001612p:plain

 

 約1年間、医療系コンぺ中心に参加してきました。CT画像やX線画像、テーブルデータ等たくさんのデータに触れることができました。また、技術的な面では、画像分類や物体検出、セグメンテーションまで触れることができ1つ1つが貴重な経験でした。1年前は、Python機械学習も全く分からず、モデルのトレーニングもろくにできませんでしたが、貪欲にメダル獲得を目指すことで、できなかったことが段々とできるようになってきたと感じます。さらに、シェイクアップやシェイクダウンをたくさん経験したことで、精神的にもだいぶ鍛えられたと思います(笑)

 Kaggleは噂通り、最高のデータサイエンス系学習プラットフォームと断言できます。

 今までは、精進のためにソロ参加に拘っていましたが、今後はチームも組ませていただき、貪欲に金メダルを狙っていきたいです。

MoAコンペのふり返り


どうも、tacoriceです。

 

先日終了したKaggleのMechanisms of Action (MoA) Prediction コンペに参加しました。

せっかくなので取り組み内容を残しておこうと思います。

薬のイラスト「カプセル」 | かわいいフリー素材集 いらすとや

 

コンペ概要

 Mechanisms of Action (MoA)  = 「薬の働き」の予測します。MoAとは薬物の作用機序のことであり、薬が治療効果を及ぼす仕組みのことです。 通常、薬がどの標的分子(タンパク質)と相互作用し、どのような影響を与えた結果、治療効果が得られるのかを、分子レベルで言及します。

 MoAを予測することは併用療法 や新薬の開発に役立ちます。本コンペは、MoA予測アルゴリズムの改善を通じて医薬品開発を前進させることを目的としています。

 本コンペのタスクは、マルチラベル分類です。データ1サンプルに対して1つのラベルが与えられているマルチクラス分類と異なり、マルチラベル分類ではデータ1サンプルに対して複数のラベルを予測します。
 また、Code competitionであるので、推論はkaggleのカーネル上で行う必要があります。なお、結果の提出コードはGPUなら2時間、CPUなら9時間以内に実行されるものである必要があります。

 

データ

 本コンペでは、遺伝子発現データや細胞生存率データ等の様々なインプットが与えられた異なるサンプル(sig_id)の作用機序(MoA)応答の複数のターゲットを予測します。予測するラベルは206種あります。

 データが不均衡で、50以上のラベルで陽性サンプル数が 0.1% 以下 (20サンプル以下) ですが、 あるラベルでは、陽性数が全サンプルの 3.5% (約830) あります。

 また、学習サンプルの 40% がすべてのラベルで 陰性であり、 50% 以上が陽性ラベルを1つだけ持ちます。 一方で、陽性ラベルを7つ持つサンプルもあります。 

 

  • train_features.csv : 訓練セットの特徴量(23814個x 特徴量 875個)cp_type は化合物(cp_vehicle)または対照摂動(ctrl_vehicle)で処理されたサンプルを示す
  • train_targets_scored.csv : スコア化されるMoAターゲット(206種)
  • train_targets_nonscored.csv :追加の(オプションの)MoAターゲット(402種)※ただし、予測もスコア化もされません
  • train_drug.csv:学習データのサンプルと薬剤IDの紐付けたデータ
  • test_features.csv : テストデータの特徴量(3982個 x 特徴量 875個)  テストデータの各行のスコアされたMoAの確率を予測する必要があります
  • sample_submission.csv : 正しい形式の提出ファイル

 

評価指標

 log loss score

 

前処理

Rank Gauss
・数値変数を正規分布に変換(ニューラルネットワークを使用する際の特徴量変換の手法として、 正規化や標準化よりも優れた性能を発揮すると言われています)

・外れ値の影響を軽減

・対象となる値を順位付けし、その順位を -1 ~ 1 の範囲に変換

・変換後の結果を分位関数に適用し、正規分布を取得

 

PCA
・次元削減と特徴量の追加

 

Variance Threshold
・分散が閾値以下のデータを特徴量から除外

 

 

モデル

 今回、マルチラベル分類ということで、GBDT系の勾配ブースティングは使用しませんでした。代わりにNN系のモデルを複数採用しました。理由としては、GBDTは各サンプルに対して1つのラベルを予測することに特化したモデルだからです。一応、サンプルそれぞれに対してモデルを作成すれば予測も可能ですが、206サンプル分必要になり、計算コストもかかります。一方、NN系のモデルであれば1つのモデルで予測が可能です。マルチラベル分類タスクを解くに際してはNN系のモデルを採用した方が良さそうです。

 

以下、採用したモデル(5つ)

MLP (with K Folds by Drug ID)
後半から開示されたDrug IDを用いてクロスバリデーションを実施しました。

また、nonscoredを含めたターゲットを用いて事前に学習した重みを用いて、学習を実施。

使用したモデルの中でもっとも良いスコア(public)を出力しました。

 

MLP (with DenoisingAutoEncoder)
DAE(DenoisingAutoEncoder)を用いて特徴抽出を実施。また、バリデーションの損失はepoch=30程度から改善しませんでしたが、エポック数を増やすほどCVが改善したのでエポック数を大きめに設定(epoch=70)しました(おそらく過学習

 

③TabNet
tabnetは表計算用のディープラーニングモデル。コンペでは、事前学習のないMLPに劣っていましたが、discussionでは予測結果の分布が違うことからアンサンブルに有用だと議論されていました。

 

④TabNet (with KMeans clustering)
前述の前処理に加えて、kmeansによる特徴抽出を実施。

 

⑤ResNet
resnetのアーキテクチャを模擬したモデル。

 

各モデルを以下にアップしたので詳細の説明は省きます。

github.com

 

 最終的には上記のモデルをアンサンブルし提出しました。publicとprivateテストデータの分布差の影響を避けるため、アンサンブルにはスタッキング等の手法は使わずに、単純に加重平均を用いました。Yirun Zhangさんが、OOFを用いた加重平均の重みの最適化方法を示したノートブック

を上げてくれていましたが、自分のモデルではスコアが伸びなかったため、最もスコアの高いシングルモデルとの相関の比を用いました。(※基準となるベストシングルモデルの重みは2倍しています)

 

以下に、各モデルの相関ヒートマップを示します。

f:id:pino080:20201208024526p:plain

 相関0.95以下のモデル同士のアンサンブルは精度向上に寄与するといわれており、上記の各モデルがそれを満たしていることが分かります。

 また、MLP (with DenoisingAutoEncoder)モデルはエポック70に設定し、かなり過学習していたモデルですが、スコアアップに役立ちました。これは、アンサンブルは一般的にモデルのバイアスを減らして未知の予測精度をよくするものである一方で、バリアンスが高くなりすぎることに対処したものです。下図は、高バリアンスと高バイアスの予測結果を模擬したものです。

f:id:pino080:20201213200855p:plain

 MLP (with DenoisingAutoEncoder)モデルのアンサンブル前後で以下のように予測結果の分布に変化があったと考えられます。

f:id:pino080:20201213200935p:plain

 実際値に対して少しバイアスが高くなる一方で、予測値の点がアンサンブル前より1つ多く実際値の中に入っており、バリアンスの調整に貢献したことが確認できます。

 以上より、シングルモデルのスコアが低くても、相関が大きく(0.7以上)且つアンサンブル後の公開スコアが向上するモデルならアンサンブルに役立つといえそうです。ただ、例外もあり、メラノーマコンペのようにpublicとprivateテストデータが大きく異なる場合は、アンサンブル後のpublic LBが悪くなってもprivate LBは向上する可能性があります。(※メラノーマコンペの時は、高スコアモデルの予測結果に偽陰性の疑いのあるものが多数確認されたため実施)

 publicとprivateテストデータが似通ているかどうかはコンペ終了後しか分からないので、上記のようなアンサンブルを行ったものと行っていないもの両方を提出することが1つの戦略だと思います。私は提出用submissionにはそれら2つを選択しました。


  結果は、過学習のモデルを少しアンサンブルしたものがprivate 0.01609でした。f:id:pino080:20201208032835p:plain

 

 public 161st 、private 61st(初銀メダル獲得!!)

f:id:pino080:20201213211550p:plain

 

 

まとめ

  • MoAのような連続値のテーブルデータでマルチラベル分類を行う場合はTabNetやMLPが高精度になりそう

  • TabNetはテーブルデータの予測精度向上に役立ちそう

 

 そういえば、今話題のmRNAワクチンの作用機序は従来ワクチンのそれとは異なる新しいものらしく、摂取に対して不安がないわけではありません。(宿主に変異リスクやウイルス粒子の情報がないため安全と言われていますが)作用機序の予測が安全な薬やワクチンの早期開発に役立つことを願うばかりです。

 最近のKaggleはmRNAワクチン開発や作用機序予測など、人類に貢献しそうなテーマが多く、その分だけやりがいがありますね。

 


残すところ、あと銀メダル以上1つ獲得で目標のKaggle masterです。

画像コンペで連敗しているので画像系でも結果出したいなと思います。

とりあえず、サンタさんにRTX3090をお願いするところから始めようと思います。

鳥コンペのふり返り

はじめに

 先日終了したKaggleのCornell Birdcall Identificationに参加しました。初めての音声認識コンペだったこともあり思ったようにいかず辛いコンペでしたが、音声処理や最近の音声認識のトレンド等色々勉強になったので記録として残したいと思います。
www.kaggle.com

 

コンペ概要

 音声データ(mp3)にどの鳥(264種類)の鳴き声が含まれているかを推定するマルチラベル分類のタスクです。
Code competitionであるので、推論はkaggleのカーネル上で行う必要があります。
学習データはシングルラベルですが、テストデータはマルチラベルでした。

 f:id:pino080:20200924072559p:plain

 

音声認識への取り組み方

 まず、最近の音声系の機械学習では音声データを画像に変換して、画像認識タスクとして解くことが主流のようです。これは、音声データを画像認識として落としこめばうまく学習できるのではという発想からきているようです。
機械学習分野の研究者、技術者は発想が豊かですね!

 具体的な手法については以下の記事で紹介されていますが、音声データをlogmel変換したメルスペクトログラムを画像としてとらえ、特徴抽出に2D CNNベースのモデルを使用し、CNNの出力である特徴マップで分類を行うという手法をとっています。出力はバッチサイズ、チャネル、周波数、時間の4次元あります。

qiita.com

 

 一方で、音声認識におけるデータ拡張手法は一般的な画像認識におけるデータオーギュメンテーションとは異なりSpecAugmentと呼ばれる手法がとられています。SpecAugmentでは時間方向での伸縮や以下画像のような周波数軸でのマスキングや時間軸でのマスキングの3種類が提案されており、認識性能の向上に大きく貢献しています。

f:id:pino080:20200924062601p:plain

qiita.com

 

実際のコンペの取り組み

 コンペ終了の約2週間前からスタートしました。音声認識コンペは初めてだったので公開カーネルやdiscussionの情報から自分でもできそうな手法を試していく方針で進めていきました。また、音声データの前処理の実装は追いつかなかったのでほぼ公開カーネルのものを引用させて頂きました。この辺の処理に関するカーネルがなければ参加できていなかったとさえ感じます。(thanks@Arai&Tawara)

 今回のコンペでは、事前学習のモデルとして主流のPANNsとResNeStを用いたものが多かった印象です。discussionでも、事前学習モデルの違いはスコアアップにほとんど差がないと議論されていたこともあり、それ以外のモデルは使用しませんでした。
 SpecAugmentの周波数マスキング(横方向)と時間マスキングを追加したり、値を大きくすると学習時のlossの減少が大きく、学習スピードが増加しました。ただ、publicスコアは向上しませんでした。また、CNNの構造や、画像サイズを変更しても、手元のCVは向上するのですが、publicスコアの向上は全く見られず、なおかつ、LBと相関があるCVが全くできないという状況でした。
 結局終盤まで、単体モデルでは公開カーネルを超えることができなかったので、方針をかえ、最後の三日間はスコアの良いアンサンブルの組み合わせを探すという方向に切り替えました。
手法としては、PANNsモデルの予測の閾値を高めに設定し、nocall(鳴き声なし)と予測される部分にResNeStモデルの予測結果で補完するという疑似的なアンサンブルの手法を取りました。
少し荒業な気がしますが、この結果何とか公開カーネルの壁を越えpublicで銅圏に食い込むことができました。

ソリューション

・ResNeSt50_fast model

image size: 224x547

loss:BCE

optimizer:Adam(lr=0.001)

scheduler:CosineAnnealingLR(T_max=10)

DataAugment:
・mixup
・SpecAugment

fold:StratifiedKFold(n_splits=5)

melspectrogram parameters:
・n_mels: 128
・fmin: 20
・fmax: 16000

threshold:0.46

 

・PANNs model

loss:BCE

optimizer:Adam(lr=0.001)

scheduler;CosineAnnealingLR(T_max=10)

DataAugment:
・waveform
・mixup
・SpecAugment

fold:StratifiedKFold(n_splits=5)

melspectrogram parameters:
・window_size=1024
・hop_size=320
・sample_rate=32000
・mel_bins=64
・fmin=50
・fmax=14000

threshold=0.7

 

 

結果

結果はpublic101位private123位でした。

少しシェイクダウンしてしまいましたが、なんとか銅メダル獲得です!

f:id:pino080:20200923050907p:plain

 

反省点

 今回、CNNの構造等のパラメータ変更中心にさわってみましたが、publicスコアの向上は全くみられませんでした。コンペ終了後の上位入賞者のソリューションをみると、音声ファイルから手動で鳴き声が現れてない部分を削除することや実際に音声ファイルをきいてクロップ時間変更をする等の前処理の部分で工夫しているものが多かった印象です。そこに関しては全然取り組めなかったのが大きな反省点です。

 

おわりに

CVの結果とLBが全く連動しておらず、色々と辛いコンペでしたが、学びも多く有意義な時間であったと思います。

kaggleに取り組む上で最も重要な忍耐力もだいぶ向上したと思います(笑)

今後も色々なコンペに挑戦していきたいです。

 

それからですが・・・

 

f:id:pino080:20200923050412p:plain

 通算でメダル二枚ゲットできたのでKaggle Expert昇格です!(パチパチ)
 
次はKaggle Masterを目指して腕を磨いていきたいです。
 

簡易メラノーマ診断キットを作成しました。

どうも、tacoriceです。

 

早速、メラノーマコンペで作成したモデルをもとに、簡易メラノーマ診断キットを作成してみました。

 

一応、正しく判別してくれているみたいで、最低限の組み込みはできたと思います。

せっかくだったので、自分の黒子も診断してみました。

以下が記事になります。

https://qiita.com/tacotacorice/items/40c267538e5ce55c3463

 

組み込みにはラズパイを使用しました。

最近のラズパイはEdge AIの分野で注目を集めており、多くの取り組みが散見されますが、自動運転への期待が大きいためか物体検出モデルの組み込みの情報が多い印象です。

一方で、画像分類タスクのものは少ないように思いますので、画像分類を組み込んでみたい際は、ぜひ参考にしてみてください。

重みとコードを少し変更すれば使えるようになると思います。

 

今回作成したものは精度や使いやすさに課題が残りますが、今後のAI実装の課題にしていきたいです。

 

 

メラノーマコンペ ソリューション概要

 

 

こんにちは、tacorice です。

 先日終了したkaggleのメラノーマコンペ SIIM-ISIC Melanoma Classification に参加しました。とても幸いなことに ゴールドメダルを獲得できました。Discussionの中で、私のアンサンブル手法等をブログに残してはどうかという提案を頂いたこともあり、自分の Solution 概要や取り組みについて残しておこうと思います。

f:id:pino080:20200831181504p:plain

 

 
1. コンペについて

概要
 皮膚の画像からメラノーマ(悪性黒色腫である確率を 0.0から1.0の間で予測するコンペです。


データ
 本コンペは データとして train 33126, test 10982 の画像データとテーブルデータを利用できます。データサイズはなんと108Gもあります!

 外部データとして、2017 ~ 2019 年のデータが利用できました。また、PubricスコアトップのChris 氏が画像のサイズごとに (128, 192, 384, 512, 768, 1024) データセットを公開してくれていました。(thanks to @cdeotte)(こういった貢献の文化があるkaggleは素晴らしい情報共有と勉強の場であると感じます)

 

評価指標
ROC-AUC score


2. 参加の動機

・丁度長期休暇中であったので、全力コミットできる時間があった
・医療機器メーカーの一員として医療分野の最先端のAI技術開発に参加してみたかった
・知人に臨床検査技師の勉強をしている方がおり、臨床検査の視点から色々と相談できると思った(コンペを通してAI技術について医療側の意見等も聞きたかった)

 

3. 戦略

 休暇といっても使える時間があまりなかったので、解法が分かりやすいカーネルを参考にモデルを作成し、とりあえずLBの上位を目指しました。
 適当なハイパーパラメータを探すためKaggleのTPUをがん回して色々試行しました。あとは、解法との類似点が少ない(相関が小さい)公開カーネルの予測とアンサンブルを実施。
 また、アンサンブル時は、何か指標が欲しかったので、以下のような処理を実装しました。

github.com

 

 シンプルな手法ですが、効率的に(少ないアンサンブルとsubmit回数で)スコア伸ばすことができました。個人的には、難解な手法を試すより、分かりやすい手法を使ってみる方がPDCAの回転が速く効果的であると思います。シンプルイズベストです。

 やっていることとしては、最高スコアモデルのスコアアップに寄与したモデルを基準として、あるモデルとのアンサンブルと最高スコアモデルのアンサンブルの差分が最小になる割り合いで、アンサンブルするというものです。要は、もっといいモデルでアンサンブルしようという試みです。また、差分が極端に悪いものは除外することで効率よくスコアを上げることができたと思います。
 ただこのような手法は、必然的にpublicデータにfitしていってしまうため、privateで高得点を狙う場合は、差分だけでなく、R2スコアが0.5~0.7(相関が小さい)くらいでかつ、publicスコアが上がるものを見つける方が賢明でしょう。(コンペ後に、privateスコアが高いモデルのR2は0.6くらいでした。逆にprivateスコアが低かったモデルではR2が0.9以上ありました。)
 この辺で、銅圏(上位10%)でスコアが上がらなくなってしまったのでdisucussionをあさりまくりました。異なる画像サイズで学習を行うと、それぞれの画像サイズのモデルがそれぞれ異なった特徴を学習できるため、アンサンブルすると汎化性能の良いモデルができるという主張を発見しました。 また、CVを信用した方が良いという議論が頻繁に行われていたため、CVを重視しつつ、128,192,256,384,512の画像サイズでのモデルを作成。Foldはリソースの問題で2~3しか設定できませんでした。(もっと大きいFoldや画像サイズ(712,1024)を試せていればさらに高い得点がでたかもしれません)

 

 しかしながら、先に説明したアンサンブル手法を実施した時に、アンサンブル後との差分をとった際、上記の複数画像サイズのモデルとの差が大きくなってしまいました。原因を探るべく、複数画像サイズのモデルの予測結果とベストスコアのモデルの予測結果を一つずつ比較して確認したところ、ベストスコアのモデルでは陽性率が低く予測されているものに対して複数画像サイズのモデルでは一部高く予測しているものがあることを発見しました。さらに、公開されている多くのカーネルでも同様に確認したところ、陽性率が低く予測されていました。
私はこれが多くのモデルでは偽陰性を示してしまっている可能性を考えました。臨床検査の勉強している知人にモデルの精度について相談した際に、偽陰性を示してしまう感度が悪いモデルはあってはならないという話を聞いていたこともあり、このモデルの割合を高めにしてブレンドに用いました。(画像サイズ別にみていったところ、384*384のモデルが特に偽陰性を示す割合が低かったため、最終的に384*384のモデルのみ使用しました。)

 

 最終的に次のモデルを提出しました。
①ベストスコア
②ベストスコアと偽陰性の割合が低いと思われるモデルのアンサンブル
③オーバーフィットの危険から、ベストスコア以外のモデル*と偽陰性の割合が低いと思われるモデルのアンサンブル 
*ベストスコア以外のモデルにはPak Lau9氏のMinMax ensembringモデルを使用しました(thanks to@Pak Lau9)

 結果としては、モデル③がprivate 4thの結果となりました。また、①がもっとも悪く、②がぎりぎり銅圏でした。この結果から次のことが導かれます。


・多くのカーネルの予測モデル同様、ベストスコアモデルもまた偽陰性と判定してしまう可能性が高い、感度が悪いモデルであったこと
・ベストスコアモデルがpublicデータにオーバーフィットしていたこと

 

 これらの結果から、精度の高いモデルを作成するためには、次のことが有効であると考えます。
・コンペ終了前後で多くの議論がなされていたようにtrust CV
・CVを信頼したモデルと相関が小さい多くのモデルの結果を比較し、傾向を観察すること

・あと、ドメイン有識者から話を聞くことも気づきがあって大事だと思います


4. Solution

AjayKumar氏の notebook をベースに作成しました。 (thanks to @ajaykumar7778)


Dataset:image only

External data : (2019,2018,2017)

Cross-validation : STRATIFIED KFOLD (k=3)

Augmentation :
・random_flip_left_right
・random_Saturation
・random_Contrast
・random_brightness

EfficientNet : B6

Pretrain : imagenet

Image size : 384*384

Loss : binary_crossentropy

Optimizer : Adam

Seed : 42

TTA : 15

Model building
from efficientnet import tfkeras as efn
base=efn.EfficientNetB6(input_shape=(384,384,3),weights='imagenet', include_top=False)
x = base(keras.layers.Input(shape=(384,384,3)))
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dropout(0.3)(x)
x = keras.layers.Dense(1024)(x)
x = keras.layers.Dropout(0.2)(x)
x = keras.layers.Dense(512)(x)
x = keras.layers.Dropout(0.4)(x)
x = keras.layers.Dense(256)(x)
x = keras.layers.Dropout(0.3)(x)
x = keras.layers.Dense(128)(x)
x = keras.layers.Dense(1)(x)
x = keras.layers.Activation('sigmoid', dtype='float32')(x)

1024のような大きい全結合層を入れているカーネルは本コンペではほとんど見られませんでしたが、私のモデルでは若干向上しました。(実務などで使う場合は計算コストの観点から追加しない方が良いと思います)


 今回やり残したことを下記にまとめておきます。
・さらに大きいFoldや画像サイズ(768*768,1024*1024)でのモデル作成
・EfficientNet以外のモデルの利用(ResNetやDenceNet)
・Psuedo labeling


5. 良かった点・悪かった点

 医療関係者からROC曲線や感度の大切さとかいろいろ話を聞けたこと。
これにより、病気であるのに病気でないと診断してしまうような偽陰性を示すことはあってはならないという信念の下、最終のアンサンブルを行う際に、モデル間で偽陰性を示してるものがないかを比較して重点的に確認できたことで、オーバーフィッティングの危険性に気付くことができました。

 一方で、kaerururuさんの記事を参考にテーブルデータを用いたLightGBMモデルをブレンドしたところ3位タイのスコアでした。テーブルデータはできる限り使用した方がよいでしょう。(LightGBMモデルが効くということはdiscussionで議論されていたようです。もう少し、discussion見てればなあ。)


6. まとめ

・医療系コンペに参加することで、医療分野へのAI技術の可能性がひしひしと感じられました。
・たとえ、モデルのスコアが低かったとしても、医療の分野では偽陰性を示してしまうモデルはあってはならないと思います。trust CVは偽陰性を高めないためにも重要な手法であると感じました。
・コンペであっても実務であっても、ドメイン有識者に話しを聞いておくことで、後戻りがなく後悔のないモデルができると思います。

 

7.今後

 コンペの復習と本コンペのモデルをマイコンに組み込み、簡易診断キットを作成してみたいです。

 

AIとの出あい

どうも、tacoriceです。

 

今回は、私とAIとの出会いについて思い出しながら書いてみようと思います。

 

きっかけ

 きっかけは大学時代の研究室の同期が自身の研究にニューラルネットワークを利用して、IEEEに論文を通したことに感銘を受けたからです。その同期は韓国人留学生で、一緒に受けていたAI関連の授業でそれを思いついたそうです。授業中に「これだ!」と言い放ってから、本当に実装までもっていくとは思っていませんでした。海外勢のチャレンジ精神には目を見張るものがあります。

 それまでは、AI技術はすごく遠いもののように感じていましたが、このことがきっかけで私もやってみたいと思い始めました。ただ、大学時代は、自分の研究成果を論文にまとめるのが精一杯で、AI技術まで手が出せませんでした。ただ、研究のアウトプットの部分で画像化のためにpythonを利用していたので、いつかAI実装にも挑戦したいと思っていました。

 大学院を修了してからは、企業に就職して、AIとあまり接点のないところにおります。一方で、大学院時代の努力が実ったこともあり、奨学金が全額免除になったので、余った資金をAI技術の勉強に投資したいと思い、本格的に勉強を開始しました。

 

学習法

 浮いた資金で、高スペックのパソコンや大量の書籍を購入して勉強していきました。

今住んでいるところでは、スクールや勉強会がなく、周りに詳しい方がいる環境になかったので、ほとんど独学で挑むこととなりました。

 ただ、現在は情報社会で、プログラムにエラーが出ても少しネットで調べればわかる時代です。諦めさえしなければ、大体解決します。

 一つ一つエラーをつぶしていくのは骨の折れる作業ですが、研究室時代に回路を自作していた経験もあり、しらみつぶしに調べていくのには慣れていたことで挫折は避けられました。コツとしては、一度に組み立ててから動かすのではなく、入力側から細かい機能に分けて、一つずつ動作を確かめていくことだと思います。

 

 現在は、データ分析コンペ参加や実務に利用できる部分を探すことで理解を深める努力をしています。

 

まとめ

 何かを始めるきっかけを作るには、やはり周りの環境というものが大きく影響すると思います。

 ただ、情報についてはネットを調べればわかる時代になったので、やり続けることさえできれば、AI技術であろうと結果は出てくると信じます。

 

 

 

G検定の受験記

どうも、tacoriceです。

 

以前、2020年7月4日に行われたG検定を受講し、無事に合格したので、記録として残しておきます。

 

G検定とは

ディープラーニングの基礎知識を有し、適切な活用方針を決定して、事業活用する能力や知識を有しているかを判定するために、日本ディープラーニング協会(JDLA)が実施している検定です。

 

受験の動機

ちょうど半額キャンペーンをしており良い機会かなと思ったことが大きいです。

もともと、公式テキストは買っていて、ある程度読んでいたのですが、読み進めていくうちに受験の意味を見いだせなくなり放置しておりました(笑)

 

もちろん、ディープラーニングをはじめとしたAI技術関連のことが多く学べてよいですが、どちらかというとジェネラリスト向けのものなので、この検定を取得したからといってAIを使えるようにはならないと思いました。

 

AIを実際に使っていくためには、実務に盛り込んだり、データ分析コンペに参加する方が効果的だと思います。

 

対策

受験日の3日前くらいから親知らずが痛み始めたことに加え、球種コンペの最終追い込みもしていたので対策はほとんどできませんでした。

この時ばかりは、半額キャンペーンにつられて申し込んだのが悔やまれました。

 

以前に公式テキストや参考書は一読していたので、パッと見返す程度は最低限実施しました。

また下記のサイトを参考に、キーワードはチェックしておきました。

scrapbox.io

 

 

結果と感想

辛い中受験したのですが、結果は合格。

 

問題も法律よりの問題が多く、自信がなかったので意外でした。

 

合格率が受験者の7割近くいたので、そこまで合格ラインは高くないのだと思います。

法律に弱くても、ディープラーニング周りの理論さえきちんと理解できていれば合格は可能だと思います。

最近は法律の問題も多くなる傾向にあるということで、世間的に、いよいよAIの実装段階に入ってきたのだと勝手に思っています。

AI実装にあたっては、法律もきちんと勉強しておかないといけないですね。

 

まとめ

G検定を取得することで、AIには何ができるかできないかくらいは把握できるとおもいます。ただ、実装のためにはどんな障壁があるかなどの泥臭い部分は分からないです。

何事も傍観するのではなく、データ分析コンペ等に参加して自らの手を動かしてみるのが一番だと思います。