안녕하세요!!
오늘은 지금 데이콘에서 진행중인 공모전에 대해서 제 주관적인 생각을 아주 많이 넣은(?) 연구용 블로그를 작성해보겠습니다.
이미 상위 랭킹에 속하긴 했지만 순위를 더 좁히고 싶어서 영상 데이터부터 시각화 검증까지 다 뜯어보면서 분석해보는 중입니다.
오늘 진행한 내용들에 대해서 정리해보도록 하겠습니다.
진행 상황 메모 블로그 참고:
[DACON 공모전] 구조물 안정성 예측 대회: EVA-Giant Dual-View 모델과 Center Crop 추론 스터디 (2)
Dacon 구조물 안정성 예측 대회에 참가하면서 겪은 시행착오, 모델 선택의 근거, 그리고 단순한 추론 전처리 변경 하나로 LogLoss 0.02117 → 0.01756을 달성한 과정을 기록합니다.1. 대회 개요와 문제 정
pak1010pak.tistory.com
[DACON 공모전] Dinov2_large 모델 분석 및 학습 진행 상황 스터디
오늘은 현재 진행중인 DACON 공모전에 대해 진행 상황 및 모델 분석에 대해서 정리해본다. 이번 dinov2_large pretrain은 이전 붕괴 구간과 달리 정상적으로 학습되고 있다고 판단할 수 있다.val logloss가
pak1010pak.tistory.com
개요 및 진행 상황
- 구조물 안정성 예측이 목적입니다. 이미지가 주어졌을 때 그 이미지가 10초 안에 쓰러지는 건축물인지 확인하는 것 입니다.
- eva_giant 모델 사용
- 입력 데이터: front.png + top.png (336×336)
- Shared Backbone Dual-View + Concat → BN+MLP (simple head)
- simple (ColorJitter 강하게, 나머지 최소) + 코랩 패치로 강화, CosineAnnealingWarmRestarts (T₀=10, T_mult=2)
- Head 2e-4, Backbone 2e-5
- 추론 시 0.9 센터 크롭 적용중
1. 실패한 원인 정리
1-1 영상 데이터 활용
- 영상을 제가 하나하나 보면서 드는 생각이 있었습니다. 학습 데이터에 10초짜리 영상이 함께 제공되는데, 영상이 시작되고 0.1초 프레임 사이에 블럭이 쓰러지기전 블럭이 위에서 살짝 떨어지는 프레임이 잡혔습니다.


그래서 저는 이 데이터를 사용할 수 있을 줄 알았습니다.
제가 생각한 이유: AI는 데이터양에 따라서도 성능이 갈라집니다. 이걸 굳게 믿고 있었습니다. 물론 양질의 데이터셋만 해당 됩니다.
원래 30ep를 돌린 테스트 제출 성능이 0.017로 준수했습니다. 여기에 동영상 프레임 0.1초 데이터 이미지를 파인튜닝 진행했습니다. 아래와 같은 원인이 발생했습니다.
- Video Frame Aug → train/test 분포 불일치
- 학습: 50% 확률로 영상 0.1초 프레임 (조명, 블러, 앵글 미세 차이)
- 테스트: front.png 고정 이미지
- 모델이 "영상 프레임 특유의 노이즈 패턴"을 unstable/stable 신호로 학습했을 가능성 → test에서는 그 패턴이 없으니 판단 오류
- 동영상 파인튜닝 후 제출 성능: 0.0242853922 -> 성능 하락
그래서 성능이 더 좋아질줄 알고 맹신했지만, 아니였습니다!! 그래서 아, 내가 하던 방식으로 AI를 다뤘던 방식으로 내 눈으로 보고 작업해야겠다! 라는 생각을 했습니다.
1-2 기존 Fold 5개의 앙상블 버전에서 - 1개의 가장 Loss가 적은 모델만 사용
이번 원인 정리는 내용이 길 수 있습니다. 현재까지도 해결하고 진행을 하고 있습니다.
지금부턴 시각화 셀을 추가 했습니다. "내가 직접 눈으로 보고 판단을 해야겠구나. 내가 눈으로 보고 원인을 찾아야 겠구나"
첫 번째 확인 입니다. 가장 처음 0.017성능을 냈던 모델중에서 가장 Loss율이 낮았던 모델입니다.



