ふぁむたろうのブログ

機械学習系のお話やポエムを投稿します

Kaggle Master になりました(ポエム)

先日(2019/11/19)念願(?)の Kaggle Master になることができました。

これまでの振り返りも踏まえて書いてみたかった Kaggle Master ポエムを書いてみます。

1. この記事の対象

  • Kaggle に興味がある人
  • 画像系コンペに興味がある人
    • ただし細かい技術的な部分はこのポエムでは触れていません
    • 筆者は画像系コンペしかメダル取れていません。テーブルコンペはほぼ未経験ですので参考になる情報はないです
      • LightGBM で Learning Rate をチューニングしてしまうくらい分かっていません
  • 暇な人

2. 結論

  • 運ゲーに勝ち申しました
  • Kaggle はソシャゲー。時間とお金をかけて殴りましょう
    • 誰がやっても時間かかる作業はあるので、どのコンペも最後までやって損はないと思います
  • とりあえずコンペ参加しましょう。ウチもやったんだからさ

3. これまで参加したコンペとかの履歴

時期 コンペとかイベント 戦果 コメント
2018/04 《Sansan×ヤフー×DeNA》Kagglerが伝える、Kaggleの楽しみ方 - connpass 当時 Master だった onodera さんと Expert のばんくしさんが登壇してたイベント。登壇されてた皆さん楽しそうだったので Kaggle って楽しそうだなと思いました
2018/04 TalkingData AdTracking Fraud Detection Challenge 上位 48%(1881/3946) とりあえずカーネルコピペしてキャッキャしてました。Negative Down Sampling すげーーー!!!とか思ってた時期です
2018/05 Kaggle Tokyo Meetup #4 - connpass   @osciiart さんが 2-stage コンペの闇について触れていたのを憶えています。その御蔭で気胸コンペでも正気を保つことができました
2018/09 今の会社に転職 機械学習楽しそうだったので、機械学習できそうなところに絞って 4-6 月あたりに職を探してました
2018/10-11 Airbus Ship Detection Challenge(船コンペ) 上位 82%(717/882) Segmentation とか UNet で余裕wwwと思って死んだコンペです。あと転職直後でそれどころではありませんでした
2018/11- 2019/01 Human Protein Atlas Image Classification(細胞コンペ・タンパクコンペ) 上位 32%(681/2169) PyTorch に少し慣れてきてチャレンジしたコンペ。1st の bestfitting 氏が metric learning とか言ってて「???」となりました
2019/03 会社の近くに引っ越し 通勤時間が 1.5時間(徒歩・バス・電車)から 20分(徒歩) になり Kaggle に使える時間が増えました
2019/04 まで 虚無の期間 何故か競技プログラミングにハマって「AtCoder たのち〜〜〜!!!」とか言っていました
2019/04-06 iMet Collection 2019 - FGVC6(壺コンペ) 上位31%(159/521) GWはずっとパイプライン組んでた気がします。カーネル難しいなとか、@tawatawara さんが上位にいてすげーーー!って思ってた気がします
2019/07-09 SIIM-ACR Pneumothorax Segmentation(気胸コンペ) Team Gold(12 / 1475) 初メダルでした。夏休みとか会社とかあらゆるリソースを捧げました
2019/10 Severstal: Steel Defect Detection(鉄コンペ) 上位14%(329/2433) 気胸コンペのパイプラインを反省して PyTorch-Lightning で挑戦して砕け散りました
2019/10-11 RSNA Intracranial Hemorrhage Detection(脳コンペ) Team Silver(42 / 1345) @Appian42 さんの神コードや計算環境に恵まれたのもあり Silver おいち〜〜〜!とか思ってました。Appian さん takuoko さん solo gold おめでとうございます
2019/11 Understanding Clouds from Satellite Images(雲コンペ) Solo Silver(69 / 1538) きつかったのですが年内に Master になりたくて 2週間チャレンジ。Appian さんのパイプラインとかも見習って再度 PyTorch-Lightning で挑戦しました

4. 各コンペ振り返り

ここではメダルを取れたコンペについて軽く振り返ります。

4.1 SIIM-ACR Pneumothorax Segmentation(気胸コンペ)・Team Gold(12 / 1475)

このコンペは胸部 X線画像から気胸の領域を検出する Semantic Segmentation コンペでした。
評価指標はよく用いられる Dice Score でしたが、気胸がないデータに対しては全く無い(all 0) と予測すると 1.0、そうでない(1pixel でも1となる)と 0 という、FP(偽陽性)に対して厳しい評価指標でした。
そのため、後述しますが気胸の有無をしっかり分類できるかがポイントでした。

