【Kaggle】CSIRO 上位解法振り返り
本記事は下記について記載しています
- Kaggle コンペ(CSIRO - Image2Biomass Prediction)の概要
- 上位解法解説(1 位〜 3 位)
1. はじめに
最近,Kaggle の CSIRO コンペに参加しました.
ちゃんとしたコンペは 2 回目の挑戦でしたが,前回に引き続き今回も撃沈でした.
なので本記事では公開された上位解法(3 位まで!)を解説してみました!
※ 上位の方の投稿ソリューションを参考にしているため,多少の記載の揺らぎはお許しください.
2. コンペ概要
まずコンペ概要です.
今回参加したコンペは下記の CSIRO コンペです.
タスク概要
- 草の画像やメタ情報などから,5 つの指標の草の量(牧草バイオマス)を予測するコンペ
- データはオーストラリアの各州で収集されている
目的
- 農家の放牧判定・研究者の牧草地研究・農業を持続可能性と生産性のサポート
- 従来手法では時間や信頼性などの観点から課題がある
評価指標
-
Dry_Green_g: 0.1 -
Dry_Dead_g: 0.1 -
Dry_Clover_g: 0.1 -
GDM_g: 0.2 -
Dry_Total_g: 0.5
上記の重みで $R^2$ を算出する.
\begin{align}
R^2_w &= 1 - \frac{\sum_j w_j (y_j - \hat{y}_j)^2}{\sum_j w_j (y_j - \bar{y}_w)^2} \\
where: \bar{y}_w &= \frac{\sum_j w_j y_j}{\sum_j w_j}
\end{align}
この指標では,各ターゲットごとに $R^2$ を算出するのではなく,全サンプルをまとめた上で上記の重みで $R^2_w$ を算出します.
そのため,最も重みの大きい Total の精度がスコアに大きく影響するような構造になっています.
バイオマス
| 種類 | 説明 |
|---|---|
| Dry_Green | 乾燥した緑の植物(クローバー除く) |
| Dry_Dead | 乾燥した枯れた植物 |
| Dry_Clover | 乾燥したクローバー |
| GDM | GDM = Dry_Green + Dry_Clover |
| Dry_Total | 乾燥した植物の総量 Dry_Total ≈ Green + Dead + Clover |
一見すると画像回帰のシンプルなタスクに見えますが,
評価指標やデータの性質に結構癖があり,
個人的にはかなり難しいコンペでした.
3. 自分の解法
まず私がやったことを紹介します.
モデル
- ConvNext
- SwintTransformer
- それぞれの特徴を抽出し,attention でまぜまぜ
- State などの情報も埋め込む
入力・訓練
- Sampling Date で Fold(Fold = 5)
- 左右分割し,768x768 にリサイズ
- 訓練データオーグメンテーション
- Flip / Rotate
- コントラスト
- ガウシアンノイズ
- ぼかし
- 画像圧縮
- EMA
出力・推論
- ターゲット 5 個を直接予測
- TTA として,そのまま/水平 Flip/垂直 Flip
- 全モデル(ConvNext x 5 + SwinTransformer x 5 = 10)の単純平均アンサンブル
- ターゲット 3 つ予測で,
cloverとdeadは 3 つのターゲットから算出
Sampling Date で Fold に関しては,Sampling Date によってデータの偏りがあるとディスカッションにあったので,それに即してデータ分割しました.
また,データオーグメンテーションに関しても,撮影機材(スマホ・カメラ)などでノイズなどに差があると話題になっていたので,そのあたりを埋めるための処理を入れました.
他にもやりたいことはありましたが,この辺りまでしかできませんでした!
ここまでは私のトライ,ここから上位解法です!
4. 上位解法
1 位解法
元の記事はこちら
いろいろ盛り,というイメージです.
モデル
- Backbone
- DINOv3 を使用
- 左右分割画像の特徴(backbone の出力)を結合し,multi-head self-attention で融合
- 融合した特徴を MLP
- Head
- 回帰ヘッド
- 各バイオマスの指標を独立に回帰
- 物理的制約無し - 分類ヘッド
- 各バイオマスの指標に対して分類ヘッドを追加(補助的に使い,特徴表現を安定させる)
- 各指標を 7 つの区間に分割し,その区間を予測する(density map のない Crowd Count のように)
- 回帰ヘッド
入力・訓練
- State と Sampling Date の組み合わせで 3-fold 分割
- 各 fold ごとにモデルを学習
- 左右分割
- 同一 backbone 入力
- 訓練データオーグメンテーション
- Flip / Rotate
- Noise
- Brightness
- Contrast
- HSV
- CLAHE
- ColorJitter
- リサイズ & 黒パディング
- 縮小し,黒背景に重畳
- カメラによる焦点距離・視野角の差を作る
出力・推論
- 5 ターゲットの回帰
- 5 ターゲットの分類
-
Test-time training
- 4 つのバリエーションの異なるモデルでテストデータの擬似ラベル作成
- DINOv3-Large x 2 を訓練データ + テストデータで学習
- 過適合を防ぐため,最後に訓練データのみで fine-tuning
- DINOv3-Large x 2 で再度擬似ラベル作成
- DINOv3-Base x 2 作成
- Large:Base = 0.4:0.6 で推論
- 後処理
- Clover / Dead をスケーリング
- GDM は GDM と Green + Clover の関係から再計算
- Total は複数の値を用いて再計算
2 位解法
元の記事はこちら
この解法はタスクを単純な画像回帰ではなく,density estimation の問題 として捉えています.
モデル
- DINOv3
- 中間層 [4, 11, 17, 23] の抽出
- DPT Head
- セマンティックセグメンテーションとして設計
- SegDINO を参考に DPT Head 採用
- 各中間層の特徴を [96, 192, 384, 768] に射影
- 3x3 Conv
- 解像度を合わせて結合(U-Net のよう)
- 1x1 Conv で 3ch(Clover / Dead / Green)を出力
入力・訓練
-
State で 5-fold
- 5-fold 内の label の mean /std が揃うように seed 調整
- データ数の観点から Sampling Date と State の組み合わせでの fold はしない
- リークを許容して fold 実施
- 2 つの入力サイズ
- 2048 x 1024
- 1024 x 1024
-
データ生成
- Qwen を用いてデータ生成
- 季節・天候・砂利・岩など
- 裸地のみを残した画像(Clover / Dead / Green を 0) - 回帰タスク用のデータ生成は難しく,生成データを混ぜるとスコアが低下(季節や色味を変えるとバイオマスがわからなくなる)
- 既存モデルで生成データに擬似ラベルを付与
- Qwen を用いてデータ生成
- 訓練データオーグメンテーション
- 一般的なオーグメンテーション
- Mixup
- CutMix
- RandomResizedCrop / RandomErasing(意外にも向上に寄与)
出力・推論
- 3 ch のセグメンテーション(density map)
- Clover
- Dead
- Green
- State-based scaling
- 画像から State の予測は可能
- WA 州では Dry_Dead_g はすべて 0
- State を予測し,ルールベースで補正
- Clipping
- 訓練データから得られた最大値を用いて各ターゲットをクリッピング
- Separate target models
- Green は早期に過学習
- Clover / Dead は遅くに収束
- ターゲットごとに採用するモデルの epoch を変更する
3 位解法
元の記事はこちら
モデルの多様性と大規模アンサンブルを実施しています.
モデル
- 2 系統のモデル
- Metadata Models(不採用)
- Non-Metadata Models
- Non-Metadata Models
- Backbone
- DINOv3 ViT-Huge Plus
- ConvNextV2-Large
- Vit-Base など - MambaBlock
- backbone 部分の lr は通常の 1/10
- Backbone
- 最終 19 モデルのアンサンブル
入力・訓練
- 左右分割
- 訓練データオーグメンテーション
- 一般的なオーグメンテーション
- Random Grayscale
- MixUp
- 縦に 4 分割し,場所を入れ替える
- 2 種類の fold
- Sampling Date
- Embedding Distance CV
- いずれにせよ信じてない
出力・推論
- 3 ターゲットの回帰
- Green
- Dead
- Clover
- GDM と Total は上記から算出
- TTA 不採用
- 強いデータオーグメンテーションと大規模アンサンブルのため不要
- ターゲットによってスケーリング
- Test-Time Training も不採用(効果なし)
5. さいごに
今回は私がトライした Kaggle のコンペの上位解法について紹介しました.
個人的なイメージとしては,
- 1 位:やれること全部やる
- 2 位:別方向からのアプローチ
- 3 位:たくさんのモデルで戦う
という感じでした.
特に,2 位の方の density map とするアプローチや,1 位の人でうまく行った Test-time training が 3 位の解法ではうまくいかなかったところなどは大変興味深い内容でした.
また,それぞれの解説ページにある実験のトライ&エラーの数の多さにも驚きました.
そろそろ私もメダルが欲しいので,また次のコンペ見つけてメダルを狙っていきます!
そして,これらの経験を活かし,得られた知見を今後の業務や AI モデル開発に活かしていきたいと考えています.
本記事が,これからコンペに挑戦する方や,AI モデル開発に取り組む方のヒントになれば幸いです.
参考
注意事項
本ブログに掲載している内容は,私個人の見解であり,所属する組織の立場や戦略,意見を代表するものではありません.あくまでエンジニアとしての経験や考えを発信していますので,ご了承ください.