배경에도 가끔 집중하는 경향이 있지만 가운데의 블럭에 더 집중하는 모습이 보입니다.
두 번째로 30ep + 동영상 프레임 이미지 파인튜닝을 진행한 모델입니다.
로그에 찍히는 loss율은 압도적으로 좋아보였습니다.
Ep [15/15] lr=4.27e-06 02:43 | train loss=0.0006 acc=1.0000 | val logloss=0.0001 acc=1.0000 | best=0.000093
Resume ckpt 삭제: /content/dacon/local_ckpt/eva_giant_fold0_ckpt.pth
Fold 0 Best: 0.000093
============================================================
CV Mean LogLoss: 0.000093 ± 0.000000
============================================================

사진만 봐도 과적합 되었다는걸 알 수 있습니다. Train, dev 모든 이미지를 "외웠다"가 맞습니다.
그래서 더 블록에 집중하는 모델인 eva_giant_fold0.pth 을 사용해 봤더니 결과는 그래도 0.0345542771이 나왔습니다.
ep30가 충분히 무거운 모델한테 너무 많은 epoch를 준 거 같다는 느낌이 들었습니다. 그래서 5에포크씩 끊어서 파인튜닝하는 전략으로 바꿨습니다. -> 시각적으로 제가 보면서 업데이트 하는게 맞다고 느꼈습니다.
unstable_prob: mean=0.5095, std=0.4936
id unstable_prob stable_prob
0 TEST_0001 0.000067 0.999933
1 TEST_0002 0.999866 0.000134
2 TEST_0003 0.999883 0.000117
3 TEST_0004 0.999856 0.000144
4 TEST_0005 0.000346 0.999654
eva_giant_fold0.pth의 추론 파일 생성 확률 표.
1-3 기존 0.017성능 모델에 Top crop 0.7로 타이트하게 설정
기존 성능이 가장 좋았던 모델을 추론할 때 센터 크롭을 0.7로 더 줄여봤다.
왜냐, 시각적으로 봤을 때 0.9 * 0.9로 크롭한 이미지들이 가끔가다 배경 끝에 집중을 하는 경향이 보였다.
그래서 추론할 때 top crop을 0.7로 두었더니 아래와 같이 깔끔하게 나왔다.

하지만 실제 제출 성능은 0.0358793342로 더 낮게 나왔다.
이번 제출 테스트로 두 가지가 추가로 생각났다.
- 학습 때와 같이 센터 크롭을 동등하게 주면 성능이 괜찮겠다.
- front + top 이미지의 연관 관계를 학습 시켜서 성능을 끌어올려 봐야 겠다.
2. 진행중인 개선 및 연구 사항들
2-1 기존 하이퍼파라미터 설정 버전
==========================================================================================
Checkpoint Train Loss Dev Loss Train Acc Dev Acc
==========================================================================================
eva_giant_fold0.pth 0.0021944 0.0178329 0.9990 0.9900
eva_giant_fold1.pth 0.0027551 0.0417982 0.9990 0.9800
eva_giant_fold2.pth 0.0051724 0.0047132 0.9990 1.0000
eva_giant_fold3.pth 0.0064283 0.0607076 0.9990 0.9800
eva_giant_fold4.pth 0.0026747 0.0309846 1.0000 1.0000
==============================================================================================================
Checkpoint Train LL Dev LL T-Acc D-Acc T-Unst T-Stab D-Unst D-Stab
-------------------------------------------------------------------------------------------------------
eva_giant_fold0.pth 0.0021944 0.0178329 0.9990 0.9900 0.9980 1.0000 0.9808 1.0000
eva_giant_fold1.pth 0.0027551 0.0417982 0.9990 0.9800 0.9980 1.0000 0.9808 0.9792
eva_giant_fold2.pth 0.0051724 0.0047132 0.9990 1.0000 0.9980 1.0000 1.0000 1.0000
eva_giant_fold3.pth 0.0064283 0.0607076 0.9990 0.9800 0.9980 1.0000 0.9615 1.0000
eva_giant_fold4.pth 0.0026747 0.0309846 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000
======================================================================
Best Dev LogLoss: eva_giant_fold2.pth -> 0.0047132
Best Train LogLoss: eva_giant_fold0.pth -> 0.0021944
======================================================================
기존 설정 그대로 가져온 5에포크의 로그 상황입니다.
Models: ['eva_giant'] × 1 checkpoints
Folds: [2] | TTA: True | Temp: 1.0
Front crop: 0.9 | Top crop: 0.9
unstable_prob: mean=0.4894 std=0.4882
최신 제출: submission_eva_giant_f2_tta_v2.csv
샘플 수: 1000
unstable_prob: mean=0.4894, std=0.4882
id unstable_prob stable_prob
0 TEST_0001 0.001565 0.998435
1 TEST_0002 0.999104 0.000896
2 TEST_0003 0.999134 0.000866
3 TEST_0004 0.999497 0.000503
4 TEST_0005 0.002199 0.997801
위는 제출 할 때 출력되는 실제 csv 확률 분포도 입니다.
생각 없이 이 무거운 모델(eva-giant)을 30에포크나 돌려서 사용한게 많이 후회 됩니다.

