🌾
CSIRO - Image2Biomass Prediction 上位解法MEMO
※ 個人用メモです。が間違っていたらご指摘ください:pray:
コンペの概要
- CSIRO - Image2Biomass Prediction
- 期間: 2025/10/28 ~ 2026/01/28
- 目的: 牧草地の画像から、そこに含まれるバイオマスを予測するコンペ
(割と)共通している手法
- DINOv3をbackboneに使用
- Backboneの重みをなるべく崩さないように工夫
- backboneをunfreeze(段階的にunfreeze)
- 学習率を小さくする
- model: 画像を左右に分割してそれぞれでbackbone通す
- post-processing: clipやスケーリングなど
各解法の特徴的な手法
1st Place Solution
- augmentation
- 画像にランダムに小さなサイズのスケーリングを適用し、黒ピクセルで補完する
- 異なるカメラの焦点距離と視野角の違いをシミュレートするため
- 画像にランダムに小さなサイズのスケーリングを適用し、黒ピクセルで補完する
- model
- DINOv3を通した後に、self-attention layerを通してからMLPに通す
- 5つのregression headを使用(3つではない)
- 物理的制約なしで学習を進めるため
- targetをbinsに分割して、補助LOSSで分類タスクを追加
- EpsilonInsensitiveLossを使用
- 正解データ(target)が大きくなるほど、誤差に対する許容範囲(epsilon)を広げる
- training: 2段階
- 1段階目: backboneをfreezeして学習
- 2段階目: backbone含めてfine-tune
- online trainingを実施
- スコアが安定しているモデルで疑似ラベル生成→DINO-Largeの学習→DINO-Largeで擬似ラベル生成→DINO-Baseの学習の流れ
2nd Place Solution
- 合成データ(ラベルはpseudo-labelingで生成)を作成して学習に使用
- Augmentation
- RandomResizedCropが効果的だった(おそらく1st placeと同じ理由)
- model: 密度推定問題として扱う方法を使用
- DINOv3の出力を使用してサイズ(N, C, H, W)の特徴マップを抽出
- その後、異なるheadによって密度マップを推定
- post-processing
- どの州のデータかを予測して、その予測確率に応じて後処理を分ける
- WAの確率が0.75より大きい場合はdeadを0と予測
- 週ごとにスケーリング係数を適用
- 予測値を学習データの最大値でclipする
- どの州のデータかを予測して、その予測確率に応じて後処理を分ける
- training:
- targetによってlossが下がり切るタイミングが変わるので、targetごとに使用するcheckpointを変える
- 高速化
- FP16量子化を使用(推論時間を2H→27minに短縮)
3rd Place Solution
- model
- DINOv3 backboneを通した後にMambaBlockを通す
- training
- backboneは1/10の学習率を使用
- augmentation
- 画像を横方向に4つのセグメントに分割して、セグメントの順序を入れ替える。
- 左右の画像も50%の確率で入れ替える
- CV strategy
- 推論が難しいor 簡単なサブセットを分けた場合、簡単なサブセットに対するスコアとLBスコアに相関があった
4th Place Solution
- 画像に含まれるタイムスタンプをHSV色空間検出と画像修復技術を用いて除去
- model
- 画像の右、左、全体それぞれをBackboneに通す
- aux用のheadも使用(ndvi, heightなどを予測)
- loss: GaussianNLLLossを主に使用
- R^2 metricのハズレに対する感度に対処するため
- ノイズの多いサンプルを自動的に重み付けするため
- TTA
- 水平, 垂直反転
5th Place Solution
- model: 密度推定アプローチに極力近づける
- 各パッチトークンから局所的なバイオマス密度を予測し、画像全体で合計する
- training
- epochごとにbackboneを段階的にunfreezeして学習
- 先頭に近い層から徐々にunfreezeしていく
- 後半のepochで回答された層を学習するために学習率のスケジューラーは使用しない
- loss
- (特徴量間の?) 物理的な関係性を強制するためConsistencyLossも活用
- data
- 画像を半分に分割して、ラベルも半分にしてtrainingデータを2倍に増やす
- CV strategy
- グループベースのアプローチに加えて、CloverとDeadが0のサンプルが各foldに均等に分布するようにfoldを構成
7th Place Solution
- model
- dual/single streamの2つのモデルを使用
- 画像を左右に分割してbackboneに通すかどうか
- dual/single streamの2つのモデルを使用
- 高速化
- 1つのGPUでdual stream, もう1つのGPUでsingle streamの推論を実施
- TestTimeTraining(TTT)を実施
- 推論に後処理(clippingとscaling)を実施し、その予測値とtrainig dataの両方を用いてsingle streamモデルを学習
- 最後の4epochにSWA(Stochastic Weight Averaging)を適用
8th Place Solution
- 各メンバーをそれぞれで異なるtraining手法, modelアーキテクチャを採用しており、それらのアンサンブルが効いた(のかも)
- takumi part
- DINOv2 HugeとSigLIPのdual streamモデル
9th Place Solution
- model
- DINOv3 Large + LocalMambaBlock
-
Dry_Total_gにおける割合としてDry_Dead_gを予測-
Dry_Dead_g=head_dead_ratio×Dry_Total_g
-
- loss
ターゲットごとにlossの重みを変える - CV strategy
- clover/deadによる層別化, 日付と州によるグループ化
10th Place Solution
- 前処理: ラベルのおかしいサンプルを学習データから除外
- クローバーが含まれているが,
Dry_Clover_gが0のサンプル
- クローバーが含まれているが,
- augmentation: 以下のアーティファクトに対応するaugmentationを実施
- フラッシュと思われる赤い点
- 画像の右下に表示される撮影日時
MEMO
Tipsまとめ
- データが少ないときは大規模なbackboneをpretrainの重みを上手く活寮するのが良い
- ターゲットが複数ある場合は、targetごとにlossの重みを変えたり、lossの推移を確認して、それぞれで適切なcheckpointを使用するのが良い
- データが少ないのでtest time training(TTT)が効いた?
所感・学び・反省点
- データにブレがあることは把握できていたが、それらへの対策を講じていなかった
- カメラの画角、撮影距離の微妙なズレ
- 撮影日時などのアーティファクト
- モデルサイズの検討は基本的にするべきで、CVだけでなくLBスコアも確認しておくべきだった
関連書籍
- Kaggleで勝つデータ分析の技術
- Kaggleに挑む深層学習プログラミングの極意 (KS情報科学専門書)
- 実践Data Scienceシリーズ PythonではじめるKaggleスタートブック (KS情報科学専門書)
以上
Discussion