見出し画像

【記事紹介】How Well Can You Kaggle with Just One Hour a Day?


🌟Kaggleのコンペティションと1日1時間の取り組みの重要性について

子育てや普段の仕事があると、どうしても自分のための学習の時間、例えばKaggleなどのコンペや資格の勉強などを独身の時と比べると確保できない実情があり、制限時間の中でどれだけパフォーマンスを出せるか、と言うテーマに興味がありました。

この記事は、Kaggleのコンペティションにおいて、1日1時間の取り組みでどれだけの成果を上げることができるかについての実験報告です。ほぼ原文記事の和訳ですが、備忘録のために記事として残します。ほとんど和訳です。

⏰記事の要旨

目的
- 1日1時間の取り組みでKaggleのコンペティションにどれだけ効果的に参加できるかを検証。

方法
- Humpback Whale Identification Challengeに参加し、1日1時間の制限時間でモデルを訓練。

ツール
- 実験にはW&B(Weights & Biases)を使用し、モデルのトラッキングと可視化を行った。

結果
- 1日1時間の取り組みでも、効果的な学習が可能であることが確認された。ランキングは上位25%に到達

📝結論

  • 1日1時間の制限時間でも、計画的な取り組みと効率的なツールの使用により、競争力のある結果を出すことが可能

  • W&Bの使用により、モデルの進捗とパフォーマンスを効果的にトラッキング。

キーワード

  • Kaggle, コンペティション, 1日1時間, W&B, データ拡張, 転移学習, アンサンブル学習


なぜこの取り組みを開始したのか

Kaggleの熱狂的なファンになってかなり経ちます。そして、コンテストがもたらす楽しさと激しさに吸い込まれるように参加してきたが、その過程でレベルアップしたり学んだりする運にはあまり恵まれなかった。なぜだろう?答えは簡単だ: カグリングに割く時間がなかったから、近道に頼っていたのだ。
Kaggleのコンペティションに参加すること自体がフルタイムの仕事のようなものだとよく耳にするが、まさにその通りだ。少し視点を変えてみると、私はフルタイムの仕事と家庭を持つ平凡な一般人です。そのわずかな時間を使って、Kaggleのコンペティションに参加しています。私のこれまでのやり方は、面白いと思うコンペティションを見つけ、時間があるときに公開カーネルやノートブックに手を加えるというものでした。以前はこのやり方を繰り返していたが、どこにも行けなかった!
この時点で、Kaggleへのアプローチを変えなければならないことに気づきました。気前のいいKaggleマスターやグランドマスターのブログやチュートリアルには、質の高いアドバイスがいくつもありますが、しばしば欠けているのは、時間とリソースに追われ、コンペティションを通して苦労し、その過程で何かを学ぼうとしている初心者やエンスージアストの生の経験です。例えば、何がうまくいかなかったのか?何がうまくいかなかったのか?どのようにしてフラストレーションを乗り越えたのか?
それがこのブログ記事につながる: 私は、いくつかのルールはあるものの、「正しい」方法で物事を進めることで、大会でどこまで勝ち進むことができるかを試してみることにした。

ルール

これまで私がKaggleのコンペティションでうまくいかなかった言い訳は、暇な時間がなさすぎることと、専用のGPUがないことの2つだった。問題は、それが正しかったかどうかだ。
この言い訳に真実があるかどうかを確かめるため、私は競技中に次のようなルールを自分に課した

- 60日間、1日1時間だけ働くこと(これにはモデルのトレーニング時間は含まず、コーディングや分析などに費やしたアクティブな時間のみ)。
- もし1日でも休んだら、残念だ。その1時間の時間はエーテルに失われ、保留時間に加えることはできない。
- すべてのステップを記録し、文書化し、参考文献を収集し、正当なクレジットを帰属させる。
- 既存のカーネル(特にトップスコアのもの)をやみくもに修正したり再利用したりしない。
- 計算リソースにはKaggleカーネルまたはGoogle Colabのみを使用すること。
- 現在の順位と戦略を評価するためにのみ、公開リーダーボードを使用すること。
- コンテストのルールを厳守すること。
- ディスカッションフォーラムを利用する
- 十分な休息