30에포크에서 5에포크로 줄여서 돌렸다고 해서 eva를 시각화해서 봤을 때 큰 차이를 느끼지 못했습니다.
그래도 배경에 집중 경향과 블럭 전체를 보려는게 약한 느낌이 들었습니다.
아래는 eva버전으로 학습 설정을 맞춘 다른 방법입니다.
2-2 EVA-Giant에 맞춘 하이퍼파라미터 변형 버전
학습 설정
BACKBONE = "eva_giant"
PRETRAIN_EPOCHS = 0
FINETUNE_EPOCHS = 5
PATIENCE = 15
MERGE_DEV = True
LOSS = "ce"
NO_MIXUP = True
HEAD_TYPE = "simple"
SIMPLE_AUG = True
SCHEDULER = "cosine"
# EVA-Giant 최적화 LR (기존 2e-4/2e-5 → 5e-5/1e-5로 보수적 설정)
HEAD_LR = 5e-5
BB_LR = 1e-5
WEIGHT_DECAY = 0.05 # 기존 0.01 → 0.05 (강한 규제)
DROP_RATE = 0.3
# 층별 학습률 감소 (Layer-wise LR Decay)
LAYER_DECAY = 0.9 # EVA-Giant 추천값 (Large=0.8, Base=0.7)
WARMUP_EPOCHS = 2 # Linear warmup 2 epoch
USE_VIDEO = False
HEAD_LR
분류 헤드 쪽 학습률입니다. 새로 붙인 분류기 부분을 얼마나 빨리 업데이트할지 정합니다.
BB_LR
backbone 학습률입니다. pretrained backbone은 보통 작은 값으로 천천히 미세조정합니다.
WEIGHT_DECAY
가중치가 너무 커지는 걸 막는 정규화 강도입니다. 과적합 완화에 도움됩니다.
DROP_RATE
dropout 비율입니다. 학습 중 일부 뉴런을 랜덤하게 꺼서 과적합을 줄입니다.
WARMUP_EPOCHS
초반 몇 epoch 동안 학습률을 천천히 올리는 구간입니다. 큰 모델에서 학습을 안정적으로 시작하려고 씁니다.
LAYER_DECAY
backbone의 층별 학습률 감소 비율입니다. 보통 앞단 layer는 더 적게, 뒷단 layer는 더 많이 학습하게 만듭니다.
SCHEDULER
epoch가 진행될 때 학습률을 어떻게 바꿀지 정하는 방식입니다. cosine은 cosine 곡선처럼 줄이고, cosine_wr은 restart가 들어간 방식입니다.
NO_MIXUP
True면 Mixup/CutMix 같은 샘플 혼합 증강을 끕니다. 원본 이미지 기준으로만 학습합니다.
SIMPLE_AUG
True면 단순한 augmentation만 사용합니다. 과한 증강 대신 안정적인 증강 위주라는 뜻입니다.
MERGE_DEV
True면 train과 dev를 합쳐서 K-Fold 학습에 사용합니다. 데이터 수를 늘리는 목적입니다.
GRAD_ACCUM
gradient accumulation 횟수입니다. 작은 batch를 여러 번 누적해서 큰 batch처럼 학습합니다.
HEAD_TYPE
backbone feature를 최종 분류로 연결하는 헤드 구조입니다. simple은 단순 결합, attn_gate는 가중치 게이트, cross_attn은 두 뷰를 attention으로 섞습니다.
FUSION_LAYERS
cross_attn일 때 front/top 특징을 섞는 transformer layer 개수입니다. 많을수록 표현력은 늘 수 있지만 계산량도 증가합니다.
FUSION_HEADS
cross_attn의 multi-head attention head 수입니다. attention을 여러 관점으로 나눠 보게 합니다.
아래는 15에포크를 돌렸을 때의 grad-cam 화면 입니다.