4.1.1 参加した背景

この領域は会社としても無視できない領域でもあり、会社の業務として取り組んで良いという許可をいただきました(工数としてはお察し)。
正確には政治力の高いメンバーである Kさん(おそらく日本最高齢のMaster)が取ってきてくださりました。

そのおかげで会社で Kaggle していても白い目で見られなくなりました。加えて計算資源をゲットできたのは非常に大きかったです。 ただし一部業務として取り組む以上、あまりにひどい成果だと今後会社で取り組めなくなるためそれなりにプレッシャーはありました。

上記の背景もあり、今回のコンペでは捧げられるリソースを捧げきって Gold 取るぞという気持ちで始めました。

4.1.2 序盤

始めてから気づきましたが、僕の中での Segmentation は Vanilla UNet で止まっていました。ですのでその周りの Paper のサーベイカーネルの読み込みに時間がかかりました。またカーネルでは UNet(EfficientNet encoder) が公開されていましたが、こちらは Keras で書かれていたので泣きながら PyTorch 移植を行いました。

そのおかげでネットワークの変更やテンソルの扱いに慣れることができました。
(for 文をテンソル計算に拡張したりとか)

序盤でまだ参加者が多くなかったこともあり、60~50 位くらい(ギリギリ Silver 圏)から始められた気がします。 他のメンバーも Silver 圏にいたため、情報共有のためチームマージをしました。

マージ後は、K さんが僕が作った Classification Model の結果を組み合わせるとスコアが上がることを発見したので、私は Segmentation + Classification で進めることにしました。ただしコンペ後の Solution を見ると、Gold 圏の 2/3 ぐらいは Segmentation Model だけでもできていたため、この選択は早まりすぎたようにも思えます。

不思議だったのですが、Classification Model が効果ありそうということはチームで共有されていましたが、私以外は実装してくれませんでした。不思議です。やはり Classification は難しいのかもしれません。

4.1.3 中盤

ここらへんから他のチームメンバーは業務上の都合もあり、参加が難しくなってきました。
各 Augmentation の有無やしきい値調整とかは試していただきました。

自身の作業では、 cvpaper.challenge も始まっていたのでこちらを参考にいろんな論文をチェックしたり実装したりしてました。

また外部データセットとして NIH Chest X-ray dataset (デカい) と CheXPert(デカい) が Discussion 上で共有されていました。 これらのデータセットには気胸の有無に関するラベルが付与されていたため、Classification Model の精度向上が期待できました。
特に今回の Kaggle Dataset は NIH Chest X-ray dataset の一部のデータに対して気胸のマスクを付与しているため、私の中では NIH-dataset は必須だと思っていました。

ここらへんで夏休み含む 10連休を取って、外部データセットを使った Classification の精度向上や論文実装に充てました。ですので 2019年の夏休みは Kaggle しかしていません。

ですが悲しいことに、NIH Chest X-ray dataset はあまり役に立たないという結論に至りました。 正確には NIH のラベルは正確ではなく(ところどころ Kaggle Dataset と食い違う)、NIH のラベルを使ったモデルは有用ではありませんでした。ただし後の Solution を見ると pseudo labeling には有用そうでした。

また今回はデータの配布形式が DICOM 形式であり、患者の年齢や性別・撮影方向等が付与されていました。そのため CNN(2 class classification) で作った特徴量に対し、これらの情報を加えて LightGBM で分類してみました。

4.1.4 終盤

終盤では CheXpert を使った Classification の精度向上や Loss やモデルの細かい部分の調整をしてました。 加えて初めての 2-stage 制でしたので、 Train や Predict の再現性確認・ドキュメントの準備等も行いました。

終了三日前には泣きながら optuna で LightGBM のチューニングを行いました(後の反省会でボコボコにされる項目)。

1st-stage 終了時には、自分の成果物だけ固めてアップロードしました。

他メンバーについてはコメントを控えさせていただきます。

ちなみにこの時期が精神的に一番不安定だったような気がします。
「チームとはなんだろう(哲学)」「仮に Gold を取れたとしても、それは何もしていない人が Gold を取ることになり Gold の価値を下げてしまうのではないか?」
みたいな謎のことが頭の中をよぎっていた気がします。

こうして 1st-stage を終了しましたが、順位はこんな感じでした。

f:id:fam_taro:20191123171543p:plain:w500
金が遠い

4.1.5 2nd-stage とコンペ終了

