Kaggle画像コンペでやっていること①

データ分析コンペを始めたてな人の中には『**どこから手を付けていいのかわからない**』方もいらっしゃるのではないでしょうか。『**テーブルコンペは特徴量つくればいいけど、画像コンペって何するの？**』という声も聞いたことがあります。

ということで、kaggle advent calender 2024の8日目の記事は、**画像コンペで何しようか**というお話になります。数回にわけて書かせていただこうと思います。基本的に初級者(Expertぐらい)向けですのでご了承ください。

8日目：本記事
14日目：[Kaggle画像コンペでやっていること②](https://qiita.com/Kmat67916008/items/73e303451e3bc69e50bb)
21日目：[Kaggle画像コンペでやっていること③](https://qiita.com/Kmat67916008/items/6db4446698a58a6b3f0d)
24日目：[Kaggle画像コンペでやっていること④](https://qiita.com/Kmat67916008/items/d7586a28e6ec8595d579)

# 自己紹介
- **アカウント名: K_mat**
- **Competition Grandmaster** (動画像系や時系列センサデータ系が主)
- 元々、本業はメカニカルエンジニアで博士 :airplane:
- Kaggleおよび機械学習は2019年から5年
- Vision系NNが好みで、参加コンペも半数以上が動画像を扱うコンペです

<img width="190" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/cbc13ee7-b7c4-89c4-966b-723b82bf2e69.png"> <img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/0ece2859-31bb-3fc2-5873-d52fbdcaf800.png">
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/526a1643-25f3-e548-84b3-f83fa09aacc9.png">


# 画像コンペで何をするのか
簡潔に書くと二種類の試行錯誤をしています。
- いつもやること:rice:
- そのコンペだからやること:meat_on_bone:

|  |  |  |
|:-----------|------------:|:------------:|
| いつもやること | データを見なくてもできること | パラメータ調整・Ensembleなど |
| そのコンペだからやること | データの特性を意識した工夫 | 特徴量づくり・モデルアーキテクチャ検討など |

前者は非常にベーシックですが、一通りできることが上位を狙うためには必須なのではないかと思います。後者はコンペ次第ではありますが、上位からさらに差別化して抜け出すためには、そのデータのドメインを考えることが重要になってきます。

以下、まずは『いつもやること』について、**あくまで私のケース**ですが、最低限このぐらいは見るという内容を書き下します。

# いつもやること
## 例えばどんなことをするか？
以下のようなものはざっと確認していると思います。
- **データを見る**
- バリデーションの切り方を考える
- **解像度**を変えてみる
- 数値を0-1範囲にノーマライズしてみる。Logスケールとってみる
- Dropoutなどregularizationを追加してみる
- OptimizerやLossをちょっと変えてみる
- 学習epochを長くしてみる/短くしてみる
- **Augmentation**を色々試してみる
- Modelやハイパラを変えてみる (conv-transformer, deep-shallow, gap-gmpなど)
- サブタスクを学習させる (補助ロス。後の記事で紹介予定)
- metricを最大化するための閾値調整をおこなう(必要な場合のみ)
- **Ensemble** してみる
- pseudo label, domain adaptationしてみる
- 外部データをさがしにいってみる
- ラベル付け・差し換えを考える

初心者向けに基本的なところを少しだけ補足します。

#### 補足：データを見る
当たり前ですが、ちゃんとデータは見ます。悲しいことに結構サボる人も多いかもしれませんが、いろんなシーンで重要になります。
- 初めてすぐ。戦略を練るとき
- モデル構築前にデータの傾向を見るとき
- Augmentationガンガンに入れてみたとき
- 推論結果をもとにエラー分析するとき

最初は『なんかラベルがノイジーだなぁ』とか『物体でかいな、アス比すごいな』とか『こんなん予測できんのか』とか比較的抽象的なところから方針を練るぐらいかもしれません。細かい調整や工夫のフェーズになると、『このデータのこの予測は〇〇を工夫すれば対処できそう』とか細かい視点になると思います。

下図は[崩し字コンペ](https://www.kaggle.com/competitions/kuzushiji-recognition)のlog(文字サイズ)の分布ですが、こういうのを見るだけでも
> 文字サイズ分布の広さに対策を打とうかな。この異常に大きいのはラベルミスだったりしないかな。

とか、いろんな視点が生まれます。
![0_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/d4b5e3f8-6e20-e921-50a6-a9850519abb2.png)![0_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/61ed4b6e-ef48-250a-7732-0e6090b1ec06.png)


#### 補足：解像度について【対象が小さい場合】
解像度は性能に与える影響がまぁまぁ大きく、初心者にとっては最初に意識すべきところではないでしょうか。いつもやるとはいえ、問題に合わせて変えていくところでもあります。~~個人的な思いとして、怪しいAI系業者は解像度の気持ちがわかっていません。~~

たとえば画像全体からめちゃくちゃ小さいものを見つけたいときは、むやみに解像度を落とせません。(例：下図からボールを見つけたい)
しかし一方で、限られた時間でコンペをやるためには実験効率も重要ですので、序盤から過度に高い解像度は避けたいところです。また、限られた推論時間で実行するコードコンペでは、実行速度もある程度意識したいところです。

たとえばこの例であれば、モノが小さいしコンテクストはそれほど重要ではなさそうなので浅いモデルでさばこうかな、という選択肢がでてきます。こういったトレードオフを意識しつつ戦略を練るのもコンペの醍醐味の一つですね！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/4bf6fe16-6c34-f272-f398-68c22916f553.png" width=70%>DFLコンペより

#### 補足：解像度について【対象が大きい場合】
逆に対象物が大きい時には画像全体を見渡せるような解像度とモデルが必要になると思います。たとえば、1024x1024のような大きい入力画像を軽量な浅いモデルで処理する場合は、本当に画像全体が見えているのかどうかが考えどころです。
解像度をさげるか、モデルを大きくする選択肢を持ちたいところです。

有名なEfficientNet論文でもそのあたりの重要性が主張されました。[EfficientNetってもう5年前(2019)](https://arxiv.org/abs/1905.11946)なんですね。


#### 補足：ベーシックなAugmentation
NNは数値で覚えたり場所で覚えたりを簡単にできてしまうので、特に問題なければ以下の①、②のジャンルのAugmentationは入れるようにしています。
- ① 数値自体を変化させる、色いじり系Augmentation
  - random brightness/contrast
  - random hue
- ② 場所を変化させる、空間系Augmentation
  - random flip
  - random crop
  - random scale
  - random shift, shear, rotate

あとは強い正則化系のaugmentationを可能なら入れたいですね。このあたりは、パラメータ調整が難しいことに加えて、学習ステップにあわせてaugmentationを緩めたりなど、効かせ方も難しいアイテムになります。
- ③ なんか強い正則化系
  - Cutout/Course Dropout, mixup, cutmixなど

ちなみに[cutmixももう5年前(2019)の技術](https://arxiv.org/abs/1905.04899)です。ちょっとショックでした…。

![0_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/8a8e2ca1-56eb-97a6-82a5-ad2a23bc6a0f.png)(図は論文より)

#### 補足：Ensemble
コードコンペで実行時間制約ができたとはいえ、複数モデル混ぜ混ぜは精度アップの常套手段です。実施しない手はありません。
- なんだかんだでシンプルなアベレージングでも十分戦えます
- 画像中の物体検出や時間方向のイベント検出では、**Weighted Box Fusion**風(WBF)のensembleが便利です

WBFはご存じkaggleコンペで使われだしたensembleテクニックです。[arxiv](https://arxiv.org/abs/1910.13302)
複数の予測がオーバーラップしているときに、どれを残すのかを考えるNMSとは異なり、それらの確信度に対する重み付き和として予測結果を残すensembleテクニックになります。

考え方としてはイベント検出などでも使用可能です。例えば起床時間を予測するコンペでは、時間とともに確信度を予測させるとします。確信度0.3で9時起床と出したモデルAと、確信度0.6で10時起床と出したモデルBを混ぜることで、9時40分起床とすることができます。
(異なるモデルの確信度を対等に扱う気持ち悪さはありますが)

![0_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557686/8f25e5f2-6dc1-fdf6-f04b-054da986a377.png)(図は論文より)

ちなみに[WBFももう5年前(2019)](https://arxiv.org/abs/1910.13302)

## いつ実施するのか？
- 序盤に軽く実施。あたりを付ける程度
- 何もひらめかない中盤の空き時間に実施
- 終盤にしっかり調整して最終サブにもっていく

『いつもやること』は、序盤の粗調整と終盤の最終調整、そして何も考えられないときのGPU暖房となるケースが多いと思います:sunny:

まだあまりコンペやNNの経験がない方は、序盤から終盤までされることもあると思います。肌感覚を掴む意味で決して悪いことではないと思います。(毎回それだとあまり好ましくないですけど)

## 効果はあるか？
- コンペにもよるが、しっかりできれば銀圏を取れる印象:medal:
- やって勝てるのか、ではなく、やって当たり前なものが多い
  - とはいえ、これだけで勝ち負けが決まるような辛い戦いのコンペもある
  - 簡単に見えるけれど非常に難しく、謎の勘所が多い。上位勢もたまに最適な調整ができないまま終わると思う
- 調整系は、やればやるほど局所最適に落ちるので覚悟が必要
  - 絶妙なパラメータ調整の後の工夫は何をやっても精度が伸び悩む。ドツボにハマる
  - 「え、ウチのチームはそれ効かなかったけど、どういうこと？」になりがち

# まとめ
ということで今回はどのコンペでもとりあえずやることをいくつか紹介しました。
いずれも基本的なことですが、経験的なノウハウも多く、思いのほか難しかったり差がついたりします。ここらへんのことをササっと一通りできる皆様は既に金圏レディではないでしょうか！:medal:

ということで、**次回以降は『そのコンペだからやること』について紹介予定**です。もっとドメイン スペシフィックなコンペ固有の工夫でロマン砲を狙いましょう！


# 参考
- EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks: https://arxiv.org/abs/1905.11946
- CutMix: https://arxiv.org/abs/1905.04899
- Weighted Box Fusion: https://arxiv.org/abs/1910.13302
- Kaggle Kuzushiji Recognition: https://www.kaggle.com/competitions/kuzushiji-recognition
- Kaggle DFL: https://www.kaggle.com/competitions/dfl-bundesliga-data-shootout