Competition: Kaggle CSIRO Biomass Task: ๋ชฉ์ด์ง(Pasture) top-view ์ด๋ฏธ์ง๋ก ๋ฐ์ด์ค๋งค์ค(๊ฑด์กฐ ์ค๋) ์์ธก Metric: Globally Weighted Rยฒ (Dry_Total_g 50%, GDM_g 20%, ๋๋จธ์ง ๊ฐ 10%) Data: 357๊ฐ ์ด๋ฏธ์ง (70cm ร 30cm quadrat), 19๊ฐ ํธ์ฃผ ์ฌ์ดํธ
| ๋ฒ์ | CV Score | Public LB | ํต์ฌ ํน์ง |
|---|---|---|---|
| v27 (5-model ensemble) | ~0.80 |
0.70 | ํ์ฌ ์ต๊ณ Public |
| CV1 (honest CV) | 0.6366 | 0.68 | ์ ์งํ CV ๊ธฐ์ค์ |
| CV3 (preprocessing) | 0.5253 | 0.65 | ์ ์ฒ๋ฆฌ๊ฐ ์ญํจ๊ณผ |
| 1์ | ? | 0.79 | ๋ชฉํ |
โ ๏ธ v27์ CV ~0.80์ data leakage๊ฐ ์๋ ํ์ ์์น. Private LB์์ ํ๋ฝ ์ํ ์์.
notebooks/
โโโ 01_eda.py # ์ด๊ธฐ EDA
โโโ 02~11_*.py # ์ด๊ธฐ ์คํ (DINOv2 ๊ธฐ๋ฐ, LB ~0.50)
โโโ 12~19_*.py # DINOv3 ์ ํ (LB ~0.70 ๋ฌ์ฑ)
โโโ 20~27_*.py # v20 ๊ณ์ด (v27 ์ต๊ณ ์ 0.70)
โโโ cv1_train/infer.py # ์ ์งํ CV ๊ธฐ์ค์ (LB 0.68)
โโโ cv2_train/infer.py # Weighted Loss + Frozen backbone (์คํจ)
โโโ cv3_train/infer.py # ์ด๋ฏธ์ง ์ ์ฒ๋ฆฌ ์คํ (์ญํจ๊ณผ)
โโโ cv4_infer.py # v27 + TTA + WA ํ์ฒ๋ฆฌ
โโโ cv4a/cv4b_infer.py # Kaggle timeout ๋์ ๊ฒฝ๋ ๋ฒ์
โโโ cv5_train/infer.py # ConvNeXt-Base ๋ฉํฐ ๋ฐฑ๋ณธ
โโโ cv5e_infer.py # DINOv3 + ConvNeXt ์์๋ธ
โโโ cv6_train/infer.py # ์ง์ฌ๊ฐํ full-frame + SSF
โโโ cv7_train/infer.py # v26 OOF training
โโโ cv7a_train.py # EMA ์ ์ฉ
โโโ cv7b_train.py # EMA variant 2
โโโ cv8_train/infer.py # LLRD (Layer-wise LR Decay)
data/
โโโ EDA_Report_CSIRO_Biomass.md
โโโ Full_Analysis_Report.md
โโโ Breakthrough_Strategy_0.70_to_0.79.md
โโโ CV3_Strategy_0.72_Target.md
โโโ CSIRO_Competition_Strategy_DINOv2.md
โโโ Strategy_0.75_Execution_Plan.md
docs/
โโโ DINOV3_GOLD_STRATEGY.md # ํต์ฌ ์ํคํ
์ฒ ์ค๊ณ ๋ฌธ์
โโโ DIAGNOSTIC_ANALYSIS.md
โโโ HYBRID_APPROACH_DESIGN.md
ํ์ผ: 01_eda.py
์ฃผ์ ๋ฐ๊ฒฌ:
- Train: 357๊ฐ ๊ณ ์ ์ด๋ฏธ์ง, ๊ฐ ์ด๋ฏธ์ง๋น 5๊ฐ ์ํ (ํ๊ฒ๋ณ) โ ์ด 1,785ํ
- Test: ๋ฉํ๋ฐ์ดํฐ ์์ โ ์ด๋ฏธ์ง๋ง์ผ๋ก ์์ธกํด์ผ ํจ
- ํ๊ฒ ๋ถํฌ:
Dry_Clover_g: 37.8%๊ฐ 0 (์ฌํ sparsity)Dry_Total_gโDry_Green_g+Dry_Dead_g+Dry_Clover_g(๋ฌผ๋ฆฌ์ ๊ด๊ณ)GDM_gโDry_Green_g+Dry_Clover_g
Height_Ave_cm๊ณผDry_Green_g์๊ด๊ณ์ 0.648 (๊ฐ์ฅ ๊ฐํจ)- WA(Western Australia) 32๊ฐ ์ํ ์ ๋ถ
Dry_Dead_g = 0(100% ํจํด)
ํ์ผ: 02~11_*.py
์ ๊ทผ๋ฒ: DINOv2 ViT-Base(86M) โ Frozen backbone โ ๋ค์ํ Head ์คํ
| ์คํ | ํน์ง |
|---|---|
| 02~06 | ResNet/EfficientNet baseline, Kaggle/Colab ํ๊ฒฝ ์ค์ |
| 07 | Physics-constrained head (GDM=G+C, Total=GDM+D) |
| 08 | Auxiliary task learning |
| 09~10 | Pseudo labeling |
| 11 | LUPI/Knowledge Distillation hybrid approach |
๊ฒฐ๊ณผ: LB ~0.50์์ ์ ์ฒด ์์ธ ๋ถ์:
- ViT-Base๋ feature ํํ๋ ฅ์ด ๋ถ์กฑ
- Frozen backbone โ ๋๋ฉ์ธ ์ ์ ๋ถ๊ฐ
- LUPI/KD๋ Teacher ceiling(0.62)์ด Student ์ํ์ ์ด ๋จ
ํต์ฌ ์ ํ: Public notebook 070.py ๋ถ์์ผ๋ก ํต์ฌ ๊ตฌ์กฐ ํ์
ํต์ฌ ์ธ์ฌ์ดํธ:
1. DINOv3 ViT-Large (~300M) >> ViT-Base (86M)
2. ์ด๋ฏธ์ง๋ฅผ Left/Right ์ ๋ฐ์ผ๋ก ๋ถํ ํ FiLM fusion
3. Physics constraints (GDM=G+C, Total=GDM+D)
4. 5-Fold Ensemble + TTA
์ํคํ ์ฒ (v12~ ์ดํ ํ์ค):
Input Image (70cm ร 30cm)
โ
โโโโโโดโโโโโ
โผ โผ
Left Half Right Half (๊ฐ๊ฐ 512ร512 resize)
โ โ
โโโโโโฌโโโโโ
โ DINOv3 ViT-Large (๊ณต์ backbone)
โ output: 1024-dim
โผ
FiLM Module (cross-region context sharing)
ฮณ = Tanh(MLP(left+right)/2)
ฮฒ = Tanh(MLP(left+right)/2)
left_mod = left ร (1+ฮณ) + ฮฒ
โ
Concat(left_mod, right_mod) โ 2048-dim
โ
โโโโโโผโโโโโ
Head_Green Head_Clover Head_Dead
โ โ โ
โโโโโโSoftplus (non-negative)
โ
Physics Layer: GDM = G+C, Total = GDM+D
โ
[Green, Dead, Clover, GDM, Total]
์คํ ํ๋ฆ:
| ๋ฒ์ | ํต์ฌ ๋ณ๊ฒฝ | ๊ฒฐ๊ณผ |
|---|---|---|
| v12 | DINOv3 ViT-Large + FiLM ์ฒซ ๊ตฌํ | ๊ธฐ์ค์ |
| v13 | ์ต์ ํ (AMP, gradient clipping) | - |
| v14 | ๊ฐ์ | - |
| v15 | ๊ธฐ๋ณธ์ผ๋ก ๋ณต๊ท | - |
| v16 | Optuna HPO ์ถ๊ฐ | - |
| v17 | Optuna ์ต์ ํ ์ ์ฉ | - |
| v17b | CV-LB gap ๊ฐ์ ์๋ | - |
| v18 | Simple model tuning | - |
| v19 | Trial 22 vs 27 ๋น๊ต | - |
ํ์ผ: 20_train.py
์ฃผ์ ํน์ง:
hidden_dim=512, num_layers=3, dropout=0.1- Sampling_Date ๊ธฐ๋ฐ
StratifiedGroupKFoldโ ์ดํ ๋ฐ๊ฒฌ์ ์ผ๋ก ์ค์ - AMP(์๋ ํผํฉ ์ ๋ฐ๋) ํ์ต
- Cosine scheduler with warmup
ํ์ผ: 21_train.py
์์ด๋์ด: Location(Site) ๊ธฐ๋ฐ leave-one-out CV๋ก ๋ ์๊ฒฉํ validation
๊ฒฐ๊ณผ: CV ํ๋ฝ (๋ฐ์ดํฐ๊ฐ ๋๋ฌด ์์)
ํ์ผ: 22_train.py
ํน์ง: hidden_dim=256, num_layers=2, backbone ๊ณ ์
๊ฒฐ๊ณผ: CV ํ๋ฝ - fine-tuning์ด ํ์ํจ์ ํ์ธ
ํ์ผ: 23_train.py
๊ฒฐ๊ณผ: ๊ฐ์ ์์
ํ์ผ: 24_infer_tent.py
์์ด๋์ด: Test ๋ฐ์ดํฐ์ BN ํต๊ณ๋ก ๋ชจ๋ธ adapt
๊ฒฐ๊ณผ: Hidden test set์์ ์ค๋ฅ ๋ฐ์์ผ๋ก ์คํจ
ํ์ผ: 25_train.py
์์ด๋์ด: NDVI/Height ๋ฑ tabular feature๋ฅผ ์ถ๊ฐ ์
๋ ฅ์ผ๋ก
๊ฒฐ๊ณผ: Test์ ๋ฉํ๋ฐ์ดํฐ ์์ด ํจ๊ณผ ์ ํ์
ํ์ผ: 26_train_oof.py
๋ชฉ์ : ์์๋ธ ๊ฐ์ค์น ์ต์ ํ๋ฅผ ์ํ OOF ์์ธก ์์ง
ํน์ง: v20 ๊ตฌ์กฐ ์ ์ง, OOF ํ์ผ ์ถ๊ฐ ์ ์ฅ
ํ์ผ: 27_train.py, 27_infer.py
# v27์ 5๊ฐ ๋ชจ๋ธ ์กฐํฉ
MODELS = {
'v20': (hidden_dim=512, layers=3), # ๊ธฐ๋ณธ ๊ตฌ์กฐ
'v22': (hidden_dim=256, layers=2), # ์์ Head, frozen backbone
'v23': (hidden_dim=512, layers=3), # v20๊ณผ ๋์ผ, ๋ค๋ฅธ seed
'v25': VegetationEncoder + FiLM, # VegIdx late fusion
'v26': (hidden_dim=512, layers=3), # OOF ๋ฒ์
}
# ์์๋ธ: Simple average (5 ร 5-fold = 25๊ฐ ๋ชจ๋ธ)์ 0.70์ ๋ฌ์ฑํ๋:
- ๋ชจ๋ธ ๋ค์์ฑ: 3๊ฐ์ง ๊ตฌ์กฐ ร ๋ค๋ฅธ seed โ ์์๋ธ ํจ๊ณผ
- 5๊ฐ ๋ชจ๋ธ ร 5-fold = 25๊ฐ ์์ธก์ ํ๊ท
์ฝ์ :
- CV leakage (image_id๋ก grouping โ ๊ฐ์ ๋ ์ง ์ด๋ฏธ์ง๋ค์ด ์์)
- CV ~0.80์ ํ์ โ ๊ณผ์ ํฉ๋ ๊ฒ
- TTA ์์
๋ฐฐ๊ฒฝ: Discussion 126 votes ์ธ์ฌ์ดํธ
"๋ฐ๋์
Sampling_Date๋ก GroupKFold ํด์ผ ํจ. ๊ฐ์ ๋ ์ง ์ด๋ฏธ์ง๋ค์ ๋์ผํ ๋ ์จ/์กฐ๋ช ์กฐ๊ฑด ๊ณต์ . image_id๋ก ํ๋ฉด ์ฌ๊ฐํ data leakage."
ํ์ผ: cv1_train.py, cv1_infer.py
ํต์ฌ ๋ณ๊ฒฝ:
# โ ์ด์ (leakage)
groups = df['image_id']
# โ
CV1 (์ ์ง)
groups = df['Sampling_Date'] # ๋ ์ง๋ณ ์์ ๋ถ๋ฆฌ
sgkf = StratifiedGroupKFold(n_splits=5)
# + State_Month stratification key๋ณ๊ฒฝ์ฌํญ:
- CV Split: image_id โ Sampling_Date (data leakage ์ ๊ฑฐ)
- ํด์๋: 512 โ 560 (14์ 16 ๋ชจ๋์ ๋ฐฐ์)
- TTA: 4-fold (Original ร HFlip ร VFlip)
- Head: hidden_dim=256, num_layers=2, dropout=0.3
๊ฒฐ๊ณผ:
- CV Score: 0.6366 (์ ์ง, fold๋ณ 0.71, 0.65, 0.64, 0.66, 0.63)
- Public LB: 0.68
- CV-LB gap: ~0.04 (์ด์ v27์ gap ~0.10๋ณด๋ค ํจ์ฌ ์์)
์๋ฏธ: ์ ์งํ CV ํ๋ณด โ ์ดํ ์คํ์ ์ ๋ขฐ ๊ฐ๋ฅํ ๊ธฐ์ค์
ํ์ผ: cv2_train.py
์คํ ๋ชฉ์ : ๋ํ ํ๊ฐ์งํ(Weighted Rยฒ)์ ๋ง์ถ loss function
# Competition weights: Total=0.5, GDM=0.2, ๋๋จธ์ง=0.1
loss = weighted_mse(pred, target, weights=[0.1, 0.1, 0.1, 0.2, 0.5])
+ frozen backbone (fine-tuning ์์ด head๋ง ํ์ต)๊ฒฐ๊ณผ: CV 0.5966 โ ์คํจ ์์ธ:
- Frozen backbone: 357๊ฐ ์๊ท๋ชจ ๋ฐ์ดํฐ์์ ๋๋ฉ์ธ ๊ฐญ ํด๊ฒฐ ๋ถ๊ฐ
- Weighted Loss: MSE ๋๋น ํ์ต ๋ถ์์
์๋ธ ์คํ: Optuna HPO (cv2_optuna.py)
- ์์ Head ํ์:
hidden_dim=[64,128,256,512],num_layers=[1,2,3] - ๊ฒฐ๋ก :
hidden_dim=256, num_layers=2๊ฐ ์ต์ (ํฐ head๋ 357๊ฐ์ ๊ณผ์ ํฉ)
ํ์ผ: cv3_train.py, cv3_infer.py
์คํ ๋ชฉ์ : Discussion ๋ณด๊ณ (0.60 โ 0.62 ๊ฐ์ )
def clean_image(img):
# 1. Bottom 10% crop (color chart, cardboard artifacts)
img = img[0:int(h*0.90), :]
# 2. Orange timestamp inpainting (HSV mask + cv2.inpaint)
mask = cv2.inRange(hsv, [5,150,150], [25,255,255])
img = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)๊ฒฐ๊ณผ: CV 0.5253 โ Public LB 0.65 โ ์ญํจ๊ณผ
์์ธ ๋ถ์:
0.60 ์์ค: ๋
ธ์ด์ฆ ์ ๊ฑฐ โ ์ ํธ ๋๋น ํฅ์ โ ํจ๊ณผ์
0.70 ์์ค: ์ ๋ณด ์์ค์ด ๋ ํผ โ ์คํ๋ ค ํด๋ก์
๊ฒฐ๋ก : ๊ณ ๋์ ๊ตฌ๊ฐ์์๋ "๋
ธ์ด์ฆ ์ ๊ฑฐ"๋ณด๋ค "์ ๋ณด ๋ณด์กด"์ด ์ค์
๋ณํ ์คํ: WA State Dead=0 ํ์ฒ๋ฆฌ ๊ฐ๋ฐ
# WA 32๊ฐ ์ํ ๋ชจ๋ Dead=0 โ 100% ํจํด โ ๊ฐ์ ํ์ฒ๋ฆฌ
if state == 'WA':
pred[dead_idx] = 0.0
pred[gdm_idx] = green + clover
pred[total_idx] = green + clover # dead=0์ด๋ฏ๋กํ์ผ: cv4_infer.py
๋ชฉํ: ๊ธฐ์กด v27 ์ฒดํฌํฌ์ธํธ ํ์ฉ, ๋น ๋ฅธ ์ ์ ํฅ์
v27 5๊ฐ ๋ชจ๋ธ ร 5-fold = 25 ์ฒดํฌํฌ์ธํธ
+ 4-fold TTA (Original, HFlip, VFlip, Both)
+ WA State Dead=0 ๊ฐ์ ํ์ฒ๋ฆฌ
= ์ด 100๊ฐ ์์ธก ํ๊ท
ํ์ ๋ฒ์ :
cv4a_infer.py: 2-fold TTA๋ง (Kaggle ์๊ฐ ์ ํ ๋์)cv4b_infer.py: v20/v22/v26 3๊ฐ ๋ชจ๋ธ๋ง (timeout ๋ฌธ์ ํด๊ฒฐ)
ํ์ผ: cv5_train.py, cv5_infer.py
์์ด๋์ด: Transformer + CNN์ ์ด์ค ๊ด์ ์์๋ธ
DINOv3 ViT-Large: Global attention, long-range dependency
ConvNeXt-Base (ImageNet-22k): Local patterns, hierarchical features
โ ์๋ก ๋ค๋ฅธ inductive bias โ ์์๋ธ ๋ค์์ฑ ๊ทน๋ํ
# cv5e (์์๋ธ inference)
CV5E_WEIGHT = 0.3 # ConvNeXt: ๋ค์์ฑ ๋ชฉ์
V27_WEIGHT = 0.7 # DINOv3: ๋ฉ์ธ ๋ชจ๋ธํน์ง:
- ConvNeXt:
convnext_base.fb_in22k_ft_in1k, feat_dim=1024 - ์ด๋ฏธ์ง ํฌ๊ธฐ: 560ร560 (DINOv3์ ๋์ผ)
- WandB ์คํ ์ถ์
ํ์ผ: cv6_train.py, cv6_infer.py
ํต์ฌ ์์ด๋์ด: ์ด๋ฏธ์ง๋ฅผ Left/Right๋ก ์๋ฅด์ง ๋ง๊ณ , ์๋ ๋น์จ ์ ์ง
๊ธฐ์กด: Left(512ร512) + Right(512ร512) โ FiLM fusion
CV6: Full-frame (784ร336) โ ๋จ์ผ ์
๋ ฅ
โ 70cmร30cm ์๋ ๋น์จ ๊ทผ์ฌ
class CFG:
img_size = (336, 784) # Height ร Width (๋น์จ ์ ์ง)
freeze_backbone = True # Frozen + SSF๋ง ํ์ต
use_ssf = True # Scale-Shift Feature adapters
# SSF: ๊ฐ Transformer block ์ถ๋ ฅ์ ํ์ต ๊ฐ๋ฅํ scale/shift ์ ์ฉ
# ฮณ, ฮฒ๋ง ํ์ต โ Frozen backbone์์ ๋๋ฉ์ธ ์ ์ ๊ฐ๋ฅ
class SSFAdapter(nn.Module):
# scale: ฮพ * x + ฮณ (per-feature)์ถ๊ฐ ํน์ง:
ZeroInflatedHead: Clover์ 37.8% zero ์ฒ๋ฆฌ (๋ถ๋ฅ + ํ๊ท 2-stage)CLS + Patch Meanpooling (richer aggregation)ZeroInflatedLoss: BCE(zero/nonzero) + MSE(nonzero only)
๋ชฉํ: SSF๋ก frozen backbone์ ํ๊ณ ๊ทน๋ณตํ๋ฉด์ overfitting ๋ฐฉ์ง
ํ์ผ: cv7_train.py, cv7_infer.py
๊ธฐ๋ฐ: v26 ๊ตฌ์กฐ
๋ชฉ์ : ๋ค๋ฅธ ํด์๋/๋ ์ง split ์ค์ ์ผ๋ก OOF ํ์ง ๊ฐ์
ํ์ผ: cv7a_train.py
ํต์ฌ ์ถ๊ฐ:
class EMA:
"""Shadow weights: ฮธ_ema = decay * ฮธ_ema + (1-decay) * ฮธ"""
# ํ์ต ์ค weight์ ์ง์ ์ด๋ ํ๊ท ์ ์ง
# Inference: EMA weights ์ฌ์ฉ โ ์์ ์ , ์ผ๋ฐํ ์ฐ์
class CFG:
use_ema = True
ema_decay = 0.999
backbone_lr_mult = 0.084 # LLRD: backbone lr = lr ร 0.084์ EMA์ธ๊ฐ: ์๊ท๋ชจ ๋ฐ์ดํฐ(357๊ฐ)์์ weight ์ง๋ ์ํ, ๋ ๋ถ๋๋ฌ์ด loss landscape
ํ์ผ: cv7b_train.py
EMA ์ค์ ๋ณํ ์คํ
ํ์ผ: cv8_train.py
ํต์ฌ ์์ด๋์ด:
# Transformer ๋ ์ด์ด๋ณ LR ๊ฐ์ ์ ์ฉ
# ๊น์ ๋ ์ด์ด (ํ์ ๋ ์ด์ด): ์์ LR โ ์ฌ์ ํ์ต ๋ณด์กด
# ์์ ๋ ์ด์ด + Head: ํฐ LR โ ํ์คํฌ ์ ์
layer_lr_decay = 0.9 # ๋ ์ด์ด๋น 10% ๊ฐ์
# Layer 0 lr = base_lr ร decay^n_layers
# Layer n lr = base_lr ร decay^0 = base_lrimage_id grouping โ CV 0.80 (ํ์) โ LB 0.70, CV-LB gap 0.10
Sampling_Date grouping โ CV 0.64 (์ ์ง) โ LB 0.68, CV-LB gap 0.04
โ ์ ์งํ CV ์์ด๋ ์๋ฌด๊ฒ๋ ์ ๋ขฐํ ์ ์๋ค.
๋ฎ์ ์ ์(0.60): ์ ์ฒ๋ฆฌ ๋
ธ์ด์ฆ ์ ๊ฑฐ โ +0.02 ํจ๊ณผ ์์ (Discussion ๋ณด๊ณ )
๋์ ์ ์(0.70): ์ ์ฒ๋ฆฌ โ ์คํ๋ ค -0.05 (CV3)
โ ์ ๋ณด ๋ณด์กด vs ๋ ธ์ด์ฆ ์ ๊ฑฐ์ trade-off๋ ์ ์ ์์ค์ ๋ฐ๋ผ ๋ค๋ฆ
๋จ์ผ ๋ชจ๋ธ (CV1): LB 0.68
5-๋ชจ๋ธ ์์๋ธ (v27): LB 0.70
์ฐจ์ด: +0.02 (๋ชจ๋ธ ๋ค์์ฑ๋ง์ผ๋ก)
๋ฐ์ดํฐ: 357๊ฐ ์ด๋ฏธ์ง (๋งค์ฐ ์์)
์ต์ Head: hidden_dim=128~256, num_layers=1~2, dropout=0.3~0.5
ํฐ Head(hidden_dim=512, layers=3) โ ๊ณผ์ ํฉ
DINOv3 ViT-Large๊ฐ ์ด๋ฏธ 1024-dim ํ๋ถํ feature ์ ๊ณต
# ๋ชจ๋ธ์ด ๋ฌผ๋ฆฌ ๋ฒ์น์ ์๋์ผ๋ก ๋ง์กฑํ๋๋ก ๊ฐ์
GDM = Green + Clover # ๋ณ๋ ํ์ต ๋ถํ์
Total = GDM + Dead # ํญ์ consistentclass CSIROModel(nn.Module):
backbone = timm.create_model(
"vit_large_patch16_dinov3_qkvb.lvd1689m",
pretrained=False # ๋ณ๋ weights ๋ก๋
) # DINOv3 ViT-Large, 1024-dim output
film = FiLM(feat_dim=1024) # Cross-region modulation
head_green = MLP(2048 โ 512 โ 1) # Dry_Green_g
head_clover = MLP(2048 โ 512 โ 1) # Dry_Clover_g
head_dead = MLP(2048 โ 512 โ 1) # Dry_Dead_g
# Physics: GDM = G+C, Total = GDM+D (computation, not learning)ํ์ต ์ค์ :
- Optimizer: AdamW
- LR:
1e-4(head),1e-5(backbone, ร0.1) - Scheduler: Cosine with warmup
- Loss: MSE on [Green, Dead, Clover] (GDM, Total์ ๊ณ์ฐ์ผ๋ก ์๋)
- Image size: 560ร560 (14์ 16 ๋ชจ๋์ ๋ฐฐ์)
- Augmentation: HFlip, VFlip, ColorJitter
- AMP (Mixed Precision)
์์ ํจ๊ณผ๋ณ ์ ๋ต:
| ์ ๋ต | ์์ ํฅ์ | ์ํ |
|---|---|---|
| CV ์์ (Sampling_Date) | +0.03~0.05 | โ CV1์์ ์๋ฃ |
| ํด์๋ 560 + TTA | +0.02~0.03 | โ CV1์์ ์๋ฃ |
| Optuna HPO (์์ Head) | +0.02~0.03 | ๐ ์งํ ์์ |
| EMA (CV7a) | +0.01~0.02 | ๐ ์คํ ์ค |
| LLRD (CV8) | +0.01~0.02 | ๐ ์คํ ์ค |
| Multi-backbone (DINOv3+ConvNeXt) | +0.02~0.03 | ๐ CV5E |
| Weighted Loss alignment | +0.01~0.02 | ์คํ ํ์ |
| Multi-seed ensemble | +0.01 | ์คํ ํ์ |
| OOF ๊ธฐ๋ฐ ์์๋ธ ์ต์ ํ | +0.01 | ์คํ ํ์ |
์ฃผ์: Private LB๋ ์ ์ฒด์ 47%. v27(leakage CV) ๊ธฐ๋ฐ ์ ์ถ์ Private์์ ํ๋ฝ ์ํ.
# ์ฃผ์ ์์กด์ฑ
torch>=2.0 timm albumentations transformers wandb optuna
# DINOv3 weights (Kaggle dataset: pretrained-weights-biomass)
# /kaggle/input/pretrained-weights-biomass/dinov3_large/dinov3_large/dinov3_vitl16_qkvb.pthํ์ต/์ถ๋ก ๋ถ๋ฆฌ ์ ๋ต:
1. [ํ์ต] cv*_train.py โ Colab/Kaggle GPU์์ ์คํ (~80๋ถ)
โ fold*.pth ์ ์ฅ โ Google Drive ๋๋ Kaggle Dataset
2. [์ถ๋ก ] cv*_infer.py โ Kaggle ์ ์ถ ๋
ธํธ๋ถ (๊ฐ์ค์น๋ง ๋ก๋, ~1๋ถ)
๋ง์ง๋ง ์ ๋ฐ์ดํธ: 2026-02-26 ํ์ฌ ์ต๊ณ Public LB: 0.70 (v27) ์ ์งํ CV ๊ธฐ์ค์ : 0.68 (CV1)