Kaggleの画像コンペでかっこよく勝ちたい話

Kaggleでコンペに参加されている方の中には、
- メダルが欲しい！
- 上位になりたい！
- 賞金が欲しい！

など、様々なモチベーションで**勝つこと**を目標にしている方も多いのではないかと思います。もちろん勉強やコミュニケーションなどの側面もありますが、競い合う楽しさというのはデータ分析コンペの醍醐味の1つです。

私自身もそういう楽しさにハマってしまった者の1人のですが、さらなるロマンを求め、**あわよくばカッコよく勝ちたい**という気持ちで取り組んできました。狙いがガチッとはまったコンペもあれば、箸にも棒にもかからなかったものもありました。本記事ではそんな私がKaggleでかっこよくかちたくて、あれこれ頑張った話を紹介いたします。

『ぼくの考えた最強のソリューション』がたくさん出てくるポエムですので、そういったものが苦手な方はここで引き返してください。

本記事は[Kaggle advent calendar 2013](https://qiita.com/advent-calendar/2023/kaggle)の24日目の記事です。

## あのころはただの勝ちたいマンだった・・・

[コンペや機械学習をはじめて１年がたったころ](https://qiita.com/Kmat67916008/items/3fbead37b95e4c9506c2 "expert10kagetu")は、そろそろなにかしらのコンペに入賞できるんじゃないかと思っていました (過信していました)。
個人的な興味から画像コンペに好んで参加していました。2019年前後は今よりもシンプルなコンペも多く、画像系では分類や検出、セグメンテーションなどが多かった印象です。当時は**苛烈なimagenet sota争いの時勢を受け、コンペにおいてもいち早く最新技術を取り込もうとする動きもよく見られました**。私自身もEfficient Netのようなモデル、CutMixなどのAugmentation、ほかには検出器やLoss、Optimizerなんかも細かく実装して試行錯誤していました。「このモデルがいいらしい」と聞けばすぐに飛びついていました。

実際にそういったものも有効で、小さなコンペではそれなりに手応えを感じていました。崩し字コンペや、Signateのコンペで、新しいモデルを実装してみては程よい順位をとれるようになりつつありました。
多少のドメイン特性の活用や特徴量づくりなんかも手慣れてきて、「**僕も色々わかってきたもんだな、きっとこの延長として賞金圏にたどり着くだろう**」と、その頃は調子をこいていました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/b0677c7c-7d42-6cb3-4f22-cb1c18d02eda.jpeg" width=30%>


## 勝ちたいマンが、かっこよく勝ちたいマンになった日

きっかけは、みんな大好きベンガル語コンペでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/84bffe86-a6e2-d927-af4a-03e96361c215.png" width=70%>


#### コンペ概要：
ベンガル語の文字は部首のような複数の構成要素からなり、それらの組み合わせによって多数の文字があります。コンペでは**手書き文字を分類する**ことが求められますが、**テストデータには訓練データには存在しない構成要素の組み合わせがあり、これにうまく対応することがポイントの一つでした。**

#### 当時の僕 (脳内だけで参加)：
参加もせずに脳内Kaggleをして脳内で銀圏ぐらいにいました。

> - マルチラベル x マルチクラスのコンペか。
> - モデルは最後に分岐させるぐらいで、アテンションレイヤみたいなものを付けてもいいか。
> - 手書きなので、強めのAugmentationでがんばる感じだろうか。
> - 部首が隠れるようなAugmentationをすれば、見たことない組み合わせの文字がきてもいけるんじゃないかな。

という程度でした。「終了したし、一応ソリューションみとくか」てなもんです。


#### そこにやってきた 1st Place Solution

https://www.kaggle.com/c/bengaliai-cv19/discussion/135984

**Cycle GANで訓練データに存在しなかった手書き文字をつくる、どエレガントな解法**でした。
ちまちました工夫で調子にのっていた私にとっては非常に新鮮なソリューションでした。そもそもこれまではターゲットを直接導くようなモデルばかり考えていたので、メインの学習のためにサブのモデルを準備している時点で極めてオシャレです。
**今まで考えていた延長線にこの格好いい解法はなく、参加してもいなかったのに負けた気分でした**。できる気がしないというのは相当に格下です。「悔しい！私もどうにかしてかっこいいソリューションを書くぞ！」と決意しました。

----

以降、かっこよく勝ちたいためにあれこれ試した6コンペと得られた学びを紹介します。

----

## かっこよく勝ちたかったコンペ① (未遂)：Kaggle キャッサバ
データを作るのはめちゃくちゃ優れた差別化だなと思い、とりあえず**GAN Augmentation**を使いたくなっていた私は、**Kaggle キャッサバコンペ**に手を出します。


#### コンペ概要：
キャッサバの状態(病気の種類・正常)を画像から予測するコンペ

#### かっこつけようとしたこと：
病気の葉を正常の葉から作ろうとした。病気データマシマシでウマウマだと思った。増やしたデータで学習すればいいところいくんじゃないかと。
[Notebook公開済](https://www.kaggle.com/code/kmat2019/cycle-gan-to-enlarge-training-data)
![cassava.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/18e65d9a-78e1-0396-a095-a9c1074e75df.png)


#### 失敗した理由：
悔しいことに、見た目の割に案外効かなかった。
結局、**既にあるデータからつくるだけでは、訓練データ以上の情報は得られない**ので、やるのであれば**訓練データの外の常識をうまく巻き込まないといけない**。ベンガル文字コンペでは訓練データにはない『フォント』を使っていた。

#### かっこよさ (自己評価)：30点
生成画像アプローチはまぁまぁかっこいいし視覚的にも楽しいものの、ベンガル優勝解法の二番煎じ。かっこよさ不足が否めない。

## かっこよく勝ちたかったコンペ② (未遂)：Signate スバル
RGBだけじゃなくて**デプス(奥行き)がわかるとすごいお得**ぢゃん！情報4/3倍ぢゃん！と、デプス生成ブームだった私は、[**Signateスバルコンペ**](https://signate.jp/competitions/563)に食いつきます。


#### コンペ概要：
ステレオ画像と視差画像、自社速度情報から、先行車の速度を予測するコンペ

![subaru.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/f5d041a9-22d8-f3ed-4796-fa5f5022c040.png)

#### かっこつけようとしたこと：
**ステレオ画像からオプティカルフロー(RAFT)を自己教師あり学習する**ことで、深層学習ベースの視差画像を獲得し、より精度の高い先行車位置推定をおこなおうとした。SMURF(https://arxiv.org/abs/2105.07014) の実装に近いことをした。

#### 失敗した理由：
視差画像は既に提供されていたことが敗因。悔しいことにそちらの方が精度が高く、自作視差画像はあまり寄与しなかった。**予測に用いたステレオ画像の解像度が提供時点で既に小さくされてしまっていた**ことが原因かと思われる。なんだかんだで「デプス生成したいからした」というシーズベース(not目的ドリブン)なアプローチはよくなかったかもしれない。

とはいえ、デプス推定やオプティカルフローなどは動画の常識をほんのり学習できているので、とりあえず試すという意味では全然ありだと思う。(私個人はこれ以降のコンペでもよく試しています)

#### かっこよさ (自己評価)：50点
自己教師あり×深層学習での視差推定は芸術点が高いが、アプローチとしては想像がつくし月並みだった。

## かっこよく勝ちたかったコンペ③ (未遂)：Kaggle サンゴ礁
**NeRF**すげぇ！**2D動画から3次元つくれたら**動画コンペで最強ぢゃん！そう思っていた私の目を引いたのは**Kaggle GreatBarrierReefコンペ**でした。

#### コンペ概要：
[動画にうつるサンゴ礁を矩形検出するコンペ。](https://www.kaggle.com/c/tensorflow-great-barrier-reef)

#### かっこつけようとしたこと：
NeRFで**視点を変えてデータマシマシ**してやろうと思った。(下図はNeRF生成画像)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/97e11bdf-0897-44be-4a7d-8546a5776f35.gif" width=70%>

#### 失敗した理由：
そもそも**参加登録していなかった**。(忙しかった…)

#### かっこよさ (自己評価)：60点
まだKaggleでNeRFを使ったソリューションはなさそうなので結構カッコいい。これを使って勝てていれば70点越えだった。

いつかNeRFで1st place solution書くぞと思っていたけど、かれこれ数年たってしまった。今でも**NeuralField系はおすすめテクなので、誰かかっこよく優勝してほしい。**

## かっこよく勝ちたかったコンペ④ (成功)：Kaggle NFL2022
[自己教師有り単眼デプス推定ブーム?だった](https://qiita.com/Kmat67916008/items/267a3d3a6ac7c3512382)私は、NNのモデルの中にロジカルな意図を組み込んでみたくなっていました。そんな折、マルチモーダルのNFLコンペがやってきました。

#### コンペ概要：
**NFLの動画からどのプレイヤがどこにいるかをヘルメット位置で見つける**コンペ。動画とセットでプレイヤの位置や動き、チームやポジションなどの情報が与えられる。
まとめ記事は[こちら](https://qiita.com/Kmat67916008/items/8ccf0171219036621540)

#### かっこつけようとしたこと：
**画像からマップ上のプレイヤ位置(実座標)を推論するモデル**を組み込んだ。カメラの仰角やプレイヤの姿勢を暗に推定するモデル。下図の①~②の部分を深層学習でゴリ押しする。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/b2560e2d-fa49-b64a-050f-9e0fdc0e9c3f.png" width=80%>

#### うまくいった理由：
上述した単眼デプス推定モデルもそうであるが、NNは**制約(意図)を組み込むと案外うまくいく**ことが多いと思う。多少無茶な学習をさせても安定しやすくなる。このコンペ以降、モデルの学習に指向性を持たせるのが好きになった。

#### かっこよさ (自己評価)：80点
Lossの演算途中で[**Point Set Registration**](https://en.wikipedia.org/wiki/Point-set_registration)が出てきて動的にロスが変化するところが芸術点がかなり高い。ヘルメットのアテンションを効かせながらプレイヤ位置を推論させているあたりも、地味に匠の技感があるなと思った。

何言ってるかわからないけれど、当時はとても自己満足していた。


## かっこよく勝ちたかったコンペ⑤ (成功)：Kaggle DFL
**ビデオはその連続性ゆえにすごい情報量が眠っていてかっこよくなりたい放題**だということに気づき、またしてもビデオコンペに参加。[DFLのサッカーコンペ](https://www.kaggle.com/competitions/dfl-bundesliga-data-shootout/discussion?sort=votes)。

#### コンペ概要：
サッカーのプレイ動画から、パス・チャレンジ・スローインのイベントを検出する。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/4bf6fe16-6c34-f272-f398-68c22916f553.png" width=80%>

#### かっこつけようとしたこと：
イベント判定の補助として、ボールをどうしても正確に検出したくて、複数フレームを用いた推論を実施した。その際に**自己教師あり学習をしたオプティカルフローによって、カメラ(画像全体)の動きと人や物体の動きを切り分けることを前処理的におこない**、精度向上を果たした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/d34270c9-12f8-c3f8-5deb-5acf545ac002.png" width=90%>

#### うまくいった理由：
動画を用いたタスクでは、複数フレームを入力として検出やイベント判定をおこなうことは一般的におこなわれている。その際に、**果たして事前のフロー推定を活用する必要があるか？普通のカラー画像だけ複数フレームいれてやれば情報量としては変わらないのではないか？** と、いつも疑問に感じる。

今もあまり自信はないけれど、上述したような**カメラモーションと物体モーションの切り分けを用いることで、NNモデルにとって親切で学習しやすくなる**ことは少なくなさそうだなと思う。本件はもちろん、[過去のNFL Impact Detectionコンペ](https://www.kaggle.com/competitions/nfl-impact-detection/discussion?sort=votes)においてもオプティカルフローの活用は見られた。

#### かっこよさ (自己評価)：60点
Optical Flowを活用した検出自体はやや一般的であるものの、解像度調整によってグローバルモーションだけを高速で抽出できるような工夫をおこなった点は評価できる。

一方で、上位のh2oチームやcamaroさんはもっとシンプルで強い手法だったのでちょっと格好悪いなと感じた。そもそもイベント検出のためのボール検出のための自己教師ありオプティカルフローとかやりすぎ。複雑な技巧がかっこいいわけではなく、ストレートに度肝を抜きにいくソリューションを目指したいと思った。

## かっこよく勝ちたかったコンペ⑥ (成功)：Kaggle NFL2023
最近のコンペでのモデル構成は複雑すぎるし、独りよがりでホストフレンドリーではなかったことを反省していた。**シンプルで強力なソリューション**への憧れもあり、もう一度[NFLのマルチモーダルビデオコンペ](https://www.kaggle.com/competitions/nfl-player-contact-detection)に参加。チーム参加。

#### コンペ概要：
NFL動画から、『プレイヤ～プレイヤ間』、もしくは、『プレイヤ～地面間』の接触有無を判定する。
![inbox_644036_65cd663d2c823043b36ecda6c93c1304_contact-example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/cf9272fa-3344-49e6-f0bd-2c5200e78a61.gif)


#### かっこつけようとしたこと：
- [うまくいった方]　プレイヤ同士の**ROIの交差領域からコンタクトは発生するはずという意図**をくんだモデリングにより、接触有無のみならず、ビジブルに接触部位が見えるモデルをつくった。弱教師あり学習のようなアプローチ。[解法はこちら](https://www.kaggle.com/competitions/nfl-player-contact-detection/discussion/391719)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/4f638389-e530-8727-21d8-cf3ceeb0aca5.jpeg" width=70%>

- [うまくいかなかった方]　センサ値からプレイヤの存在領域を予測するような2D occupancy fieldもトライしたがそれほどうまくいかず。occupancyしてみたかった。

#### うまくいった理由：
上でも述べたが、NNは**制約(意図)を組み込むと案外うまくいく**ことが多いと思う。プレイヤ間の交差領域にコンタクトは存在するという縛りは、その領域からのロスという形でモデルが非常に解釈・学習しやすくなった。

#### かっこよさ (自己評価)：50点
狙い通りシンプルで解釈しやすく映えるモデルができたが、そこまで精度が高かったとも言い切れずその点のダサさは否めない。prizeは完全にチームメンバのおかげでした。


----


## さいごに
ここまでつらつらと私のチャレンジを書き綴りました。ベンガルコンペ以降、私の中でのカッコいい解法は、自己教師あり学習やデータ拡張を活用して他の参加者には見えていないものを学習させたり、NNの中にドメインやタスク特有のロジカルな仕組みを組み込むところにあったのかなと思います。

いざやってみると…

〇　勝つためにKaggle以外の勉強ができる (論文とか)
〇　勝つと他の人に自慢しやすい
△　負けるとただ奇をてらった残念ソリューションになる
△　負けるとアプローチが悪かったのかモデリングが悪かったのかさっぱりわからない
△　成長が目に見えにくい (なんだかんだで金まで3年)

など、良い面もつらい面もありました。

今回紹介したもの以外も色々トライしましたが、**基本的には自己満足**だと思います。結果はともなわなくとも、**面白い学習が意図通りに回ったりするだけでも案外達成感はあります**。

自慢のソリューションを見た他の参加者の中には「それ思いついたけどやらなかった」とか「そんなのでいいのか」とか言うこともあります。ですが、実際にトライして成功(失敗)させるのは、やってないことよりも段違いにかっこいいことだと思います。

長々と書きましたが、最後まで読んでいただきありがとうございました。
みなさんの自慢の解法を私もたのしみにしています！