화재·연기 탐지 모델은 신경망 구조보다 라벨이 성능을 좌우합니다. 경계가 모호한 옅은 연기, 빠뜨린 화염, 라벨러마다 다른 기준 — 이런 오라벨이 그대로 학습되면 현장에서 오탐(없는 불을 알림)과 미탐(있는 불을 놓침)으로 돌아옵니다. 이 안내서는 모델을 돌리기 전에 라벨 품질을 검수하는 방법입니다.
- 라벨 기준·일치도·의심 점수·클래스 분포가 서로 무엇을 검사하는지 설명할 수 있습니다.
- 같은 샘플의 라벨러 간 차이를 비교해 기준이 흔들리는 클래스를 식별할 수 있습니다.
- 자동 의심 점수와 중복 탐지를 사람 검수 후보로 사용할 수 있습니다.
- 라벨 수정 뒤 클래스 합과 학습·검증 분리 상태를 다시 검산할 수 있습니다.
라벨이 왜 구조보다 중요한가
아무리 똑똑한 수험생도 오답이 적힌 교재로 공부하면 그 오답을 정답으로 외웁니다. 라벨은 모델의 교재입니다. 교재가 틀리면 신경망이 아무리 좋아도 틀린 것을 배웁니다. 흔히 "쓰레기를 넣으면 쓰레기가 나온다"고 말하는 이유입니다.
신경망 구조를 바꾸는 일은 눈에 띄고 성취감도 있습니다. 하지만 현장 오탐·미탐의 상당수는 더 지루한 곳 — 라벨 — 에서 옵니다. 옅은 연기를 누구는 연기로, 누구는 배경으로 표시하면, 모델은 "연기가 무엇인가"에 대해 서로 모순된 신호를 받습니다. 그 혼란이 그대로 현장 성능으로 나타납니다.
그래서 학습 버튼을 누르기 전에 라벨을 먼저 점검하는 것이, 나중에 학습을 여러 번 다시 돌리는 것보다 훨씬 쌉니다. 이 안내서의 순서 — 기준 합의 → 일치도 → 의심 라벨 → 불균형 — 는 그 "학습 전 한 번의 검수"를 짜임새 있게 하는 절차입니다.
동작 원리
라벨 품질 검수는 한 점수로 정답을 판정하는 일이 아닙니다. 먼저 기준 합의문이 사람이 무엇을 같은 클래스로 볼지 정의합니다. 같은 샘플을 독립적으로 라벨한 결과를 비교하면 기준이 실제 작업에서 공유됐는지 볼 수 있습니다. 박스 겹침과 클래스 일치가 낮은 항목은 누가 틀렸다고 즉시 결정하는 대신 함께 볼 경계 사례가 됩니다.
의심 점수는 사람 라벨과 다른 신호의 차이를 이용해 검수 순서를 정합니다. 여기서 다른 신호는 모델 예측이나 2차 라벨일 수 있지만 그 자체가 정답은 아닙니다. 차이가 큰 샘플을 위로 올린 뒤 사람이 원본과 기준 문서를 보고 유지·수정·보류를 확정합니다. 수정 이유와 기준 버전을 남겨야 같은 경계 사례가 다시 나왔을 때 일관되게 처리할 수 있습니다.
마지막으로 분포와 중복을 봅니다. 클래스별 라벨 수의 합은 전체 라벨 수와 맞아야 하고, 거의 같은 프레임이 학습과 검증에 갈라져 들어갔는지 확인합니다. 이 단계는 라벨 의미가 맞는지를 대신하지 않습니다. 기준의 일관성, 의심 샘플의 내용, 데이터 분할의 독립성을 서로 다른 검사로 유지하는 것이 핵심입니다.
라벨 품질의 네 가지 적
- 오라벨 — 연기를 화염으로, 수증기를 연기로 잘못 표시
- 라벨러 간 불일치 — 같은 프레임을 사람마다 다르게 라벨
- 클래스 불균형 — 화염만 많고 연기·어려운 배경이 적어 한쪽으로 치우친 학습
- 누락·중복 — 불이 있는데 박스 없음, 또는 거의 같은 프레임이 train/val에 동시 존재
이 넷은 따로 노는 문제가 아닙니다. 라벨러 간 기준이 흔들리면(불일치) 오라벨이 늘고, 특정 클래스에 라벨이 몰리면(불균형) 그 클래스의 오라벨은 눈에 잘 띄지 않습니다. 그래서 아래 점검은 순서가 있습니다 — 먼저 사람 사이의 기준을 맞추고, 그다음 의심 라벨을 찾고, 마지막에 분포를 셉니다.
선택지와 트레이드오프
검수 질문에 맞는 방법을 고르고, 자동 결과가 확정 판정처럼 쓰이지 않게 합니다.
| 선택지 | 맞는 질문 | 장점 | 주의할 점 |
|---|---|---|---|
| 소량 교차 라벨 + 일치도 | 사람 사이의 클래스·경계 기준이 공유됐는가 | 기준 흔들림을 학습 전에 드러냄 | 점수만 올리려 하지 말고 불일치 장면을 함께 검토해야 함 |
| 의심 점수 상위 검수 | 전수 검수가 어려울 때 어디부터 볼 것인가 | 제한된 시간에 차이가 큰 후보를 우선 확인 | 모델 예측과 점수를 정답으로 간주하면 안 됨 |
| 중복·유사 프레임 탐색 | 학습·검증에 거의 같은 장면이 섞였는가 | 데이터 누수 후보를 빠르게 모음 | 비슷해도 업무상 다른 장면일 수 있어 사람 확인 필요 |
| 클래스 분포 집계 | 특정 클래스·조건이 지나치게 적은가 | 수집·검수 범위의 빈 곳을 보여 줌 | 건수 균형만 맞춰도 다양성과 정확성이 보장되지는 않음 |
라벨 기준 합의문 먼저
일치도를 재기 전에 할 일이 있습니다. 애초에 무엇을 어떻게 라벨할지 한 장으로 합의해 두는 것입니다. 기준이 글로 없으면 사람마다 다르게 그리고, 그 차이를 나중에 일치도로 발견해 봐야 이미 앞의 작업을 되돌려야 합니다.
채점 기준표(루브릭) 없이 여러 명이 채점하면 점수가 제각각인 것과 같습니다. 기준표를 먼저 나눠 주면 채점이 일관됩니다. 라벨도 마찬가지라, 짧아도 좋으니 합의문을 먼저 만듭니다.
[화염·연기 라벨 기준 합의문 v1 — 예시] - 연기: 배경이 비쳐 보이는 옅은 연무도 포함. 상자는 육안으로 연기가 사라지는 지점까지. - 화염: 불꽃과 그로 인한 발광부까지. 바닥·유리의 반사광은 제외. - 제외(배경): 주방·온수 수증기, 안개, 구름, 노을, 붉은 조명, 자동차 미등. - 애매하면: 상자를 넉넉히 치고 'uncertain' 태그를 달아 검수 후보로 남긴다. - 한 프레임에 연기·화염이 겹치면 각각 따로 상자를 친다.
이 합의문은 완성본이 아니라 살아 있는 문서입니다. 검수하다 새 경계 사례(용접 불꽃, 담뱃불 연기 등)가 나오면 규칙을 한 줄 추가하고 버전을 올립니다. 위 항목은 형식을 보여 주는 예시이니, 관할 데이터에 맞게 고쳐 쓰세요.
1. 라벨러 간 일치도(IAA)
같은 시험지를 두 선생님이 채점했는데 점수가 크게 다르면, 학생이 아니라 채점 기준이 흔들린 것입니다. 라벨도 같습니다 — 같은 프레임을 두 사람이 다르게 라벨하면, 그 클래스의 기준이 아직 사람 사이에 안 잡힌 것입니다.
같은 프레임 묶음을 두 사람이 독립으로 라벨한 뒤, 박스가 얼마나 겹치는지(IoU)로 일치율을 봅니다. 일치율이 낮은 클래스가 곧 기준이 흔들리는 클래스입니다.
def iou(a, b): # [x1,y1,x2,y2] ix1, iy1 = max(a[0], b[0]), max(a[1], b[1]) ix2, iy2 = min(a[2], b[2]), min(a[3], b[3]) inter = max(0, ix2 - ix1) * max(0, iy2 - iy1) union = (a[2]-a[0])*(a[3]-a[1]) + (b[2]-b[0])*(b[3]-b[1]) - inter return inter / union if union else 0.0 # 두 라벨러가 같은 박스로 본 비율(IoU≥0.5)을 클래스별로 집계 → 낮으면 기준 합의 필요
일치율이 낮게 나온 클래스는 그 정의를 합의문에 더 또렷이 적고, 몇 장을 함께 보며 기준을 맞춘 뒤 다시 잽니다. 점수 자체를 올리는 게 목적이 아니라, 기준이 사람 사이에 공유됐는지를 확인하는 절차입니다.
2. 의심 라벨 자동 탐지 — FiftyOne
FiftyOne은 라벨이 모델 예측과 크게 어긋나는 "의심 라벨"에 점수를 매기고, 거의 같은 중복 프레임을 찾아 줍니다. 전수 재검수 대신 의심 상위부터 사람이 봅니다.
import fiftyone as fo import fiftyone.brain as fob # dataset: 이미지 + ground_truth(사람 라벨) + predictions(모델 또는 2차 라벨) fob.compute_mistakenness(dataset, "predictions", label_field="ground_truth") fob.compute_uniqueness(dataset) # 중복·유사 프레임 탐지 # 의심도 높은 순으로 사람이 검수 suspects = dataset.sort_by("mistakenness", reverse=True).limit(50)
의심 점수가 어떻게 자동으로 나올까요? 원리는 단순합니다 — 사람이 붙인 라벨과 모델(또는 2차 라벨)의 예측이 크게 어긋나는 지점을 찾습니다. 모델은 자신 있게 "연기"라는데 사람 라벨엔 아무것도 없다면, 둘 중 하나는 틀렸을 가능성이 높습니다. 그런 프레임에 높은 점수를 매겨 사람이 먼저 보게 하는 것입니다.
수만 장을 다 다시 볼 수는 없습니다. 그래서 의심 상위부터 훑는 것이, 같은 시간에 가장 많은 오라벨을 걷어내는 방법입니다. compute_uniqueness가 찾아 주는 거의 같은 중복 프레임은 뒤의 train/val 누수 점검과 바로 이어집니다.
3. 클래스 불균형 점검
훈련에서 흔한 상황만 반복하면 드문 상황에 약해집니다. 늘 하던 유형만 훈련하고 드문 유형을 건너뛰면 정작 그 상황에서 굳는 것과 같습니다. 화염 라벨이 연기의 열 배라면, 모델은 화염엔 능하고 정작 중요한 옅은 연기엔 둔해집니다.
화염·연기·배경 비율이 한쪽으로 치우치면 모델이 흔한 클래스만 잘 맞춥니다. 비율을 세고, 합이 전체 라벨 수와 맞는지 검산합니다.
from collections import Counter counts = Counter(label for s in samples for label in s.labels) # 클래스별 라벨 수 total = sum(counts.values()) assert total == sum(len(s.labels) for s in samples), "검산 실패: 클래스 합 ≠ 전체 라벨 수" for cls, n in counts.most_common(): print(f"{cls:6} {n:6,} ({n/total:5.1%})") # 너무 적은 클래스는 수집·증강 보강
너무 적은 클래스는 그 장면을 더 모으거나(수집), 밝기·좌우반전 같은 증강으로 보완합니다. 다만 증강은 원본이 정확할 때만 도움이 됩니다 — 오라벨을 증강하면 오류만 함께 불어납니다. 그래서 불균형 보정은 앞의 오라벨 검수가 끝난 뒤에 합니다.
가상 상황: 두 라벨러, 같은 새벽 프레임
가상의 상황을 하나 들어 보겠습니다. 두 라벨러가 같은 새벽 CCTV 묶음을 나눠 맡았습니다. A는 배경이 비치는 옅은 연무를 모두 smoke로 표시하고, B는 "이 정도는 수증기"라며 배경으로 둡니다. 둘 다 성실했지만 합의문이 없었습니다.
이 데이터로 학습하면 모델은 똑같이 생긴 장면을 어떤 곳에선 연기로, 어떤 곳에선 배경으로 배웁니다 — 서로 지우는 신호입니다. 현장에선 옅은 연기 앞에서 우물쭈물하는 모델로 나타납니다.
일치도를 미리 쟀다면 smoke 클래스의 낮은 일치율로 이 문제가 학습 전에 드러났을 것이고, 합의문 한 줄("옅은 연무도 연기에 포함")로 막혔을 일입니다. 이것이 순서를 지키는 이유입니다.
가상 사례: 데이터 관리 담당자의 중복 프레임 분할 검수
다음은 라벨러 기준 사례와 다른 가상 사례입니다. 데이터 관리 담당자가 연속 영상에서 뽑은 프레임을 학습용과 검증용으로 나눴는데, 두 묶음의 검증 결과가 지나치게 비슷해 원인을 살핍니다. 입력은 공개·합성 영상에서 추출한 프레임, 출처 영상 ID, 촬영 구간, 현재 분할표입니다.
담당자는 파일명이 다르다는 이유로 독립 장면이라고 보지 않습니다. 유사 프레임 후보를 모은 뒤 출처 영상과 시간 구간을 함께 비교하고, 같은 연속 장면의 이웃 프레임이 양쪽에 갈라졌는지 확인합니다. 같은 장면으로 판단되면 개별 이미지가 아니라 출처 묶음 단위로 다시 분리하고, 변경 전후의 클래스 수를 재검산합니다.
실패 가능성은 유사도 점수가 높다는 이유로 드문 경계 사례를 모두 삭제하는 것입니다. 비슷한 프레임이 반복 수집된 것인지, 서로 다른 조건에서 우연히 닮은 것인지는 사람이 원본을 보고 결정합니다. 최종 확인자는 분할 근거와 삭제·이동 목록을 기록하고, 검증 묶음이 학습 수정에 다시 사용되지 않도록 관리합니다.
4. 검수는 후보, 확정은 사람
자동 점수는 "여기를 보라"는 후보일 뿐입니다. 화염인지 연기인지, 학습에 쓸지 뺄지는 도메인을 아는 사람이 확정합니다.
흔한 실수
- 합의문 없이 바로 라벨: 가장 흔하고 가장 비쌉니다. 절반쯤 라벨한 뒤 기준을 바꾸면 앞의 절반을 다시 봐야 합니다.
- 거의 같은 프레임이 train과 val에 갈라 들어감: 영상은 1초에 여러 장이라 옆 프레임이 거의 똑같습니다. 이게 학습·검증에 나뉘어 들어가면 검증 점수가 부풀고, 정작 현장에서만 성능이 무너집니다.
compute_uniqueness로 중복을 먼저 걷어 냅니다. - 의심 점수를 정답으로 믿기: 자동 점수는 시작점입니다. 옅은 연기·역광 같은 경계 사례는 도구가 아니라 사람이 정합니다.
- 급하게 대량으로: 라벨러가 지치면 기준이 흔들립니다. 적정량으로 나누고, 주기적으로 몇 장을 교차 검수해 기준이 유지되는지 봅니다.
사람 검토 체크리스트
- [ ] 라벨 시작 전에 클래스 기준 합의문을 만들어 공유했습니다. - [ ] 일치율이 낮은 클래스는 라벨 기준을 다시 합의했습니다. - [ ] 의심도 상위 프레임을 사람이 직접 검수했습니다. - [ ] 클래스 합이 전체 라벨 수와 일치합니다(누락 없음). - [ ] 거의 같은 프레임이 train/val에 동시에 들어가지 않았습니다. - [ ] 공개·합성 데이터로 작업했고, 실제 CCTV에 사람이 식별되면 비식별했습니다.
→ 이 검수는 화재 영상에서 화염·연기 탐지하기의 앞단계이고, 안전한 AI 운영 도구의 라벨링 도구(Label Studio·CVAT·FiftyOne)와 이어집니다.
문제 해결
| 증상 | 가능한 원인 | 처방 | 확인 |
|---|---|---|---|
| 라벨러 일치도가 반복해서 낮음 | 기준 문구가 모호하거나 경계 사례가 빠짐 | 불일치 샘플을 함께 보고 합의문에 포함·제외 기준 추가 | 새 독립 샘플에서 다시 교차 라벨해 비교 |
| 의심 상위가 한 배경 유형에 몰림 | 모델·2차 라벨이 그 배경에 편향됨 | 점수를 정답으로 쓰지 말고 유형별 표본을 사람이 검수 | 유지·수정·보류 비율과 이유를 유형별로 확인 |
| 클래스 합이 전체 라벨 수와 다름 | 누락 클래스·중복 집계·파싱 실패 | 샘플별 라벨 수와 클래스 집계를 같은 입력에서 다시 계산 | 두 계산의 차이가 0인지 확인 |
| 검증 점수는 높은데 새 영상에서 오류가 큼 | 이웃 프레임이 학습·검증에 함께 들어감 | 출처 영상·시간 구간 단위로 중복 후보를 다시 분리 | 양쪽의 출처 묶음 ID 교집합이 없는지 확인 |
자주 묻는 질문
Q. 일치도가 높으면 라벨이 모두 정확한가요?
사람들이 같은 기준을 적용했다는 신호입니다. 모두 같은 잘못된 기준을 공유할 수도 있으므로 기준 문서와 경계 사례의 내용 검토가 별도로 필요합니다.
Q. 모델과 다른 사람 라벨은 고쳐야 하나요?
차이는 검수 후보입니다. 모델이 틀릴 수도 있고 사람 라벨이 틀릴 수도 있으므로 원본과 합의문을 보고 사람이 유지·수정·보류를 결정합니다.
Q. 클래스 수를 같게 맞추면 불균형 문제가 해결되나요?
건수만 같아도 조명·거리·각도·배경 다양성이 부족할 수 있습니다. 분포 집계는 부족한 곳을 찾는 출발점이지 품질 보증이 아닙니다.
Q. 거의 같은 프레임은 모두 삭제해야 하나요?
중복 목적과 출처를 확인합니다. 학습·검증 누수를 만드는 이웃 프레임은 분리해야 하지만, 서로 다른 조건의 중요한 경계 사례를 점수만으로 삭제하지 않습니다.
핵심 정리
- 기준 합의문이 먼저이고, 일치도는 그 기준이 사람 사이에 공유됐는지 보여 줍니다.
- 자동 의심 점수와 중복 탐지는 사람이 먼저 볼 후보를 정할 뿐 정답을 확정하지 않습니다.
- 클래스 합 검산과 학습·검증 분리 검사는 라벨 의미 검토와 다른 품질 관문입니다.
- 수정 이유·기준 버전·분할 근거를 남겨야 다음 검수에서 같은 판단을 재현할 수 있습니다.
다음 단계
- 화재 영상에서 화염·연기 탐지하기 — 검수한 라벨을 학습·미탐·오탐 평가 흐름으로 넘기는 단계입니다.
- 안전한 AI 운영 도구 — 라벨링·검수 도구를 비식별·회귀·추적 관문과 함께 배치하는 방법을 봅니다.
- 예측 모델 운영, 드리프트 감지와 재학습 시점 — 배포 후 새 오류 샘플을 언제 재검수·재학습 후보로 돌릴지 연결합니다.