인공지능

[Python] 그림 분석 모델 개발 일지(3) - 데이터 셋 추가

tony1724 2025. 3. 19. 17:14

오늘은 모델의 제시어 데이터를 늘리고, 추후 늘리기 쉽도록 코드를 설계해 보았다.

 

기존 제시어 데이터 로드 코드

# ----------------------
# QuickDraw 데이터 로드 (고양이, 개 각각 10000개)
# ----------------------
print("QuickDraw 데이터 로딩 중 ...")
cat_data = QuickDrawDataGroup("cat", max_drawings=config.MAX_DRAWINGS)
dog_data = QuickDrawDataGroup("dog", max_drawings=config.MAX_DRAWINGS)
cat_drawings = cat_data.drawings
dog_drawings = dog_data.drawings

# ----------------------
# NumPy 변환
# ----------------------
X_cat = [np.array(d.get_image(stroke_width=2).resize((config.IMAGE_SIZE[0], config.IMAGE_SIZE[1])).convert("L")) for d in cat_drawings]
X_dog = [np.array(d.get_image(stroke_width=2).resize((config.IMAGE_SIZE[0], config.IMAGE_SIZE[1])).convert("L")) for d in dog_drawings]

X_cat = np.array(X_cat)
X_dog = np.array(X_dog)

# 레이블 생성 (고양이=0, 개=1)
y_cat = np.zeros(len(X_cat), dtype=np.int32)
y_dog = np.ones(len(X_dog), dtype=np.int32)

# 데이터 합치기
X = np.concatenate([X_cat, X_dog], axis=0)
y = np.concatenate([y_cat, y_dog], axis=0)

 

테스트를 진행하면서 dog와 cat 두 가지 데이터만 로드해서 레이블을 생성하였는데,

이번엔 전역변수로 category 리스트를 가져와 레이블을 생성하는 코드를 작성해 보았다.

 

변경 코드

categories = config.CATEGORIES

X_list = []
y_list = []

for label_name, label_id in categories:
    data_group = QuickDrawDataGroup(label_name, max_drawings=config.MAX_DRAWINGS)
    drawings = data_group.drawings
    
    # 이미지 변환
    images = [
        np.array(d.get_image(stroke_width=2)
                 .resize((config.IMAGE_SIZE[0], config.IMAGE_SIZE[1]))
                 .convert("L"))
        for d in drawings
    ]
    
    images = np.array(images)
    labels = np.full(len(images), label_id, dtype=np.int32)
    
    X_list.append(images)
    y_list.append(labels)

# 데이터 합치기
X = np.concatenate(X_list, axis=0)
y = np.concatenate(y_list, axis=0)

 

크게 변경된 부분은 없다.!

 

전역변수 관리 파일

CATEGORIES = [
    ("cat", 0),
    ("dog", 1),
    ("bird", 2),
    ("fish", 3),
    ("horse", 4),
    ("lion", 5),
    ("monkey", 6),
    ("frog", 7),
    ("rabbit", 8)
]

근데 막상 생각해 보니 어차피 인덱스 번호로 레이블을 생성할 거면 굳이 두 번째 인자가 필요한가 싶어서 지우고 다시 만들었다.

CATEGORIES = [
    "cat",
    "dog",
    "bird",
    "fish",
    "horse",
    "lion",
    "monkey",
    "frog",
    "rabbit",
    "butterfly" # 데이터도 한개 추가
]

train_model.py

categories = config.CATEGORIES

X_list = []
y_list = []

for label_id, label_name in enumerate(categories):
    data_group = QuickDrawDataGroup(label_name, max_drawings=config.MAX_DRAWINGS)
    drawings = data_group.drawings
    
    # 이미지 변환
    images = [
        np.array(d.get_image(stroke_width=2)
                 .resize((config.IMAGE_SIZE[0], config.IMAGE_SIZE[1]))
                 .convert("L"))
        for d in drawings
    ]
    
    images = np.array(images)
    labels = np.full(len(images), label_id, dtype=np.int32)
    
    X_list.append(images)
    y_list.append(labels)

X = np.concatenate(X_list, axis=0)
y = np.concatenate(y_list, axis=0)

app.py

# ----------------------
# 저장된 모델 로드
# ----------------------
print("모델 로딩 중...")
model = keras.models.load_model(config.MODEL_PATH)
classes = [image for image in config.CATEGORIES]
print("모델 로드 완료!")

 

classes도 카테고리의 인자에 맞게 결괏값을 설정하였다.

 

테스트

우선 데이터의 수가 많이 늘어났기에 MAX_DRAWINGS=2500으로 하향조정하여 테스트해보았다.

{
    "filename": "rabbit.png",
    "predicted_class": "bird",
    "confidence": 0.6325628194251242
}

 

음.. 결과가 처참하다.

데이터 셋을 두배로 늘려보았다.

{
    "filename": "rabbit.png",
    "predicted_class": "rabbit",
    "confidence": 0.7925648093223572
}

 

데이터 셋을 두배로 늘리니 확연하게 정확도가 높아진 걸 확인하였다.

 

현재 프로젝트에 필요한 최소 제시어 수는 대략 100개로 예상하고 있다.

 

10개의 데이터에 최소 5000개는 있어야 80%에 근접한 수치가 나오는 걸로 보아,

방대한 데이터 셋 학습이 필요해 보인다.

 

다음에는 한정된 자원(하드웨어) 내에서 최대한 높은 정확도를 얻기 위한 방법을 고안할 예정이다.