Kaggleで初心者5人チームのリーダーとして参加した時の話


# 0. はじめに
皆さんがKaggleに初参戦したときのことを思い出してください。
恐らくは, 個人で始められた方が多いのではないでしょうか？

私も長らくその一人でした。
しかし, ある日Twitterで相互フォローしていたとある方から

![513E9490-2E40-4873-9E7E-07B0B0CAF772.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/0a383866-1dc9-573a-3348-d6fe162355a0.jpeg)

という@ツイートが届いたことで事態は一変します(※ツイートは改変しています)。

その2日後には, 初心者だらけの5人チームで[RSNA Intracranial Hemorrhage Detection](https://www.kaggle.com/c/rsna-intracranial-hemorrhage-detection) というKaggleコンペ(通称: 脳出血コンペ)にチーム参加することとなりました。

私自身もKaggle歴6ヶ月の初心者ですが, いきなり人生初のチーム戦を, チームリーダーとして戦うことになったわけです。

右も左もわからないままもがき続けましたが, 何とかPrivate Leaderboard 1345チーム中339位 (上位25%) という成績を収めることができました。
初めてのチーム戦にしてはまずまずではないでしょうか？

<img width="933" alt="E5E88651-014F-44AE-9201-C7C39A51E52C.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/b862b80f-bf75-1d7e-86b7-2a15caa6d78e.jpeg">


そこで本記事では, 「チーム戦の戦い方」という観点から, 人生初のKaggleチームリーダーとしてやってみた工夫について書いていきたいと思います。

※本記事では解法についての話はしません。

# 1. どのようなチームだったか？


一言でいうと「**全員がKaggleへの参加が全く初めてか, あるいは数回しかないチーム**」です。
また, 他には以下のような特徴がありました。

- 社会人2名(私含む), 大学生3名
- 互いに顔を知っているのは一部のみ, ほとんどはオンラインで初対面
- 機械学習やコーディングのレベル感に差がある
    - A(私): Kaggle参加歴数回, 自然言語処理の研究をしているが画像処理は初めて, Google Colabに不慣れ
    - B: Kaggle参加歴数回, 医用画像の研究をしている
    - C: Kaggleは初めて, 医用画像の研究をしている
    - D: Signate参加歴あり, Kaggleは初めて, GitHubを使うのは初めて
    - E: [ゼロから作るDeep Learning](https://www.oreilly.co.jp/books/9784873117584/)をこれから始めようと思っている

つまりは全員がほぼ初心者で, かつ, その中でも互いのレベル感がかなり異なっているというチームでした。

このようなチーム構成であるため, 早い段階でチームリーダーの目標を**コンペで勝ちを狙いに行くことよりは, 全員がそれぞれ何かしらの収穫を得られるような環境をつくること**に据えることにしました。

# 2. チーム戦を戦うためにしたこと
### 2-1. 心理的安全性を確保する
#### 2-1-1. SlackにParty Parrotを入れる

チーム参加のお誘いがあってから数時間後にSlack Workspaceを作りました。
SlackのWorkspaceを作ってまず初めてにすることといえば, ズバリ,

![parrot.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/9ec2d902-eed9-52a3-d197-ee5a8c5db3d5.gif)

これですこれ!
カラフルなこやつをカスタム絵文字として使えるようにすることですね。

Slackのpostにゆるく楽しくレスポンスするのにうってつけの**Party Parrot**は, 最初から追加すると心に決めていました。
Slackにデフォルトで入れておいて欲しいくらいですね。

最初は, 有志によって提供されているカスタム絵文字の一括追加用ライブラリを試しましたが, うまくいかなかったため, [Cult of the Party Parrot](https://cultofthepartyparrot.com/)からzip形式で絵文字を一括ダウンロードして1個1個手動で追加していきました。

#### 2-1-2. レスポンスを早くする

コンペ全体を通じて, チームメンバーの積極的な発言を歓迎するスタンスをとりました。
これを実現するために, postへのなるべく早い返信を心掛けるのはもちろんですが,

- **チームメンバーからのpostの通知が届いたら, 数秒〜数分以内に絵文字をつける**

ようにしていました。
これによって, 

- すぐ返信可能なpostにはすぐ返信する
- 返信に時間がかかる内容のpostでも, 最低限絵文字での反応はある

という状態を作るようにしました。

**せっかくチームの役に立とうとして何か投稿したのに, 絵文字が1個もついていないというのは一番寂しい**ですからね...メンバーをそういった気持ちにさせるのを極力避けるのが狙いです(出来ていない日もありましたが)。

#### 2-1-3. "皆さん" と声掛けする
こちらからチームメンバーの皆さんに作業や情報提供を依頼する際には, 必ず "皆さん" に話し掛けるようにしていました。
たとえその作業や情報提供をできそうなのは誰であるかが, 最初からほぼ分かりきっているような状況だとしても, これは徹底するよう心掛けました。

理由は, チーム内での機械学習の経験の差が大きかったことにあります。
**チームへの貢献の窓口を全員に対してオープンにしておく**ことで, 萎縮したりドロップアウトしたりする人がなるべく生じないようにするのが狙いでした。


### 2-2. 情報共有

情報共有は基本的にSlackで完結できます。
コンペが進むにつれて, 適宜チャンネルを追加していく形で情報共有の幅を広げていきました。

また, これは心理的安全性とも通じる部分がありますが, メンバー間で得意不得意が微妙に異なっていたため, これを利用してそれぞれのメンバーに異なるチャンネルで話題を定期的に振っていくことでなるべく全員が何かしらの形でチームに貢献できているような状態をつくるよう心掛けました。

<img width="263" alt="42927D21-DE7E-4F2E-A88A-DCED01B204C3.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/9064c63e-82d5-c313-8d2a-6d8031fa45d5.jpeg">

また, 私は画像処理の知識は乏しいですが, Kaggle参加歴はおそらくチーム内で最多であったため, Kaggleのルールや仕様についての情報共有も積極的に行っていきました。

Kaggleは機械学習とは本質的に関係ない落とし穴がやたらと多く, **同じ見た目なのにときどき違う動作をして学習を強制的にストップさせてしまうボタン**などがあったりします...。

<img width="746" alt="3EE351FF-787C-47A0-B5A8-1BF31033D48A.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/7dfef887-401c-4e44-af59-7761d6aa6d22.jpeg">

### 2-3. コードの共有
おそらくGitHubのプライベートリポジトリを使うことが一般的だとは思います。
が, 今回はメンバーの5人中2人がGitHub未経験であったこともあり, コードの管理にGitHubは使わない方針としました。

最終的には, Kaggle Notebookのバージョン管理機能を駆使することと, `#lost_and_found`というチャンネルを作ってNotebookのありかをひたすら最新情報に更新しつづけるという力技で切り抜けました。

<img width="745" alt="B42BE422-4EE4-4755-8541-85B452758825.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/e1f37679-8d02-085e-592f-def212add76b.jpeg">

そう, 今回のチーム戦ではほぼすべての実験をKaggle Notebook上で行っていたのです。

Kaggle Notebookは手軽に使えて便利ですが, **資源の制約ルールが以下のようにかなり厳しい**という欠点があります:

- 同時に使ってよいGPU搭載カーネルは1個(interactive), もしくは2個(commit)まで
- GPU使用時間は1人あたり週に30時間まで

私達もこの欠点は自覚しており, 実際に何度も使用時間オーバーでGPUが使えなくなったため, Google Colaboratoryに移行したり, ローカル環境で学習したりすることをずっと考慮していました。

しかし,
 
- Google Colaboratoryでは環境の違いに悩まされた(これまでに書いてきたKaggle Notebookコードが動かなかった)
- ローカルで扱おうにも, 本コンペの学習用データは150GB(!!!)という超巨大なデータであり, ダウンロードを完了させることすら一苦労で, 現状のチームの技術力では困難と考えられた

という2つの理由で, 結局は最後までKaggle Notebookの限られた資源で戦うこととなりました。
このあたりは技術面での大きな課題ですね。






### 2-4. 通知機能の活用
途中から, **学習の経過をリアルタイムで通知する機能**を導入しました。

導入はわりとすんなり出来ました。
Slackに通知を飛ばしたければ, [Incoming-webhook](https://api.slack.com/messaging/webhooks)というAPIが提供されているため, このAPIキーを取得しておいてNotebookの好きな箇所に所定のコードを挟むだけでできます。

これで, 学習の進行状況や, 何らかのトラブルによって学習が途中でストップした際にも早い段階で気づくことができるようになりました。
<img width="749" alt="62FFE26F-0E07-409F-9652-9652A3E61782.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/f56481bd-af2c-f95a-6710-b779c7ef1364.jpeg">

なお, Slackの他にも[LINEに通知を飛ばせるAPI](https://developers.line.biz/ja/services/messaging-api/)が有名です。

### 2-5. 学習にかかった時間を計測する
Kaggleでは学習から推論までの全工程を一定時間内に収めなければならない場面がよくあります(特に, ルール上Kaggle Notebookを必ず使用するように指定されているコンペに顕著)。

とはいえ, できるならば長い時間をとったほうが何かと有利になることが多いものです。
このため, 制限時間を逸脱しない範囲で極力長い時間学習を回すためにepoch数などのハイパーパラメーターを調整していく場面が出てきたりします。

このとき, **前処理, 学習, 推論などのそれぞれの工程でどのくらい時間が掛かっているのか**が分からなければ, epoch数を調整する検討がつきません。

そこでコンペの終盤では, 上記の通知機能に絡めて, 各工程の所要時間を逐一計測するようにしました。

### 2-6. すべてを保存する
Kaggleに限った話ではありませんが, 機械学習では「夜に回した計算が, 朝起きたら大量のエラーを吐きながら止まっている」ようなことが頻繁に起きます。
コンペの前半ではそうした手戻りが大量に発生し, やたらと無駄足を踏んでしまいました。

後半では反省点を活かし, 各checkpointごとにモデルの`state_dict`や学習のログを逐一保存させるようにコードを改良することで, **万が一途中で学習がストップしても続きから再開できるような状態**をつくりました。

<img width="746" alt="7D457424-8E27-47EB-A86D-0B8D69E1CB84.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254846/49846a0a-b44c-2f85-4ebe-62d37f303ede.jpeg">


# 3. 最後に
いかがだったでしょうか？
一部はチーム戦やKaggleとそれほど関係のない項目もありましたが, 初心者の方がチームを組んで参加する際に少しでも参考になれば幸いです。

最後に, [Kaggle-ja Slack](https://kaggler-ja.herokuapp.com/)で教えていただいた資料(
[Kaggle Tokyo Meetup 裏 #01 固定チームでKaggle参戦記録](https://speakerdeck.com/j20232/kaggle-tokyo-meetup-li-number-01-way-to-border-collies-feat-jtc))が大いに参考になったため, ここでご紹介させていただき, 本記事を終わりたいと思います。