コンペ中は精度向上に注力し、kernelやdiscussionのアイディアをあまり理解せずに取り入れることもあるので理解を深め次回に活かすために振り返ろうと思います。参加期間がかなり短かったので、内容は薄めです。コンペ概要や流行った手法は記載します。
どんなコンペだったか 概要編
金属画像から指定された4種類の欠陥を発見するタスクです。kaggleコンペ共通ではありますが、ドメイン知識が極端に有利にならないよう4つの欠陥が何なのかは説明されていません。見た感じ擦れたあとっぽいな、なんかの打痕っぽいなと想像することはできますが、どういう基準でクラス1が1と特定されるかは不明です。
どんなコンペだったか タスク編
Segmentationタスクです。コンペのタグには工場系画像というタグもついています。
鉄の表面がなめらかなものに限定されていれば画像処理で画素の変化量に着目することもできたと思いますが、凹凸のある鉄も画像に含まれていたので多くの参加者がDeep Learningを選択していました。
どんなコンペだったか その他制限事項編
コンペ的特徴
Submitに特徴があって、ネットワークをOffにしたkernelで1時間で推論が完了することという条件がついていました。IoT端末で推論することを想定しているのでしょうか?
学習済みモデルと必要ライブラリのセットアップに必要なファイルをデータセットに入れて、毎回推論させる必要があったので週30時間しかないGPUインスタンス起動時間がSubmitで削られる結構シビアなコンペでした。
※一般的なコンペではローカルで推論したCSVファイルを提出するだけでSubmit可能です。
※学習からSubmitまで全てkernelだけしか使えないコンペもあるので、kernel-onlyと捉えれば緩いとも言えます。
個人的な制限事項
個人的に公私ともに非常に忙しかったので、実質2週間チャレンジになってしまいました。コンペの存在自体は2ヶ月前くらいから知っていて時間ができたら参加しようと思っていたのですが。。。2週間なら睡眠時間削っても大丈夫という根拠ない基準でラスト2週間にラッシュかけました。
流行ったkernel
mlcomp
kernelリンク:学習用 推論用
mlcompという画像分類、セグメンテーションの学習をラップして良い感じに学習させてくれるpytorch製のツールがあって、mlcompで学習させた結果を用いたkernelが非常に高い精度を出していたので多くの参加者が参考にしていました。実際このkernelをforkした結果で得られるスコアの参加者が多数いましたね。
mlcompについては別記事を作成予定です。このkernelではmlcompの導入だけでなく、Segmentationタスクにおけるアンサンブル方法も実装されていたので、Segmentationに詳しくない人でも簡単にアンサンブルできたのも特徴です。
画像分類の併用
kernelリンク: https://www.kaggle.com/bibek777/heng-s-model-inference-kernel
Segmentationの前にまず画像分類で欠陥があるかないかを判定してする手法で精度向上を試みたkernelです(実際は別の人がDiscussionで精度向上を報告してくれて、このkernelの作者が Discussionに合わせて実装・公開してくれたもの)。事前に画像分類を入れることでFN(False Negative)が減る(と思われる)とのこと。実際減っていると思います。
選んだ手法
mlcomp+EfficientNet(pytorchのpretrainmodelリポジトリ名)+画像分類
mlcompのsegmentationモデルはpytorchのこのリポジトリを使っています。このリポジトリではEfficientNetも追加されているのですが、mlcompには反映されていません。EfficientNetとFPNの組み合わせが高精度になるというDiscussionがあったので、mlcompをforkしてEfficientNetを追加してアンサンブルさせました。
EfficientNetを追加したモデルはPublic LBが下がったのですが、コンペ完了後に確認したところPrivate LBは高かったです。EfficientNetを控えめにしたアンサンブルを一応最終Submissionsに選択しておいたおかげでPrivate LBの大幅ダウンを避けられてブロンズ圏内にShake up しました。(積極的にしたアンサンブルを選んでいればシルバー。。。)
精度が出なくて見送った手法
独自EfficientNet + RandomSampler
Discussionに上げてもらったEfficientNetが独自実装だったので真似して学習させたり、Resnet(Keras)でベースラインのモデルを作ったりしました。EfficientNetはモデルは提供されていたのですが、学習時にクラスを均衡にする処理が見つからず、独自実装が期間的に間に合わない関係でRandomSamplerにしたのでDiscussionほど精度が出ませんでした。KerasではAffinity Lossという不均衡データで精度が出せるLossを扱えるのですが、pytorchは慣れてなく導入できなかったのも痛かったです。
実質2週間チャレンジ(With毎日結構な残業)になりあまり独自手法を試せなかったのですが、ライブラリに手を入れる経験ができたのと、流行りのpytorchをメインに使えたので良かったかなと思います。(今までkerasとtensorflowしか使えなかったので)
やりたかったけど見送ったこと
浅いネットワークと深いネットワークの組み合わせ
深いネットワークでは畳み込みの過程で色とか模様の情報が失われるので、色や模様も重要な場合は浅いネットワークと組み合わせると良いと聞いたことがあります。特にzozoのTechBlogが参考になります。欠陥とされている部分が鉄の素人には模様に見えるので、画像分類にせよSegmentationにせよ良い精度が出るのではないかと思っています。今回はkerasで自作したモデルがイマイチ精度を出せず、pytorchでモデル追加するしかない状況に追い込まれました(自分のせい)。pytorchで0からモデルを組んだことがないのと、独自モデルをmlcompに追加するのは時間掛かりそうだったので見送ってしまいました。
mlcompへの自作モデルの追加
mlcompでのモデル生成はpytorchで重みを公開されているモデルを使用します。モデルの指定は設定ファイルで行い、設定ファイルを読み取って内部で良い感じに処理してモデルが生成されます。そのため独自モデルを追加するのがちょっとシンドイので見送りました。設定ファイルを書くだけで画像分類とセグメンテーションのモデルを生成できる非常に良い作りになっているので悪い点ではないですけど。
mlcompへのdata augmentationの追加
残念ながらmlcompには学習時にaugmentationするようなオプションはありません。独自で実装して追加しようと思ったのですが、デバッグしようにも家のGPUマシンでしかmlcompが動かせず、家についた頃には仕事でヘトヘトになっていたので学習用関数が画像とラベルをどんな形式で扱っているか確認できず見送りました。まぁその分EfficientNetの追加や独自EfficientNetを試せたので良しとします。
今後の課題
pytorchでいろんなモデルを組む
学習済みモデルを引っ張ってきてちょっと層を変えるレベルではなく、SiameseNetを自分で組んだりある程度柔軟にモデル構築をできるようにしたいです。最近はkaggleのkernelの大半がpytorchなのでpytorchで色々書けるとkagglerの知恵を借りやすいはずです。年末の第九シーズンはTuba吹きは休みなのでfast.aiでも見て学ぼうかと思っています。
Google Colaboratory 以外のGPUリソース追加
昔はこんなことなかったと思いますが、colabで学習を回し続けてshellで定期的にブラウザを開いていると、ランタイムから切断されることがよくありました。調べてみるとインタラクティブに操作している人に優先的に割り当てるため、使い方によっては割り当て優先順位が下がるみたいです。ローカルには高々6GBしかない1060が1枚あるだけなので、コンペ終盤はGCPの利用を本気で検討しました。
Colaboratoryが今まで大盤振る舞いしてくれていたので、この変更は痛いです(念の為ですが、今でも無料でGPUなりTPUが簡単に使えるのは異常な大盤振る舞いです)。kaggleも週30時間と上限を設けてきたので何かしらの方法でGPUリソースを増やす必要があります…
SegmentationタスクのCV
今回はモデルの推論結果を可視化して、目視(!!)で評価してました。。。CVは毎回kagglerから借りているので、自力で書けるようになりたいところです。教科書的なCVは出来るんですけどね。。。世のkagglerはどうやって考えているのでしょう。