16장. AI 데이터 정제와 데이터 증강
증강 파이프라인과 주의할 점
보드게임에서 주사위를 굴려 말을 움직이면 판마다 다른 길이 나옵니다. 그런데 친구에게 "어제 그 판을 다시 해 보자"고 하려면 주사위 눈을 모두 적어 두어야 합니다. 증강도 변환마다 주사위를 굴려 걸지 말지, 얼마나 세게 걸지 정합니다. 씨앗을 고정하면 주사위 눈이 매번 같게 나와 같은 결과를 다시 만들 수 있습니다.
그림의 네 단계가 랜덤 증강의 순서입니다. np.random.default_rng(1610) 처럼 씨앗을 고정한 난수 만들개를 만들고, 변환마다 rng.random() < 확률 로 걸지 고르고, 건다면 rng.uniform 으로 각도나 밝기의 세기를 뽑습니다. 다 만든 뒤에는 격자로 띄워 이상한 사진이 없는지 눈으로 봅니다. 여기서 주사위가 난수 만들개, 주사위 눈을 적어 두는 일이 씨앗 고정입니다.
증강에서 가장 자주 하는 실수가 순서입니다. 늘린 다음 나누면 같은 사진에서 나온 형제들이 학습용과 시험용에 갈라 들어갑니다. 모델은 시험에서 "뒤집힌 형제"를 보고 쉽게 맞힙니다. 그래서 그림처럼 시험용을 먼저 떼어 두고, 남은 학습용만 늘립니다.
rng 로 확률적으로 걸기
| 코드 | 뜻 | 예 |
|---|---|---|
rng.random() | 0 이상 1 미만의 소수 하나 | 0.37 |
rng.random() < 0.5 | 절반쯤 True | 뒤집기를 절반의 사진에만 |
rng.uniform(-15, 15) | −15 이상 15 미만의 소수 하나 | 회전 각도 7.3도 |
rng.integers(-3, 4) | −3 이상 4 미만의 정수 하나(−3 ~ 3) | 색상 이동 2 |
rng.normal(0, 10, 모양) | 평균 0, 표준편차 10 인 난수 표 | 노이즈 |
짧은 예시
import numpy as np
# 같은 씨앗이면 같은 주사위 눈이 나온다
a = np.random.default_rng(1610)
b = np.random.default_rng(1610)
print([round(float(a.random()), 3) for _ in range(3)])
print([round(float(b.random()), 3) for _ in range(3)]) # 결과: 윗줄과 똑같다
# 확률 0.5 로 1,000번 굴리면 True 가 500번 안팎
rng = np.random.default_rng(1610)
hits = sum(rng.random() < 0.5 for _ in range(1000))
print(hits) # 결과: 462두 rng 는 씨앗이 1610 으로 같아서 세 숫자가 똑같이 나옵니다. 1,000번 가운데 몇 번이 True 인지는 정확히 500 이 아니라 그 근처의 숫자가 나옵니다. 교안 PC 에서는 462번이었습니다. 주사위를 600번 굴려도 1 이 꼭 100번 나오지 않는 것과 같습니다.
증강 전후 점검표
주의할 점
- 학습할 때마다 그 자리에서 새로 증강하는 방법도 많이 씁니다(딥러닝 도구 대부분이 그렇게 합니다). 이 장처럼 파일로 저장하면 결과를 눈으로 확인하기 좋고, 그 자리에서 하면 저장 공간이 들지 않습니다.
- 클래스마다 사진 수가 크게 다르면, 적은 클래스를 더 많이 늘려 맞추기도 합니다. 이 장의 프로젝트는 모든 학습용 사진에 똑같이 세 장씩 더합니다.