배경을 거의 무시하고 블럭에 집중하려는게 보인다.
결과: 0.03...
추론 설정
백본: eva_giant | 이미지: 336px | 배치: 12
Front crop: 0.9 | Top crop: 0.7
TTA: True | Alpha: 1.0
앙상블: majority_best | 모델 수: 5
- eva_giant_fold0
- eva_giant_fold1
- eva_giant_fold2
- eva_giant_fold3
- eva_giant_fold4
Alpha=1.0 → Power Sharpening 미적용 (원본 그대로)
unstable_prob: mean=0.4966389647
unstable_prob: std =0.4907471499
예측 unstable: 501개
예측 stable: 499개
정답을 잘 맞췄는데 loss율이 적은 건지 확인이 필요하다.
3. DINOv2 버전 테스트
문제점 정리
- cross_attn 방법 구현
- DINO모델의 경우 eva, convnext와 같은 모델들모다 front 이미지를 보는 눈이 뛰어남.
- 하지만 top 이미지에서 집중이 안 되는 모습이 많이 보임.

핵심은 “이미지를 top에서 어떻게 구분을 하느냐” 인 것 같다.
현재 구조의 문제점
Front → DINOv2 → GAP → [1024] ─┐
├─ concat → MLP → 예측
Top → DINOv2 → GAP → [1024] ─┘
DINOv2는 336px 입력에서 24×24 = 576개 공간 토큰을 생성합니다. 각 토큰은 14×14 픽셀 패치의 의미를 담고 있어서, "어디에 뭐가 있는지" 공간 정보가 매우 풍부합니다.
그런데 현재 코드는 이 576개 토큰을 Global Average Pooling으로 하나의 벡터(1024차원)로 압축한 뒤 concat합니다. 공간 정보가 전부 날아간 상태에서 fusion이 일어나는 겁니다.
이게 왜 문제인가:
- Front: GAP해도 괜찮음. "길쭉한 탑이 있다", "기울어져 있다" = 전체 feature distribution만으로 판단 가능
- Top: GAP하면 망함. "블록이 가운데서 약간 왼쪽으로 치우쳐 있다", "무게중심이 벗어났다" = 공간 위치 정보가 핵심인데 이걸 평균내버림
Grad-CAM 이미지에서 Top의 attention이 흩어지는 이유가 정확히 이겁니다 — 모델이 top의 공간 정보를 활용할 경로 자체가 없습니다.
두 번째 문제: 학습 시 동일 augmentation
현재 datasets.py에서 front과 top에 동일한 RandomResizedCrop(0.8~1.0) 이 적용됩니다. 그런데:
- Top 뷰는 항상 가운데에 블록이 위치하는 고정된 구조
- RandomResizedCrop은 랜덤 위치를 자르므로, top에서는 블록이 잘리거나 빈 공간만 남을 수 있음
- 추론 시에는 CenterCrop(0.7)을 쓰는데 학습과 추론의 crop 전략이 다름 → train-test gap
개선 진행
1. Cross-Attention Fusion
현재 late fusion (벡터 concat)을 spatial token level cross-attention으로 교체:
Front → DINOv2 → 576 tokens [24×24×1024]
↕ Cross-Attention (front↔top)
Top → DINOv2 → 576 tokens [24×24×1024]
↓
Fused representation → Head → 예측
구체적으로:
- backbone.forward_features()로 spatial tokens 유지 (GAP 하지 않음)
- Front tokens가 Top tokens를 query하고, Top tokens가 Front tokens를 query
- "이 front 위치의 블록이 top에서는 어디에 대응하는가" 를 학습
- Cross-attention 후 pooling → classification head
- DINOv2의 patch tokens은 이미 의미 있는 공간 표현 (자기지도 학습으로 훈련됨)
- register tokens (reg4)가 global context를 담고 있어 cross-attention의 anchor 역할
- 14×14 patch size → 각 토큰이 충분히 큰 영역을 커버 → 대응 관계 학습에 적합
2. Token Concatenation + Transformer Layer
Front tokens (576) + Top tokens (576) → 1152 tokens
→ 2~4 Transformer layers (view-type embedding 추가)
→ CLS token → Head
Front/Top 토큰을 하나의 시퀀스로 합치고 self-attention으로 양방향 관계를 학습. view-type embedding ([FRONT]/[TOP])을 추가해서 어느 뷰에서 온 토큰인지 구분한다.
Token-level Cross-View Transformer Fusion 적용
학습 설정
# ── 백본 ─────────────────────────────────────────────────────────────
BACKBONE = "dinov2_large" # dinov2_large (336px, 304M params)
# ── 학습 설정 ────────────────────────────────────────────────────────
EPOCHS = 15 # 총 에폭 수
PATIENCE = 15 # early stop patience
SEED = 42
# ── 하이퍼파라미터 (DINOv2-L 최적화) ─────────────────────────────────
HEAD_LR = 1e-4 # Head 학습률
BB_LR = 1e-5 # Backbone 학습률 (자기지도 pretrain → 보수적)
WEIGHT_DECAY = 0.05 # weight decay (ViT 권장 0.05)
DROP_RATE = 0.3 # dropout rate
WARMUP_EPOCHS = 2 # warmup 에폭
LAYER_DECAY = 0.75 # DINOv2 LLRD (층별 학습률 감소)
# ── 학습 전략 ────────────────────────────────────────────────────────
LOSS = "ce" # ce | focal
SCHEDULER = "cosine" # cosine | cosine_wr
NO_MIXUP = True # True = Mixup/CutMix 끄기
SIMPLE_AUG = True # True = 단순 증강
MERGE_DEV = True # True = train+dev 1100개 합쳐서 K-Fold
# ── 하드웨어 (12GB GPU 기준) ─────────────────────────────────────────
BATCH_SIZE = 2 # DINOv2-L 336px → 12GB에서 bs=2
GRAD_ACCUM = 16 # gradient accumulation (eff_bs = 2×16 = 32)
NUM_WORKERS = 4 # DataLoader 워커 수
GRAD_CKPT = True # Gradient checkpointing (304M → 필수)
# ── 기타 ─────────────────────────────────────────────────────────────
HEAD_TYPE = "cross_attn" # simple | attn_gate | cross_attn (token-level fusion)
FUSION_LAYERS = 4 # Cross-view transformer layers (cross_attn용)
FUSION_HEADS = 8 # Attention heads in fusion
USE_VIDEO = False
# 추론 CONFIG
# --- 모델/Fold 설정 ---
INFER_FOLDS = [0, 1, 2, 3, 4] # fold 번호로 자동 탐색
INFER_CHECKPOINT = None # 직접 지정 시: ["dinov2_large_fold0.pth"]
# --- 앙상블 ---
# "majority_best": 다수결 방향 → 해당 방향 모델 중 best loss 확률 사용 (기본)
# "mean": 단순 평균
ENSEMBLE_METHOD = "majority_best"
# --- Dual-Crop ---
FRONT_CROP = 0.9 # Front view CenterCrop 비율
TOP_CROP = 0.7 # Top view CenterCrop 비율
# --- TTA ---
USE_TTA = True # Test-Time Augmentation (4가지 변환)
# --- Power Sharpening ---
ALPHA = 1.0 # alpha > 1: 날카롭게 | 1.0: 미적용
시각화 분석