つまり、一般に利用可能な計算資源のみを使用してコンテストに取り組むには、60時間の活動時間が必要です。

セットアップ

🧮計算リソース
Google Colab + Kaggleカーネル(~30時間/週のGPU時間(コーディング時間ではありません!)

📓ジャーナリング
- Notionのページ(上の図を参照)には、やることリスト、日々の日記のセクション、参考文献のセクションがある。

🪛ソフトウェアリソース
- PyTorch、FastAI(最終的には)、Weights & Biases

☕その他
- たくさんのコーヒー
- 毎日60分で止めるポモドーロ式タイマー。


そのプレッシャーと長く働きたいという誘惑を避けるために、私は終了した大会を選んだ。この場合は、ザトウクジラの識別チャレンジだ。なぜか?このコンペティションは難易度が高かったが、データセットのサイズという点では、一般に利用可能な計算リソースでなんとかなりそうだったからだ。それに、少数ショットの分類について学ぶ機会にもなった。
課題の前提は、クジラの「フルーク」(要するに尻尾)の画像からクジラを識別するという、見かけによらずシンプルなものだ。平均平均精度@5スコア(mAP@5)で評価される。基本的に、あなたのモデルの上位5つの推測が問題のクジラを含んでいれば報酬を得られるが、あなたのモデルの順位と地上真実が同じような形で並んでいれば、より多くの報酬を得られる。したがって、予測の順番は重要なのだ。この課題を選んだ私は、日々の進捗状況や次にやるべきことを記録するための日誌を作成した。

各週の取り組み

1週目の取り組み

最初の1週間は、シンプルに物事を進めようとした。私の大きな目標は、データをインジェストし、W&Bにログを記録し、データを分析してそこから何が読み取れるかを確認することだった。
当初は、PyTorchやPandasなどを使ってゼロからパイプラインを書きたかった。結局のところ、この演習の目的は何かを学ぶことではなかったのだろうか?最初の楽観的な考えに後押しされ、データローダーとロギングフックを組み立て始めた。さらに、データをよりよく理解するためにいくつかの実験を行った。

例えば、上の例では、トレーニング画像のランダムなサンプルがあります。すぐに、画像はさまざまなポーズで撮影され、グレースケールであったり、テキストが入っていたり、必ずしもシャープでないことがわかります。さらに、このデータセットは非常にバランスが悪く、5005のクラスの1つには9k枚以上の画像がある一方、1枚しかないクラスもありました。このため、いくつかのオプションを考えました:
低サンプルのクラスは捨てる(これを試したが、事態を悪化させた)
ぼかし、ポーズ、アスペクト比などを考慮する。
グレースケール画像の扱いを変える
オーグメンテーションによってデータセットのバランスを調整する。
new_whaleクラスを削除し、このクラスを予測する他の方法を使う(結局こうした)
得られた結論(記事著者より)

2~3週目の取り組み

それからの数週間は、Pytorchを使って学習と推論のパイプラインを書いた。私の主な計算ソースはKaggleとColabだったので、Jupyterノートブックに書き出し、セルをスクリプトにリファクタリングする必要があった。
このアプローチには利点と欠点があった。手始めに、私はすべてを徹底的にテストし、変更をgitリポジトリできちんと管理することができた。さらに、これらの関数のいくつかは、将来のコンテストで再利用することができた。しかし、私はKaggleカーネルとColabしか使っていなかったので、gitリポジトリをこれらのいずれかと統合し、変更を管理するのは非常に困難でした(少なくとも私がコンテストに挑戦した時点では)。
もうひとつの難点は、私には1日1時間しか時間がなく、スクリプトとノートブックを行ったり来たりするのにかかる時間が複合的だったことです。時間を最大化するために、私は不本意ながらJupyterノートブックを使うことにこだわった。
ここで3つの重要な洞察を得た:
トレーニングセット全体で学習したモデルは、ほぼ常にnew_whaleを推測の1つとして予測した。なぜか?データにはこのクラスの例が9kあり、他のクラスを圧倒していた。そのため、モデルは検証セットとテストセットのほとんどすべての例について、やみくもにこのクラスを予測し始めた(public mAP@5 0.541)。これはディスカッション・フォーラムでもよく見られる傾向のようだったので、群衆の知恵を借りて、「新クジラ」の画像をすべて削除した。推論時には、モデルの信頼度スコアのしきい値を用いて、与えられた例が新クジラかどうかを確認することにした(これについては後述する)。

もし層化K-foldクロスバリデーション(CV)を使いたいのであれば、サンプルが少ないクラスを処理しなければならない。このため、画像が5枚以下のクラスをすべて削除して、K-fold CVを使おうとした。しかし、これはスコアを大幅に悪化させた(公開mAP@5 0.452)。ディスカッション・フォーラムでは、物体検出器を使ってクジラの周りの狭い範囲を検出して切り出し、背景を省くという投稿がいくつかありました。調べてみると、Martin Piotteのノートブックに、まさにこれを実行するモデルを学習させた珠玉のものがあった。当時このコンペティションは数年前のものだったので、私はこのノートブックを正しく動作するように更新し、クジラを検出して画像から切り出すようにモデルを学習させた。これによりスコアは0.486に向上した

サンプルの少ないクラスを削除する代わりに、Albumentationsを使ったデータ補強を使って、少ないクラスのサンプル数を増やしてみました。これにより大幅な改善が見られ、わずか20エポックのトレーニングで、私のモデルは0.611のmAP@5を獲得した。


まとめると、私のデータ前処理は以下の通り:
-トレーニングセットからすべてのnew_whale画像を削除。
- 学習済みのバウンディングボックス検出モデルを使用して、残りの画像をすべて切り抜く(注:背景の風景にモデルが驚かないように、テスト画像も切り抜く😅)
- 20枚未満の画像を持つすべてのクラスを、少なくとも20枚の画像を持つように補強
- 層化5回CV

4~5週目の取り組み

データの前処理がある程度固まったので、次に、どこで最高の利益が得られるかを確認するために、いくつかの簡単な実験を試してみることに集中した。公平な」比較を行うため、トレーニングを20エポックに固定し、すべてのフォールドにわたって各セットアップを評価した。

例えば、Resnet-18、Resnet-34、Resnet-50、VGG-16(もちろんすべてImageNetで事前学習済み)などから、さまざまなアーキテクチャを試してみた。なぜ最新のものを試さなかったのかと不思議に思うかもしれない。 有限の計算リソースとタイムアウトの制限(Kaggleでは~9時間、Colabでは~12時間)を考えると、妥当なバッチサイズでメモリに収めることができ、この演習から意味のあるものを得られるモデルは限られていた。また、様々な損失関数(バニラのクロスエントロピー、フォーカルロスなど)や画像サイズ(224、384、512)も試しました。これらの実験からわかったことは以下の通りだ:
- 画像サイズは大きな影響を与え、画像サイズが大きくなるとmAP@5は着実に増加した。私はすべての実験を最小のサイズ(224)で試し、最終的にはより大きな次元でモデルを再トレーニングしてスコアを押し上げることにしました
- モデル・アーキテクチャは、小さいながらも重要な役割を果たし、大きいモデル(例えばResnet-50)は小さいモデルよりも良い結果を出した

興味深いことに、不均衡クラス問題で一般的に使用されるフォーカルロスは、まったく役に立たなかった。

これらの実験に加えて、ミックスアップラベルのスムージングプログレッシブ・リサイズなどのトリックを試して、これらがさらに役立つかどうかを確かめたかった。多くのトップ・スコアがアンサンブルの結果であることを考えると、私は後の段階でアンサンブルするために様々なモデルを用意したかった。フォーラムでは、計量学習や対照学習について多くの意見が交わされており、時間が許せばこれも試してみたかった。

いくつかの有望な方向性を探ることができたにもかかわらず、私は2つのことに阻まれた。
第一に、コンテストの評価基準の実装が楽観的すぎた。例えば、公開スコアが0.54の場合、私の予測CVスコアは0.8だった。これは、私のコードと、おそらく私のCVスプリットの両方に疑問を抱かせた。
二つ目の問題は、ディスカッション・フォーラムでは、私がこれまでに試した組み合わせでは可能であることを示す投稿が多かったのに、何をやってもパブリック・スコアが0.7を超えないことだった。前者の問題については、公開されているカーネルとgithubにあるメトリックのより良い実装を2つ見つけ(Radekに感謝!)、それを使うことで私のCVスコアがより意味のあるものになった。2つ目の問題については、補強後の画像をプロットしたところ、パディングの選択に起因するいくつかのアーチファクトを発見してショックを受けました。以下は、アーチファクトを修正する前と後の2セットの画像です:

データセットを作り直し、その上、自分の発見が本当に正しいかどうかを確認するために、以前の実験をすべてやり直さなければならなかったからだ。この2週間の残りの時間は、自分の発見を検証し、データセットを修正する時間だけだった😣 。

6~7週目の取り組み

挫折を乗り越えた私は、上記のような便利なトリックを試したり、より大きな解像度の画像で最終モデルを再トレーニングしたりという大変な仕事に直面した。この時点で、私はいくつかの難しい決断を下さなければならなかった。私はメトリック学習とコントラスト学習の追求を断念し、純粋な分類ベースのモデルを改善することだけに集中することにした。
さらに、より複雑なトリックのいくつかを実装し、テストし、使用するのにかかる時間は、法外なものになるだろうと考えました。そこで私は、FastAIに頼ることにし、彼らの素晴らしいフレームワークを残りのチャレンジに使うことにした。FastAIライブラリを知らない1e-7%の人のために説明すると、これはPytorchの上に構築されたフレームワークで、TensorflowのKerasのようなものだ。学習と推論を単純化する高水準の抽象化であることに加え、多くのテクニック(いくつか例を挙げると、ミックスアップ、ラベルスムージング、プログレッシブ・リサイジング、重みの凍結と凍結解除)の実装が組み込まれており、驚くほど簡単に使うことができる。この決断と「コーダーのためのディープラーニング」の本を手に、私は自分のモデルを改良することに熱中した。
数時間以内に、私はFastAIで私のバニラ・パイプラインを複製し、モデルをデバッグするために必要な他のすべてのベルとホイッスルを統合した。新しいデータははるかに良くなり、わずか20エポックのトレーニングの後、5つのフォールドすべてで0.72-0.73の改善されたスコアが得られた

この2週間で試したことをまとめると、以下のようになる:
- ラベルスムージング(思ったほど効果がなかった)
- ミックスアップ(少なくとも私の場合は事態を悪化させた)
- プログレッシブ・リサイズ(最終的に使用したもの)
- テスト時間増強(役に立たなかった)
- 識別学習率(これも結局使った)

まだ取り上げていない点として、new_whaleクラスをどのように予測したかがある。今それをやってみよう。
new_whaleクラスのインスタンスをすべて削除したので、推論中にモデルはnew_whaleクラスを予測しません。それを予測に再導入するために、予測値のソフトマックス・スコアをガイドとして使いました。上位5つの予測とそのソフトマックススコアが与えられたら、これらのスコア(とその下に続くもの)のどれかが閾値を下回っているかどうかを調べます。もしそうであれば、新しいクジラのクラスは、閾値より低いスコアの直前の予測として導入されることになる。これはディスカッション・フォーラムで提案された戦略であり、私自身が考案したものではないことに注意してほしい最適な閾値を見つけるために、私は各フォールドについてグリッド検索を実行し、最終予測にその値を使用した。この2週間が終わるころには、20エポックのトレーニング後、384 x 384の解像度で、私のベストスコアは0.8だった。

8~9週目の取り組み

この最後の2週間は、より長い時間、モデルのサイズを224×224から512×512に徐々に変更していくことに集中した。これには多くの試行錯誤が必要で、最終的に私の場合、384 x 384で65エポックの実行を行い、その後512 x 512の解像度で微調整を行うのがベストなアプローチだった。これには多くの骨の折れるチェックポイントが必要だった。タイムアウトの問題なしに384 x 384で65エポックのモデルをトレーニングするためには、Colabで特定のタイプのGPUを手に入れる必要がありました。そのため、GPUによっては、トレーニングに必要なエポック数を選択し、そのモデルを失わないようにチェックポイントしなければならなかった。それから重みを復元し、残りのエポック数を訓練する。不便で面倒なのは分かっている。このプロセスを5つのフォールドすべてについて繰り返し、各フォールドを512×512で5エポックずつ微調整していけば、私が今いる場所にたどり着けるだろう。
このプロセスの最後に、私の最高のモデル(公開リーダーボードに基づく)は、上記のように5フォールド層別化CVで訓練されたResnet-34でした。私はこのモデルと、このモデルの最良のシングル・フォールドをコンテストに提出した。この時点で、私は疲れきっていたが、このチャレンジを最後までやり遂げたことに満足していた。

結果

最終的なリーダーボードでの仮の順位: 258/2120 → トップ12.16%、銅メダルを0.012ポイント差で逃す


(記事の筆者が)学んだこと

毎日コンスタントにわずかな時間を投資することで、それが複合的に作用し、ボードの上位に食い込んでいくのを目の当たりにして、私は感激した。このコンテストは、私が挑戦したときには終わっていたけれど、参加している間は、まだ競争心の高まりを感じていた。もっと違ったやり方があったと思うことはたくさんある:
毎週1日1時間ではなく、週7時間を自分の好きなように使えるようにすべきだった。クリエイティビティとモチベーションは爆発的に高まるもので、もっと長く続けたいのに、自分で決めたルールのせいで続けられない日が何日もあった。逆に、疲れ果てて競技に取り組む意欲がわかない日もあった。

データ処理の検証をもっと徹底すべきだった。そのために数時間のデバッグ時間がかかり、私の場合は非常に高くついた。これをもっと早くやっていれば、もっといろいろなことを試す時間があっただろうし、おそらくもっとスコアを伸ばすことができただろう。

FastAIのようなライブラリーは、プロトタイピングを桁違いに加速してくれるという意味で神の使いだ。しかし、その代償として、結果を最大化するためには、それらをよく学ぶために時間を投資する必要がある。

ゼロから書くコードの量をよく考えるべきだった。学習と高得点のトレードオフはやっかいで、1日1時間、ColabとKaggleのカーネルを使っていたことを考えると、コンテストに使うスクリプトの自己完結型リポジトリを作るという方向には進むべきではなかった

最後に、KaggleカーネルもGoogle Colabも、自分のワークステーションやクラウドのセットアップを持っていない膨大な人々に計算を自由に利用できるようにしている。しかし、これらが無料なのには理由がある。これらは実験や研究を奨励するためのものであり、IMOの競技用ではない。タイムアウトを起こさずにモデルをトレーニングし、結果を推測できるようにするのは、骨の折れる作業だった。さらに、大規模なモデル(EfficientNetなど)のトレーニングは、通常メモリに収まらず、1エポックか2エポックのトレーニングを行うために、画像解像度やバッチサイズのどちらかを弄らなければならないため、非常に困難だった。Kaggleで勝ちたいのであれば、これらのリソースを使えばいいのですが、それはあなたの気概と決断力次第です。私のように時間に余裕のない人にとっては、これは間違いなく凹む。


所感

全体的な感想

  • これだけ頑張って、銅メダルか・・・険しい道のりKaggle

  • 計算リソースの制約はやはりあるらしい。潤沢なGPUを持っていれば削減できる学習時間や試行できるパターンも増える

  • wandbで効率的な実験管理ができれば、限られた時間でも効果的に成果を残すことができる

  • 1日1時間でも、毎日続けることが重要

  • 自分がやった手順を残して再現性ある形で文書化している点が素晴らしいと思った

    • githubとの連携、手順をNotionに残すところ、wandbで実験管理という三種の神器

  • 新しい論文を読んだり複雑なモデルの実装に挑戦したりというフローは時間効率があまり良くない。既存のモデルで十分試して、時間が余ったらそういう新規性の高いことに時間を使う

手順についての感想

  • おおよその学習手順に理解が深まった

    • 最初から高解像度で学習させるのではなく、最小の解像度でいろいろなモデル、前処理を実行

    • ある程度方向性が定まってきたら解像度を大きくしていく

    • 前処理についても実際の画像を確認しながら進めていて

  • 少ないクラス数への対処

    • サンプル数が20以下のクラスに対しては、20となるように拡張させる

  • 画像分類に物体検知のモデルを利用

    • 背景を削除して学習させるという意図は理解しているが、背景削除の精度に関しては別途どうやって確認したのだろうか

  • 実際これを自分でやるときには、60分の取り組み時間+振り返り時間10分と言う感じになりそう。時間帯も習慣的に固定した方が良いかもしれない

気になったツール

  • FastAPIで実験管理のどこが効率化するのか自分で試してみたい

  • map@5に効果的なLossについて勉強したい

  • ディスカッションを読む時間と自分で戦略立てる時間実装する時間との割り振りをどうやっているのか知りたい




 参考文献


chatgptに聞いてみたシリーズ

fastaiをKaggleで生かすためにはどのような使用方法が考えられますか?

fastaiは、ディープラーニングのモデルを素早く簡単に構築できるPythonライブラリで、Kaggleコンペティションでの使用にも適しています。以下は、fastaiをKaggleで生かすための使用方法です。

1. プロトタイピング
速度: fastaiの高レベルAPIを使用すると、数行のコードでモデルを構築できるため、プロトタイピングが迅速に行えます。
事前学習済みモデル: fastaiには多くの事前学習済みモデルが組み込まれているため、すぐに実験を開始できます。

2. データ拡張
fastaiのデータ拡張機能を使用して、データセットを人工的に増やし、モデルの汎化能力を向上させることができます。

3. 転移学習
fastaiは転移学習を容易に行えるため、異なるドメインのデータで訓練されたモデルを特定のKaggleコンペティションに適応させることができます。

4. 学習率の調整
fastaiの学習率探索機能を使用して、最適な学習率を素早く見つけることができます。

5. カスタマイズ
必要に応じて、fastaiの低レベルAPIを使用して、カスタムモデルや学習ループを構築することができます。

6. 多様なタスクへの対応
fastaiは画像分類、テキスト分類、回帰など、多岐にわたるタスクに対応しているため、様々なKaggleコンペティションで使用できます。

7. コミュニティとリソース
fastaiの豊富なドキュメントと活発なコミュニティは、Kaggleコンペティションでの問題解決の支援となります。

このように、fastaiはKaggleコンペティションでの高速なプロトタイピング、データ拡張、転移学習、カスタマイズなど、多岐にわたる使用方法が考えられます。特に画像系の機械学習エンジニアとして、これらの機能を活用することで、効率的にコンペティションに取り組むことが可能です。




この記事が気に入ったらサポートをしてみませんか?