17장. Batch Processing 과 YOLO 데이터 준비
라벨 검사: 실수 찾기 규칙
시험지를 걷은 뒤 선생님은 채점 전에 이름 칸부터 봅니다. 이름이 빠진 답안지, 두 장 낸 학생, 명단에 없는 이름을 먼저 골라냅니다. 라벨도 학습에 넣기 전에 이런 검사를 거칩니다. 사람이 단 주석에는 반드시 실수가 섞이고, 실수는 대부분 정해진 몇 가지 꼴입니다.
그림의 네 카드가 검사의 네 갈래입니다. 첫째 카드는 주석 한 줄만 보고 알 수 있는 실수, 둘째는 클래스 이름, 셋째는 그림 파일과 주석의 짝, 넷째는 같은 줄이 두 번 나온 실수를 찾습니다. 여기서 이름이 빠진 답안지가 "주석 없는 그림", 명단에 없는 이름이 "모르는 클래스", 두 장 낸 답안지가 "중복 줄"입니다.
실수의 꼴과 고치는 법
| 실수 | 찾는 규칙 | 고치는 법(이 장의 약속) |
|---|---|---|
| 범위 밖 | x1 < 0, y1 < 0, x2 > 그림 가로, y2 > 그림 세로 | 그림 테두리에 맞춰 자른다 |
| 뒤집힌 상자 | x1 > x2 이거나 y1 > y2 | 작은 값을 x1(y1)로 바꿔 적는다 |
| 크기 0 상자 | x1 = x2 이거나 y1 = y2 | 그 줄을 지운다(클릭 한 번으로 생긴 점) |
| 모르는 클래스 | 정해 둔 이름에 없다 | 그 그림을 빼고 "다시 주석" 목록에 넣는다 |
| 중복 줄 | 모든 칸이 같은 줄이 또 있다 | 하나만 남긴다 |
| 그림 없는 주석 | 주석의 파일 이름이 폴더에 없다 | 그 줄을 지운다 |
| 주석 없는 그림 | 폴더의 그림이 주석에 한 번도 없다 | 그 그림을 빼고 "다시 주석" 목록에 넣는다 |
고치는 법은 두 갈래입니다. 자르기, 바꿔 적기, 지우기처럼 무엇이 맞는지 분명한 실수는 프로그램이 고칩니다. blot 이 bolt 인지 사람이 봐야 하는 실수와 상자가 아예 없는 그림은 데이터셋에서 빼고 사람에게 돌려보냅니다.
CLASSES = ["bolt", "nut", "washer"]
W, H = 320, 240
def check_row(cls, x1, y1, x2, y2):
"""주석 한 줄의 실수 갈래를 목록으로 돌려준다. 빈 목록이면 통과."""
found = []
if cls not in CLASSES:
found.append("모르는 클래스")
if x1 > x2 or y1 > y2:
found.append("뒤집힌 상자")
if x1 == x2 or y1 == y2:
found.append("크기 0 상자")
if min(x1, x2) < 0 or min(y1, y2) < 0 or max(x1, x2) > W or max(y1, y2) > H:
found.append("범위 밖")
return found
print(check_row("nut", 40, 60, 120, 100)) # 결과: [] → 통과
print(check_row("blot", 120, 60, 40, 100)) # 결과: 모르는 클래스, 뒤집힌 상자
print(check_row("washer", 300, 10, 329, 40)) # 결과: 범위 밖주의할 점
- 상자가 그림 테두리에 딱 붙은 것(x2 = 320)은 실수가 아닙니다. 잘린 물체를 규칙대로 그린 것입니다. 범위 밖은 320 을 넘었을 때만입니다.
- 검사가 찾는 것은 꼴이 틀린 실수뿐입니다. 상자를 엉뚱한 부품에 그렸거나 너트를 와셔로 적은 실수는 숫자만 보고는 모릅니다. 그래서 라벨을 그림에 그려 눈으로도 봅니다.