- 이번엔 탑을 잘보면 엄청 잘 보고 프론트를 못 봄.
- 그리드캠이 기존 설정과 변경되어서 일치되지 않음
개선
모델의 예측 방향 자체는 정확. (stable/unstable 구분이 잘 됨). 문제는 확률 calibration이 깨진 것과, Grad-CAM 시각화가 이 구조에 맞지 않는 것입니다.
- 수정 필요한 것:
- CLS 토큰 추가 — mean pool 대신 learnable [CLS] token을 추가해서 그 토큰만 head에 넣기 (logit 크기 안정화 + Grad-CAM이 CLS→패치 attention으로 더 선명해짐)
- Grad-CAM → Attention Rollout 시각화 — fusion transformer의 attention weight를 직접 추출하여 "front의 어느 패치가 top의 어느 패치를 보는가" 시각화

분석
- 시각이미지(그리드캠)로 봤을 때 모든 모델 중 가장 괜찮음. 그림자도 보는 성능을 보임.
- 알파와 값 스케일링이 너무 높게 설정 되어있음 → 극단값만 시각화로 출력으로 변경
- 아래와 같은 결과.

분석
- 배경에도 시선 집중
- 100% ↔ 0% 극단적임.
- 배경에 가중치를 줄일 수 있도록 하이퍼파라미터를 수정해봐야 겠다.
- 에포크도 조정
아래는 5fold를 다 돌고 앙상블을 적용한 추론 확률 분포도이다. 어떻게 보면 eve보다 더 좋아보인다!
============================================================
앙상블 결합 (majority_best)
============================================================
모델별 val_logloss:
dinov2_large_fold0: 0.000048
dinov2_large_fold1: 0.000036
dinov2_large_fold2: 0.006798
dinov2_large_fold3: 0.000388
dinov2_large_fold4: 0.000035
투표 결과:
만장일치 unstable: 450개
만장일치 stable: 492개
분할 투표: 58개
모델별 최종 채택 빈도:
dinov2_large_fold0: 0회 (0.0%)
dinov2_large_fold1: 5회 (0.5%)
dinov2_large_fold2: 0회 (0.0%)
dinov2_large_fold3: 0회 (0.0%)
dinov2_large_fold4: 995회 (99.5%)
────────────────────────────────────────────────────────────
[앙상블 결과] 확률 분포
────────────────────────────────────────────────────────────
mean = 0.4867596569
std = 0.4959589108
min = 0.0000285929
max = 0.9999848604
median = 0.0115284566
구간별 분포:
[0.0~0.1): 505 █████████████████████████
[0.1~0.2): 1
[0.2~0.3): 6
[0.3~0.4): 0
[0.4~0.5): 0
[0.5~0.6): 1
[0.6~0.7): 1
[0.7~0.8): 8
[0.8~0.9): 1
[0.9~1.0): 477 ███████████████████████
unstable 예측 (>0.5): 488개 / 1000개
stable 예측 (≤0.5): 512개 / 1000개
Alpha=1.0 → Power Sharpening 미적용 (원본 그대로)
============================================================
제출 파일 저장 완료
============================================================
파일: submission_dinov2_large_5fold_tta_0327_1846.csv
경로: C:\Pyg\Projects\dacon\dacon-structural-stability\submissions\submission_dinov2_large_5fold_tta_0327_1846.csv
샘플 수: 1000
unstable_prob: mean=0.4867596569
unstable_prob: std =0.4962070764
예측 unstable: 488개
예측 stable: 512개
dinov2_large_fold4: 0.000035 로 가장 낮지만 실제 테스트 성능도 과연 좋을 지 검증이 필요함.
위 파일을 내일 제출(3월 28일) 예정이다. 이건 연구용 블로그로 진행 상황을 계속 추가 중이다.
내용이 길어서 블로그를 추가로 또 적어야 될 거 같다. DINOv2 성능 분석은 이 블로그를 계속 수정 예정입니다.
진행 중인 테스트 기록
기존 처음 학습 설정에 하이퍼파라미터 커스텀 변화하는 과정을 기록하려고 한다.
- 처음 설정 → WEIGHT_DECAY=0.05
- 변경: WEIGHT_DECAY =0.15
WEIGHT_DECAY는 왜 변경하는 실험을 하냐? 값을 조금 올려주면 배경에 덜 집중할 줄 알았다. 결과는 아래처럼 더 분포되는 모습이다.
기존 설정 시각화

