결정축은 이미 있었다 - Feature Freeze・Margin Loss・Robust Loss 4단계 실험과 NIR 밴드 검증
meadow 오분류를 잡기 위해 결정축을 직접 옮겨보고(Step 0), feature를 얼린 채 head만 재학습하고(Step 1), Pairwise Margin Loss로 여백을 강제하고(Step 2), Robust Loss로 라벨 노이즈에 대응한(Step 3) 4단계 실험 기록. 그리고 NIR 밴드 추가가 분포 분석뿐 아니라 실제 세그멘테이션 성능에서도 효과적이었음을 확인한 결과.
지난 글에서는 meadow(초지)가 forest·field·ground 세 클래스 사이에 스펙트럼상 "낀" 상태라 IoU가 가장 낮다는 것(0.537)과, 그 밑에 라벨 일관성 문제까지 깔려 있다는 걸 Fisher Ratio·AUC로 확인했다. 이번 글에서는 그 진단을 바탕으로 실제로 시도한 4단계 실험(Step 0~3)과, 별도로 검증한 NIR 밴드 추가 효과·해외 데이터셋 전이 결과를 정리한다.
다시 보는 결정축: 같은 특징 공간, 세 개의 축
실험을 설계하기 전에 먼저 확인해야 했던 건 "지금 모델이 안 되는 게 특징이 안 갈려서인지, 특징은 갈리는데 결정축이 그걸 못 쓰는 것인지"였다. forest/meadow 두 클래스의 특징 벡터(34,248개 포인트, 256차원)를 놓고 세 가지 축 위에서 Fisher Ratio(클래스 간 분산/클래스 내 분산)를 각각 재봤다.
| 축 | Fisher Ratio | 의미 |
|---|---|---|
| 두 클래스 중심을 잇는 축 (centroid axis) | 0.589 | 가장 단순한 기준선 |
| 모델이 실제로 쓰고 있는 결정축 | 3.42 | 지금 학습된 head가 긋고 있는 경계 |
| 두 클래스를 가장 잘 가르는 이론적 최적 축 (LDA-optimal) | 6.58 | feature 공간이 허용하는 최댓값 |
여기에 별도로 그 feature 공간 위에 아주 단순한 선형 분류기(linear probe) 하나를 얹어서 구분시켜보면 AUC 0.964, 비선형 분류기로도 AUC 0.955가 나온다. 즉 feature 공간에서는 forest/meadow가 이미 거의 완벽하게 갈려 있다. 문제는 지금 모델의 결정축(3.42)이 그 갈라짐을 최적 축(6.58)만큼 활용하지 못하고 있다는 것 - "특징을 더 벌리는" 방향(contrastive learning 등)보다 "이미 벌어진 특징 위에 선을 더 잘 긋는" 방향이 지렛대가 크다는 뜻이다. 4단계 실험은 전부 이 3.42 → 6.58 격차를 좁히는 시도다.
Step 0. 결정축을 직접 옮겨보기 (로짓 바이어스 이동)
가장 먼저 시도한 건 가장 단순한 방법이었다 - 결정 경계 자체가 0.5(정확히는 두 클래스 로짓이 같아지는 지점) 근방에 데이터가 몰려 있다면, 그 경계를 억지로 옆으로 밀어보면 어떻게 될까.
meadow 클래스 로짓에 상수 바이어스 δ를 더해 결정 경계를 이동시키는 실험이다. 이때 δ는 train 데이터에서만 탐색하고 그 값을 val에 그대로 고정 적용했다 - val을 보면서 δ를 고르면 사실상 val에 과적합시키는 것이라 의미가 없어지기 때문이다.
| 7클래스 mIoU | meadow | forest | |
|---|---|---|---|
| 기준선 | 0.7070 | - | - |
| δ* = +0.5 적용 후 | 0.7081 (+0.0011) | +0.005 | −0.002 |
meadow는 소폭 개선됐지만 forest가 그만큼 깎여서, 전체로 보면 거의 제자리다. 결정 경계를 어느 쪽으로 옮기든, 그 경계 자체가 애매한 데이터 뭉치 한복판을 지나고 있다면 한쪽을 살리는 만큼 다른 쪽이 죽는다 - 시소처럼 움직일 뿐 겹침 자체가 줄지 않는다는 뜻이다. 결론은 "단순 bias 문제가 아니다. 결정축의 방향 자체와 클래스 간 겹침을 함께 봐야 한다" - 이 결론이 Step 1로 이어진다.
Step 1. Feature Extraction 재확인 - 트랜스포머 전체를 얼리고 head만 다시 잡기
Step 0에서 확인한 건 "경계를 옆으로 미는 것만으로는 안 된다"는 것이었다. 그렇다면 발상을 바꿔, DINOv3 ViT-L 트랜스포머 블록 전체를 freeze(dino_unfreeze=0)한 채로 decoder(UPerNet)와 분류기만 재학습시켜서, 결정축을 3.42에서 6.58 쪽으로 재조준할 수 있는지 확인했다. OHEM(경계 근처 hard negative 집중)도 함께 켰다.
결과: 효과 없음. DINOv3의 구조를 보면 이유가 드러난다 - patch embedding(16×16 conv) 이후 24개 트랜스포머 블록을 거쳐 나온 특징은 이미 고정된 표현이고, 그 위에서 decoder가 할 수 있는 일은 사실상 "이미 주어진 특징 공간 위에 선을 다시 긋는" 정도로 제한된다. 6.58은 원본 256차원 특징 공간 전체에 대해 계산한 이론적 최적치인데, freeze된 상태에서는 표현 자체가 바뀌지 않으니 decoder가 아무리 재학습돼도 그 축에 접근할 방법이 없다. 결정축의 격차(3.42→6.58)를 좁히려면 표현 자체가 움직일 여지, 즉 encoder를 어느 정도는 열어야 한다는 게 이 실패 실험이 확인해준 것이다.
Step 2. Head-Only Fine-tuning - Pairwise Margin Loss
Step 1이 "얼린 채로는 안 된다"를 확인했으니, 이번엔 다른 각도로 접근했다. forest(0)/meadow(4) 두 클래스 사이에 Pairwise Margin Loss를 추가해, 두 클래스의 로짓 차이가 일정 margin(m=1.0) 이상 벌어지지 않으면 추가로 벌점을 주도록 했다(가중치 fm_weight=0.5).
일반 CE: 정답이 1등이기만 하면 손실이 거의 0
Margin Loss: 정답 로짓 - 상대 로짓 ≥ margin(1.0) 이어야 추가 손실이 0
경계선 근처에서 아슬아슬하게(근소한 차이로) 맞히고 있는 픽셀들이 "손실이 이미 낮으니 여기서 학습이 멈춰버리는" 상황을 막고, 최소한의 여유(margin)를 갖도록 계속 압박하는 방식이다.
결과: 조금 좋아졌으나 큰 효과는 없었다. 원인은 명확하다 - 경계 근처 픽셀을 벌점으로 밀어내는 힘보다, 애초에 forest/meadow 로짓 차이가 0.4~0.6 구간(거의 반반)에 몰려 있는 데이터 자체의 양이 훨씬 크다. margin loss는 "경계에 걸친 개별 픽셀"에는 작동하지만, "경계 자체가 지나가는 자리에 원래 그만큼의 데이터가 있다"는 분포의 구조는 바꾸지 못한다.
Step 3. Robust Loss Tuning - Generalized/Symmetric Cross Entropy
Step 0~2를 거치며 드러난 공통점은, 결정 경계 근처의 애매한 데이터가 단순히 "어려운 픽셀"이 아니라 라벨 자체가 흔들리는 영역일 가능성이 크다는 것이었다(지난 글에서 확인한 meadow/field 라벨링 불일치와 같은 맥락). 그렇다면 손실 함수 쪽에서 "애매한 데이터에 너무 확신을 갖고 벌점을 주지 않는" 방향으로 접근할 수 있다.
- GCE(Generalized Cross Entropy, q=0.7): 표준 CE는
-log(p)형태라 예측이 정답에서 벗어날수록 벌점이 무한히 커진다 - 어려운 데이터나 라벨이 애매한 경계 영역을 만나면 그 벌점이 그대로 가중치에 실려 노이즈에 과적합되는 현상으로 이어진다. GCE는 여기에 절댓값 오차 계열(MAE)의 성질을 섞어, 확신을 갖기 어려운 애매한 영역의 데이터에 대해서는 손실이 무한정 커지지 않도록 위쪽을 눌러준다. - SCE(Symmetric Cross Entropy): 기존 CE(모델 예측 → 정답 기준)에, 반대 방향(정답 → 모델 예측 기준)의 항을 대칭으로 더한다. 모델이 예측과 다르게 나온 정답을 "무조건 옳다"고 보지 않고, 일정 부분 의심할 수 있는 여지를 만들어주는 구조다 - 라벨 자체가 100% 신뢰할 수 없다는 걸 손실 함수 설계에 반영하는 접근이다.
이 두 손실은 표준 CE와 달리 "확신이 서지 않는 영역에서는 벌점을 제한한다"는 공통된 방향을 갖는다. 지금까지의 실험(Step 0~2)이 전부 결정 경계의 위치나 **여유(margin)**를 건드렸다면, GCE/SCE는 접근을 바꿔 라벨 노이즈에 대한 손실 함수의 반응 자체를 조정하는 실험이다. 현재 이 조합으로 학습을 진행 중이며, meadow IoU와 Fisher Ratio(결정축) 양쪽이 실제로 움직이는지는 학습이 끝나는 대로 이어서 확인한다.
Step 0~3 정리
| Step | 접근 | 대상 | 결과 |
|---|---|---|---|
| 0 | 로짓 바이어스 이동 | 결정 경계 위치 | 소폭 개선, forest/meadow 시소 효과로 net ≈ 0 |
| 1 | Feature freeze + head 재학습 | 결정축 방향 | 효과 없음 - freeze 상태에선 표현 자체가 고정 |
| 2 | Pairwise Margin Loss | 결정 경계 여유 | 소폭 개선, 데이터 밀집도 대비 효과 제한적 |
| 3 | GCE/SCE (Robust Loss) | 라벨 노이즈 대응 | 진행 중 |
NIR 밴드 추가 - 분포에서 봤던 개선이 실제 성능으로도 이어지는가
지난 글에서 다음 단계로 꼽았던 첫 번째가 NIR 채널 추가였다. 이번에 분포 분석과 실제 세그멘테이션 결과 두 단계로 나눠 확인했다.
분포 분석: NDVI(NIR 기반 식생 지수)로 식생(forest+meadow)과 비식생(ground+building+road+water)을 가르는 분류기의 ROC-AUC는 0.769로, 단일 지표 치고는 상당히 잘 갈린다. 클래스별 raw NDVI 중앙값을 보면 water가 0.082로 나머지 클래스(0.088~0.331)와 확연히 떨어져 있는데, 이는 물이 NIR을 거의 완전히 흡수해 반사율이 뚝 떨어지기 때문이다 - NIR 채널 하나가 water 클래스를 사실상 다른 클래스와 분리해주는 셈이고, 실제로 water가 전체 클래스 중 IoU 1위(0.789)인 이유이기도 하다.
실제 세그멘테이션 결과로 확인: 분포 분석만으로는 "그래프에서 좋아 보인다"에 그칠 수 있어서, 동일한 조건에서 입력 채널만 다른 두 모델을 직접 비교했다.
| 모델 | 입력 | 7클래스 mIoU | meadow IoU |
|---|---|---|---|
| 3채널(RGB) | R,G,B | 0.7037 / 0.7052 | 0.531 |
| 4채널(RGB+NIR) | R,G,B,NIR | 0.7070 | 0.537 (+0.006) |
4채널 모델은 기존 3채널 conv 필터를 그대로 복사하고 NIR용 필터만 RGB 필터 평균값으로 초기화한 뒤 학습 가능하게 열어두는 방식(adapt_patch_embed)으로 확장했다. 결과적으로 7클래스 전체 mIoU와 meadow IoU가 모두 개선됐고, 7개 클래스 중 5개에서 최고 또는 공동 최고 성능을 기록했다. 분포 분석에서 확인한 "NIR이 특징 공간을 유리하게 벌려준다"는 신호가, 실제 추론 성능 개선으로도 재현된 것이다 - NIR 밴드 추가는 이론상의 기대가 아니라 실측으로 검증된 효과라고 결론지을 수 있다.
참고로 NDVI 자체를 5번째 채널로 별도 추가하는 것은 거의 효과가 없었다(mIoU 0.6929 → 0.6935, 사실상 오차 범위). NDVI 정보의 상당 부분이 이미 R·NIR 원본 밴드 안에 들어있기 때문에, NIR을 이미 넣은 상태에서 NDVI를 또 넣는 건 한계효용이 낮다는 뜻이다 - 개선은 "NIR을 원본 채널로 넣는 것" 자체에서 온다.
해외 데이터셋 검증
국내(KOMPSAT) 데이터로 학습한 모델이 해외 촬영분에서도 통하는지 별도로 검수했다. 검증에 쓴 데이터셋은 베트남·남미·중국·미국·이베리아반도·영국·프랑스 등 10개 지역, 200개 장면으로 구성된 해외 촬영 세트다.
| 모델 | 조건 | 해외 데이터셋 mIoU |
|---|---|---|
| 초기 모델 | zero-shot (국내 데이터만 학습) | 0.5344 |
| 초기 모델 | 해외 데이터셋으로 미세조정 | 0.6030 (+0.069) |
| 최신 모델(0.7070) | zero-shot | 0.5383 (국내 대비 −0.17) |
흥미로운 지점은, 국내 데이터에서 가장 성능이 좋은 최신 모델(mIoU 0.7070)이 오히려 해외 데이터셋에서는 zero-shot 성능이 초기 모델과 비슷한 수준(0.5383)에 머물렀다는 것이다 - 국내 데이터에 최적화될수록 해외 도메인과의 격차가 좁혀지지 않는다는 뜻이다. 원인을 클래스별로 뜯어보면 ground IoU가 0.248까지 떨어지고, ground와 forest 양쪽에서 meadow로 과잉 예측하는 경향이 갭의 핵심이었다. 반대로 water(0.80)와 building(0.66)은 국내 모델이 그대로도 잘 전이됐다 - NIR로 명확히 분리되는 클래스(water)나 형태적 특징이 뚜렷한 클래스(building)는 도메인이 바뀌어도 잘 버틴다는 뜻으로 읽힌다.
검수 과정에서 두 가지를 추가로 확인했다. 하나는 해외 데이터셋의 train/val 분할이 장면(scene) 단위가 아니라 그 장면을 자른 패치(patch) 단위로 이뤄져 있어서, 같은 장면의 다른 패치가 train과 val 양쪽에 섞여 들어갈 수 있다는 것 - 평가 지표가 실제보다 낙관적으로 나올 위험이 있어 장면 단위 재분할이 필요하다. 다른 하나는 이 200장 중 한반도를 촬영한 장면이 한 장도 없다는 것 - 국내 서비스를 목표로 한다면 국내 지역 촬영분·라벨 확보가 우선순위가 높다.
정리
이번 라운드에서 확인한 건 세 갈래다.
- 결정 경계 실험(Step 0~2)은 모두 한계가 뚜렷했다. feature 공간 자체는 이미 잘 갈려 있는데(선형 AUC 0.964), 경계 위치를 옮기거나(Step 0) 여유를 강제하는(Step 2) 접근은 시소 효과나 데이터 밀집도의 한계를 벗어나지 못했고, feature를 얼린 채 head만 손대는 접근(Step 1)은 아예 통하지 않았다. 남은 방향은 라벨 노이즈 자체에 대응하는 Robust Loss(Step 3, 진행 중)와, 근본적으로는 지난 글에서 짚은 라벨 재정제다.
- NIR 밴드는 분포 분석과 실측 성능 양쪽에서 일관되게 효과가 확인됐다 - 특히 water처럼 NIR 하나로 명확히 갈리는 클래스에서 이득이 크고, meadow처럼 여러 클래스와 겹치는 애매한 클래스에서도 소폭이지만 꾸준한 개선을 만든다.
- 국내 최적화와 해외 일반화는 같이 가지 않는다. 국내 mIoU가 오를수록 해외 zero-shot 성능이 함께 오르지 않는다는 건, 지금까지의 개선 대부분이 국내 데이터 분포에 특화된 방향이었다는 뜻이다. 해외 대응이 필요하다면 국내 성능 개선과는 별도의 트랙(도메인 적응, 지역별 미세조정)이 필요하다.
Step 3(Robust Loss)의 결론과, 그 결과가 Fisher Ratio·meadow IoU에 실제로 어떤 변화를 만드는지는 학습이 끝나는 대로 이어서 다룬다.