2nd-stage では 1st-stage の test dataset のラベルが与えられており、再学習が許可されていました。さらにモデル毎に再学習するか否かを選択できました。
私の場合、Segmentation の一部のモデルでは再学習時にわずかに LocalCV が下がったため、再学習したモデルとしていないモデルが混在する submission となりました。

こうして 2nd-stage を終え長かった気胸コンペが終了しました。
ただし終了時はあと一歩 Gold に届きませんでした(12th までが Gold)。

f:id:fam_taro:20191123172057p:plain

終了当日は、とりあえず疲れていたのでサクッと社内用の資料やコード整備をして即帰ってスマブラして寝ました。

翌朝起床すると、takuoko さんから DM が来ていて Gold になっていることを知りました。どうやら上のチームが BAN されたらしいです。嬉しい気持ちもあったと思うのですが、一応昨日中に自分の中では終わったコンペでしたので困惑もありました。

f:id:fam_taro:20191123172823p:plain:w300
繰り上がりました

こんな感じで初メダルは Gold でした。Gold 取れたことはもちろん嬉しいです。 加えて今回のコンペではほとんど自分で Score を上げることができたので、自信を持つことができたのも非常に大きかったです。

4.1.6 気胸コンペ反省会(後日)

幸運にも takuoko さん、pocket さん、kiyo さんと反省会をすることになりました。会場は らくスパ1010神田 です。
コンペ参加者は私と takuoko さんのみでしたが、いろんなことを共有することができてよかったです。 ちなみに私は何も知らずに LightGBM で Learning Rate をチューニングしてました。もちろん反省会でボコボコにされました。

f:id:fam_taro:20191123174725p:plain
反省会の様子

4.2 RSNA Intracranial Hemorrhage Detection(脳コンペ)・Team Silver(42 / 1345)

このコンペは 脳MRI画像から各脳出血の種類を分類する multi-label classification コンペでした。

気胸コンペの振り返りとか業務で忙しかった中、タスク的に会社の対象領域でもあったので会社のメンバーで参加しました。

脳コンペはデータ数が多く(約70万枚)、計算資源的に厳しいコンペだったのですが、逆に課金すればある程度順位取れそうという下心もありました。コンペ中 @Appian42 さんが神コード(動かすと Gold になれる) を公開してくださったおかげで、このコードをベースに取り組みました。感謝の極みです。

このコンペは 2-stage 制であり、2nd-stage では追加 test data のごく一部(1% 未満ってなんだよ)しか public LB に反映されませんでした。それもあり 2nd-stage public LB はスコアが不安定で(takuoko さんとか 1st の SeuTao さんが下位 20% にいたりする)、自身の submit がバグっているかも分からずドキドキしました。

結果としては 1st-stage とほとんど shake もしておらず、無事に Silver 取れておいち〜〜〜!!となりました。

4.3 Understanding Clouds from Satellite Images(雲コンペ)・Solo Silver(69 / 1538)

上記の脳コンペ 2nd-stage(11/5-11/13)中はほとんどできることはなく暇であり、かつおそらく Silver は取れるだろうなと思ってました。ですのでせっかくなら年内にもう一つ Silver 取って †Master† になりたいなと魔が差しました。

ですが年内に終わるコンペのうち画像コンペ(かつ Segmentation が望ましい)が雲コンペしかなかったので、頑張って参加することにしました。

鉄コンペでは初めて PyTorch-Lightning を導入しましたが至らぬ点もあり爆死しました。雲コンペでは当時足りていなかった部分(細かい使い方)や @Appian42 さんのコード等を見習いもう少し実験を管理しやすくしました(yaml で設定ファイル書けるようにしたり)。その結果短い期間ではありましたが色々検証することもでき、運良く Solo Silver を取ることができました。

コードは下記に置きました。来週の分析コンペ LT までには README にちゃんと追記します。。。

github.com

5. まとめ

こうして振り返ると、改めて "会社"・"周りの人(Twitter 含め)"・"計算環境"・"開催されるコンペ" などあらゆるものに恵まれていたなと思います。
このような中で Kaggle に取り組むことができたのは本当に幸運でした。
私にとって参加して無駄だったコンペなど一つもなく、全てのコンペで学びや自身の成長が感じられたのも幸運でした。

6. 次の目標

2019年中に Kaggle Master になるという目標(先程立てた)は達成できたので、 次は 2020 年中に Grand Master を目指そうと思います。3ヶ月に1つ Gold (うち Solo Gold 1つ) 取ればなれますしね(ガバガバ計算)。 また個人としての成績を求めるだけでなく、 LT や Discussion を通じてコミュニティに色々還元できるように意識したいです。 その結果として界隈を盛り上げる一助になればと思います。