WEIGHT_DECAY =0.15

딱 봐도 더 안 좋아 보인다. 이번엔 더 줄여봐야겠다.
DINOv2 결과 분석
사실 첫 번째 DINO 시각화를 봤을 때, 객체를 확실하게 탐지하고 배경을 완벽하게 날려버리길래 당연히 제출 결과도 좋을 줄 알았다. Val Loss도 EVA보다 훨씬 좋았으니까.
근데 막상 까보니 실제 성능은 더 안 좋았다. 왜 그랬던 것인지 두 모델의 특징과 연결해서 검증해 봤다.
1. "누끼 따기" vs "물리적 붕괴점 찾기"

DINO 결과를 보면 블록 전체에 부드럽게 시선이 덮여 있다. 즉, 무너질지 아닐지 물리적 판단을 한 게 아니라, 블록만 예쁘게 오려내는 Segmentation를 해버린 거다.

반면 EVA는 덩어리를 보는 게 아니라 블록이 꺾이는 관절 부위, 삐져나온 모서리, 무게 중심이 쏠리는 특정 핫스팟에 붉은 점이 찍힌다. 탑이 무너질지 보려면 실루엣이 아니라 이런 '구조적 결함'을 봐야 하는데, DINO는 덩어리 자체를 너무 완벽하게 인식하느라 내부의 물리적 불균형을 다 뭉뚱그려버렸다.
2. 너무 똑똑한 '배경 지우개'의 역효과
DINO는 주요 객체와 배경을 분리하는 능력이 원탑이다. 근데 이 물리 태스크에서는 그게 오히려 독이 됐다.
탑이 쓰러질지 판단하려면 바닥(체커보드)과 이루는 각도나 중력의 수직/수평 기준점 같은 '공간적 맥락'이 무의식적으로 필요하다. 근데 DINO는 "바닥 무늬는 객체가 아니니까 무시해"라며 물리적 힌트를 아예 차단해버렸다. 객체만 허공에 둥둥 뜬 상태로 기울기를 보려니 실패한 거다.
3. Val Loss의 함정 (Shortcut Overfitting)
그럼 Val Loss는 왜 DINO가 압도적으로 좋았냐?
검증 셋(Val)에는 그냥 탑의 전체적인 모양이나 너비만 대충 봐도 무너질지 통계적으로 찍어 맞출 수 있는 얕은 패턴이 있었을 거다. 실루엣 따기에 미친 DINO는 이 패턴을 완벽히 외워버려서 Loss를 쫙 낮춘 거다.
하지만 실제 Test 셋의 기괴한 붕괴 패턴(무게 중심 훼이크 등) 앞에서는 이 얕은 지식이 안 통했고, 좀 지저분해 보여도 '모서리 꺾임'을 묵묵히 찾던 EVA가 점수가 더 잘 나온 거다.
결론 및 향후 계획
시각화가 깔끔하다고 해서 모델이 태스크의 본질(물리적 균형)을 이해한 건 아니라는 걸 확실히 배웠다.
아래는 더 자세하게 내 생각이 적혀있는데 실시간(?) 연구 공부방입니다.
https://www.notion.so/32f6e129440d8023871eeca76314c94d?source=copy_link
공부방 | Notion
공모전 학습 기록 메모
www.notion.so
다음 블로그 2편을 업데이트 했습니다!! 최종 순위는 850명중 16위를 했습니다!
[공모전] Vision AI 최종 실험 개인 "연구" 블로그 (2)
2-Stage Pipeline의 이론적 기반, 실험 결과, 그리고 공모전 회고아래 블로그 상세 분석 개인 연구 블로그 1편도 있습니다. [공모전] Vision 시각화 검증 상세 분석 "개인 연구용" 블로그안녕하세요!!오
pak1010pak.tistory.com
'4. [팀] 프로젝트 및 공모전 > 4-4 구조물 안정성 물리 추론 AI 경진대회(DACON)' 카테고리의 다른 글
| [공모전] Vision AI 최종 실험 개인 "연구" 블로그 (2) (0) | 2026.03.30 |
|---|---|
| [DACON 공모전] 구조물 안정성 예측 대회: EVA-Giant Dual-View 모델과 Center Crop 추론 스터디 (2) (0) | 2026.03.21 |
| [DACON 공모전] Dinov2_large 모델 분석 및 학습 진행 상황 스터디 (0) | 2026.03.12 |