세그멘테이션 손실 함수 총정리 - CE부터 Lovász, PixelCL까지
픽셀 단위(CE, Focal)부터 영역 단위(Dice, Tversky), 경계 단위(Boundary), 특징 공간 단위(Lovász-Softmax, PixelCL, Margin-CE)까지 세그멘테이션에서 쓰는 손실 함수를 정리한다.
왜 손실 함수가 여러 개 필요한가
세그멘테이션 손실 하나로 모든 문제를 잡을 수는 없다. CE Loss는 "각 픽셀을 얼마나 정확히 맞혔는가"만 보기 때문에 클래스 크기가 불균형하면 큰 클래스에 휩쓸리고, Dice Loss는 영역 전체의 겹침만 보기 때문에 경계선이 정확한지는 신경 쓰지 않는다. 그래서 실무에서는 손실을 단독으로 쓰기보다 서로 못 보는 부분을 보완하도록 조합해서 쓴다.
CE/Focal → "각 픽셀의 클래스가 맞았는가" (확률 단위)
Dice/Tversky → "예측 영역과 정답 영역이 겹치는가" (영역 단위)
Boundary → "경계선이 정확한 위치에 있는가" (거리 단위)
Lovász → "mIoU 자체가 오르는가" (평가지표 단위)
PixelCL → "같은 클래스 특징끼리 뭉쳐 있는가" (특징 공간 단위)
Margin-CE → "클래스 간 확률 차이가 충분히 벌어져 있는가" (여유 단위)
1. 확률/분류 기반
CE Loss (Cross Entropy)
각 픽셀의 예측 확률 분포와 정답 라벨이 얼마나 다른지를 측정한다. 정답 클래스에 준 확률이 낮을수록 벌점이 커진다 - 세그멘테이션 손실의 기본값이다.
CE = -log(p_correct)
p_correct = 모델이 "정답 클래스"에 부여한 확률
-log는 확률이 1(완벽히 맞음)일 때 0, 확률이 0(완전히 틀림)에 가까워질수록 무한대로 커지는 곡선이다 - 그냥 "맞았다/틀렸다"가 아니라 "확신을 갖고 틀렸는가"까지 벌점에 반영된다.
픽셀 하나의 정답이 "forest"인데 모델이 forest=0.2, meadow=0.7로 예측
→ CE = -log(0.2) ≈ 1.61 (정답에 준 확률이 낮으므로 손실이 크다)
같은 정답에 모델이 forest=0.9로 예측
→ CE = -log(0.9) ≈ 0.11 (거의 맞았으므로 손실이 작다)
이 값을 이미지의 모든 픽셀에 대해 계산해서 평균 낸 게 최종 CE Loss다.
한계: 모든 픽셀을 동등하게 취급한다. 배경처럼 압도적으로 많은 클래스가 있으면, 그 클래스만 잘 맞혀도 손실이 낮아 보여서 소수 클래스(작은 객체) 학습이 밀린다.
Focal Loss
CE에 (1-p_t)^γ 가중치를 곱해서, 이미 잘 맞히고 있는 "쉬운" 픽셀의 손실은 0에 가깝게 줄이고 자꾸 틀리는 "어려운" 픽셀(주로 경계선 근처)에 학습을 집중시킨다.
쉬운 픽셀(p_t=0.9): (1-0.9)^2 = 0.01 → 손실 대폭 축소
어려운 픽셀(p_t=0.3): (1-0.3)^2 = 0.49 → 손실 거의 그대로
γ(감마)가 클수록 쉬운 샘플을 더 강하게 억제한다. 클래스 불균형·어려운 샘플 집중이 필요할 때 CE 대신 쓴다.
2. 영역/모양 기반
Dice Loss
픽셀 하나하나의 정답 여부를 따지지 않고, 예측 영역과 정답 영역이 얼마나 겹치는지(IoU와 비슷한 개념)를 직접 점수로 만들어 최적화한다.
Dice = 2 × |예측 ∩ 정답| / (|예측| + |정답|)
= 2×TP / (2×TP + FP + FN)
|예측 ∩ 정답|(겹치는 픽셀 수, TP)에 2를 곱하고 분모에서 두 번 세는 이유는, TP를 분모(|예측|+|정답|)에서 두 번 중복 계산한 만큼 분자에서도 2배 해서 완벽히 겹칠 때(예측=정답) 정확히 1.0이 나오게 맞추기 위해서다.
정답 면적 100px, 예측 면적 90px, 그중 겹치는 픽셀(TP) 80px
→ FP(오탐)=10, FN(누락)=20
→ Dice = 2×80 / (2×80 + 10 + 20) = 160/190 ≈ 0.842
손실로 쓸 때는 1 - Dice를 최소화한다. 배경 클래스가 아무리 커도 "영역이 겹치는 비율"만 보기 때문에 손실이 큰 클래스에 압도되지 않는다 - 클래스 불균형에 CE보다 강하다.
Tversky Loss
Dice의 일반화 버전이다. 오탐(FP)과 누락(FN)에 서로 다른 가중치(α, β)를 줄 수 있다.
Tversky = TP / (TP + α·FP + β·FN)
α=β=0.5면 Dice와 완전히 같은 식이 된다 - Tversky는 Dice에서 FP와 FN의 가중치를 분리한 확장판이다.
작은 건물 하나: 정답 30px, 모델이 10px만 맞히고 20px를 놓침(FN=20), 오탐은 없음(FP=0)
α=β=0.5 (Dice와 동일):
Tversky = 10 / (10 + 0.5×0 + 0.5×20) = 10/20 = 0.50
α=0.3, β=0.7 (누락에 더 큰 벌점):
Tversky = 10 / (10 + 0.3×0 + 0.7×20) = 10/24 ≈ 0.417
같은 예측인데도 β를 키우면 점수가 더 낮게(나쁘게) 나온다 - "이 정도 놓치면 훨씬 더 나쁜 상태"라고 모델에게 알려주는 셈이라, 학습이 FN을 줄이는 방향(recall을 올리는 방향)으로 더 강하게 유도된다. 작은 도로나 작은 건물처럼 miss하기 쉬운 미세 객체를 놓치지 않도록 recall을 강조할 때 β>α로 설정한다.
3. 엣지 기반
Boundary Loss
GT 마스크 하나로부터, 모든 픽셀에 대해 "이 픽셀이 정답 경계선에서 몇 px 떨어져 있는가"를 미리 계산한 **거리 지도(signed distance map, φ)**를 만들어둔다. 경계 안쪽은 음수, 바깥쪽은 양수로 부호를 주는 게 일반적이다.
Boundary Loss ≈ Σ_pixel φ(pixel) × p_wrong(pixel)
φ(pixel) = 그 픽셀이 경계에서 떨어진 거리(부호 포함)
p_wrong = 모델이 오답 클래스에 부여한 확률
같은 확률로 틀리더라도 φ 값(거리)이 클수록 곱해지는 벌점이 커진다.
경계에서 1px 떨어진 곳에서 오답 확신 0.6 → φ=1 × 0.6 = 0.6 (작은 벌점)
경계에서 10px 떨어진 곳에서 오답 확신 0.6 → φ=10 × 0.6 = 6.0 (큰 벌점, 있을 수 없는 오류이므로)
영역 내부는 다소 부정확해도 괜찮으니, 경계선 자체를 날카롭게 만드는 데 집중하는 손실이다. 다만 거리 지도가 있어도 애초에 모델의 특징 해상도가 낮으면(예: ViT 계열 백본처럼 1/16로 다운샘플된 뒤 그 해상도로 끝까지 가는 구조) 경계를 그릴 "캔버스" 자체가 흐릿해서 Boundary Loss만으로는 한계가 있다 - 고해상도 특징을 별도로 공급하는 구조 개선이 선행돼야 효과가 난다. Dice·CE와 함께 보조 손실로 흔히 쓴다.
4. 기타
Lovász-Softmax Loss
세그멘테이션의 최종 평가 지표인 mIoU는 교집합·합집합 같은 집합 연산으로 정의되어 있어서, 픽셀 하나의 예측이 살짝 바뀌어도 IoU가 계단식으로만 변한다 - 미분(gradient)이 정의되지 않는다. 그래서 학습 중에 mIoU 자체를 직접 손실로 쓸 수 없었다.
Lovász-Softmax는 이렇게 접근한다: 각 픽셀의 예측 오차(정답 확률과 1의 차이)를 구한 뒤, 오차가 큰 순서대로 픽셀을 정렬하고, IoU 손실의 볼록 완화 버전인 Lovász extension을 그 정렬된 오차열 위에 적용해 매끄러운(구간별 선형인) 근사 곡선을 만든다.
1. 픽셀별 오차 계산 (예: 1 - 정답 클래스 확률)
2. 오차가 큰 픽셀부터 정렬
3. 정렬된 순서 위에서 Jaccard(IoU) 손실의 기울기를 구간별로 근사
이 근사 곡선은 어디서나 미분 가능하면서도, 원래의 IoU 손실과 극값(가장 좋을 때/나쁠 때)이 일치하도록 설계되어 있다 - 그래서 "mIoU와 가장 가까운 방향으로 직접 최적화"가 가능해진다. 정렬·구간 계산이 들어가서 CE·Dice보다 연산이 무겁다.
PixelCL (Pixel-wise Contrastive Learning)
지금까지의 손실은 전부 "정답 라벨과 예측이 얼마나 맞는가"를 봤다면, PixelCL은 라벨을 거치지 않고 픽셀들의 특징 벡터(embedding) 사이의 거리를 직접 교정한다. 같은 클래스에 속한 픽셀들의 특징은 특징 공간에서 서로 가깝게 끌어당기고(attract), 다른 클래스의 특징은 멀리 밀어낸다(repel) - 대조 학습(Contrastive Learning)의 표준 형태인 InfoNCE 손실을 픽셀 단위로 적용한 것이다.
기준 픽셀(anchor) 하나를 고르고:
같은 클래스 픽셀(positive) 1개 이상
다른 클래스 픽셀(negative) 여러 개
를 뽑아 코사인 유사도를 계산한다.
Loss = -log( exp(sim(anchor,positive)/τ) / Σ exp(sim(anchor, 전체)/τ) )
τ(온도, temperature)는 유사도 값을 얼마나 예민하게 반응시킬지 조절한다 - τ가 작을수록 "확실히 가까운 것"과 "그냥저냥 가까운 것"의 차이가 손실에 크게 반영돼서, 모델이 더 엄격하게 클래스를 분리하도록 학습된다.
라벨 자체가 다소 부정확한 경계선 영역에서도, 특징 공간 단위로 뭉쳐두면 개별 픽셀 라벨 노이즈에 덜 흔들린다는 장점이 있다 - 라벨 하나가 틀려도 그 주변 다수 픽셀과의 관계로 보정되기 때문이다.
Margin-CE
CE는 "정답 클래스 확률이 가장 높기만 하면" 손실이 0에 가까워진다. Margin-CE는 여기에 여유(margin) 조건을 추가한다 - 정답 클래스의 확률(또는 로짓)이 다른 클래스보다 최소 margin만큼은 확실하게 커야 손실이 0이 된다.
일반 CE: 정답 확률이 1등이기만 하면 충분
Margin-CE: 정답 확률(로짓) - 2등 확률(로짓) ≥ margin 이어야 손실 0
정답 forest 로짓 2.1, 2등 meadow 로짓 2.0 (margin=0.5 설정 시)
→ 차이 0.1 < margin 0.5 → 아직 부족한 만큼 손실 발생, 더 벌어지도록 학습 유도
같은 상황에서 forest 로짓 2.6, meadow 로짓 2.0
→ 차이 0.6 ≥ margin 0.5 → 손실 0, 이미 충분히 벌어져 있음
일반 CE라면 첫 번째 경우도 "정답이 1등"이므로 손실이 거의 0에 가까워 학습이 멈춰버린다. Margin-CE는 "1등이긴 한데 근소한 차이"인 상태를 계속 벌점 대상으로 남겨둬서, 색상·반사 특성이 비슷한 클래스(예: 숲과 초지)끼리 확률이 근소한 차이로 뒤집히는 걸 막고 클래스 사이에 확실한 완충 지대를 만든다.
정리
| 손실 | 보는 단위 | 강점 | 약점 |
|---|---|---|---|
| CE | 픽셀 확률 | 기본값, 구현 단순 | 클래스 불균형에 약함 |
| Focal | 픽셀 확률(난이도 가중) | 어려운 픽셀에 집중 | 하이퍼파라미터(γ) 튜닝 필요 |
| Dice | 영역 겹침 | 클래스 불균형에 강함 | 경계 정확도는 못 봄 |
| Tversky | 영역 겹침(FP/FN 비대칭) | 미세 객체 누락 방지 | α/β 튜닝 필요 |
| Boundary | 경계까지 거리 | 경계선을 날카롭게 | 단독 사용 어려움(보조 손실용) |
| Lovász-Softmax | mIoU 근사 | 평가지표와 직접 연결 | 계산 복잡, 느림 |
| PixelCL | 특징 공간 거리 | 라벨 노이즈에 강함 | 추가 연산·메모리 필요 |
| Margin-CE | 클래스 간 여유 | 비슷한 클래스 오분류 방지 | margin 값 튜닝 필요 |
실무에서는 이 중 목적이 다른 손실 2~4개를 가중합해서 쓴다 - 다음 글(위성영상 토지피복 분류 개선기)에서 실제 프로젝트에 이 손실들을 어떻게 조합했는지 다룬다.