0

셀럽미: 닮은 아이돌 찾기 2024년 맞이 업데이트 (3/3) – 모델학습과 발행

셀럽미: 닮은아이돌 찾기 서비스( https://celebme.net ) 의 2024년 맞이 업데이트의 마지막 이야기 입니다.
지난 글에서는 이미지 수집 과정과 얼굴 영역 크롭 과정을 담았습니다.
* 이전 글 (1/3) – 이미지 수집 : https://celebme.net/blog/?p=688
* 이전 글 (2/3) – 얼굴영역 크롭: https://celebme.net/blog/?p=869

얼굴 분류 모델 학습

셀럽미: 닮은 아이돌 찾기 서비스의 핵심은 얼굴을 분류해내는 모델을 사용한 것입니다.
기존에는 구글의 Teachable Machine 을 활용해 web ui 에서 간단하게 이미지 분류 모델을 구현했었다면,
현재는 Tensorflow Lite Model Maker 를 활용해 비교적 간단한 코드로 직접 모델을 학습하고 있어요.
이미지를 수집한 이후에 위 페이지에 해당하는 튜토리얼을 따라하면 손쉽게 이미지 학습을 진행해볼 수 있어요!

Tensorflow Lite Model Maker 학습 준비

모델 학습을 위해 필요한 준비물은 아래와 같습니다.

  • GPU 가 탑재된 linux 머신을 기동
  • nvidia driver 세팅
  • 학습할 이미지 목록을 저장
  • Tensorflow lite Image Maker 설치
  • Tensorflowjs converter 설치
  • Tensorflow Hub에서 참고할 이미지 분류 모델 확인

위 과정 중에서 위의 세가지는 건너뛰고, Tensorflow Lite Image Maker 설치는 간단하게 아래와 같이 진행할 수 있어요.
위의 Tensorflow 공식 가이드를 참고하셔도 됩니다.

pip install tflite-model-maker

그리고 셀럽미:닮은아이돌 찾기 (https://celebme.net) 서비스는 javascript 로 모델을 클라이언트에서 확인하기 때문에 모델을 javascript로 변환하여 전달해야 합니다.
이 과정을 도와줄 Tensorflowjs converter를 사용하기 위해 tensorflowjs 패키지를 설치합니다. 관련 Tensorflow의 공식 가이드를 참고하셔도 좋습니다.

pip install tensorflowjs==2.8.4

Tensorflow Hub 이미지 분류 Pretrained 모델 확인

이미지 분류 모델을 Tensorflow 를 사용해서 직접 구현하는 방법도 있는데요.
이미 공개된 성능 좋은 모델을 차용해서 쓰면 빠르고 효율적인 모델을 쉽게 생성해낼 수 있습니다.
이를 Pre-trained 모델 이라고 하는데요.
이미 학습이 어느정도 된 모델에 추가적으로 데이터를 얹어서, 적은 데이터에 대한 학습만으로도 정확도가 높은 모델을 생성할 수 있습니다.
공개된 모델 목록을 Tensorflow hub ( https://tfhub.dev )에서 확인해봅니다.

이제 tensorflow hub가 Kaggle Model로 통합되었네요.
저희는 이미지 분류를 할 예정이니, Task 에서 Image Classification을 선택해줍니다.

Hotest, 가장 핫한 순서대로 모델 목록을 확인할 수 있는데요.
image classification 으로 봤을 때 Keras의 모델 보다는 Google의 efficientnet_v2가 Variation이 많고, Upvote도 많은걸 확인할 수 있습니다.

Google 의 efficientnet_v2 를 들어가볼까요? https://www.kaggle.com/models/google/efficientnet-v2

구글이 설명하듯이, EfficientNet V2 가 학습 속도가 굉장히 빠르고, 파라미터 수도 다른 모델 대비 월등히 적다는걸 확인할 수 있습니다.

셀럽미:닮은 아이돌 찾기 (https://celebme.net) 서비스에서는
파라미터 수를 많이해서 정확도를 늘리기 보다는
적당한 모델 크기를 사용해서 일정 수준 이상의 정확도를 얻고자 했어요.
그래서 ImageNet-1K 모델을 사용하면서, 이미지 크기 300px 에 맞는 EfficientNet V2 B3 모델을 사용하기로 했습니다.
모델은 classification 과 feature_vector 두가지가 있는데요.
Tensorflow 의 튜토리얼을 따라가보면, pretrained model 에 이미지로 분류기를 재학습시키기 위해서는 feature_vector를 사용해야하는 것을 알 수 있습니다.
* classification 튜토리얼: https://www.tensorflow.org/hub/tutorials/image_classification?hl=ko
* feature_vector 튜토리얼: https://www.tensorflow.org/hub/tutorials/tf2_image_retraining?hl=ko

따라서, Efficientnetv2 B3 300 – feature_vector 을 눌러서 Model Variation 을 확인해볼게요.

그럼 Usage 에서 저 모델 Spec을 다운로드할 수 있는 URI를 볼 수 있는데요.
모델 학습에서 사용하기 위해 해당 URI 를 복사해줍니다.

이제 모델 학습에 사용할 Pretrained 모델 준비가 끝났습니다.

얼굴분류 모델 학습

이제 얼굴분류 모델 학습을 위해 python 코드를 작성해줍니다.
남자/여자 두가지 모델을 생성할텐데요.
코드상 폴더명 차이밖에 없어서, 남자 모델 기준으로 아래와 같습니다.

import os

import numpy as np
import tensorflow as tf

assert tf.__version__.startswith("2")

import matplotlib.pyplot as plt
from tflite_model_maker import image_classifier, model_spec
from tflite_model_maker.config import ExportFormat, QuantizationConfig
from tflite_model_maker.image_classifier import DataLoader

epoch = 200
# spec = model_spec.get('efficientnet_lite4')
spec = image_classifier.ModelSpec(
    uri="https://www.kaggle.com/models/google/efficientnet-v2/frameworks/TensorFlow2/variations/imagenet1k-b3-feature-vector/versions/2"
)
spec.input_image_shape = [300, 300]
bsize = 20


image_path = "/home/terry/code/celebme/celebme_model_202401/faces/men/"
data = DataLoader.from_folder(image_path)
train_data, test_data = data.split(0.9)

model = image_classifier.create(
    train_data,
    epochs=epoch,
    model_spec=spec,
    train_whole_model=False,
    validation_data=test_data,
    batch_size=bsize,
    dropout_rate=0.3,
    # learning_rate=0.01,
    # use_augmentation=True,
)


print("exporting saved_model..")
model.export(export_dir=image_path + "model_saved_model", export_format=ExportFormat.SAVED_MODEL)
print("exporting label..")
model.export(export_dir=image_path + "model_label", export_format=ExportFormat.LABEL)

print("exporting model..")
model.export(export_dir=image_path + "model_default")


loss, accuracy = model.evaluate(test_data)

print(f"loss, accuracy: {loss}, {accuracy}")

위 코드는 튜토리얼 코드를 거의 대부분 그대로 가져왔습니다.
* Tensorflow Lite Model Maker 에서 이미지 분류 튜토리얼 : https://www.tensorflow.org/lite/models/modify/model_maker/image_classification

위 코드는 Default Quantization을 사용하는데요.
셀럽미: 닮은 아이돌 찾기 (https://celebme.net) 서비스에 사용되는 모델 크기를 가능한 한 줄이기 위함입니다.
Quantization 에 대해서는 튜토리얼상의 이 부분을 참고해보셔도 좋습니다.
* 튜토리얼 : https://www.tensorflow.org/lite/models/modify/model_maker/image_classification#customize_post-training_quantization_on_the_tensorflow_lite_model
* quantzation 설명페이지: https://www.tensorflow.org/lite/performance/post_training_quantization

위의 코드로 학습을 실행해보면 아래와 같은 진행상황을 볼 수 있습니다.


Keras Model Hub에서 다운로드받은 Pretrained Model Spec을 기준으로 로드에 성공했고, 학습을 잘 진행하고 있는 모습입니다.

모델 학습 결과 Metric 확인

위의 코드로 모델을 학습해보면 GPU 장비의 스펙에 따라 다른 속도로 모델이 학습될텐데요.
저는 노트북의 작고 작은 gpu를 사용해서 학습에 소요된 시간이 꽤 긴 편입니다.
최종적으로는 아래와 같이 accuracy 0.56, val_accuracy 0.36 수준의 스코어로 학습된걸 확인할 수 있었습니다.

이 정확도는 실제적으로는 얼굴사진을 입력 받을 때 약 1/3 수준으로 정확하게 맞춘다고 볼 수 있는 수준입니다.
얼굴 분류 모델의 input 이 해당 연예인들이 아닌 일반인들의 다양한 사진을 입력으로 받을 텐데요~
이 정확도 값이 높은게 중요하기 보다는 얼굴의 특징들이 들어올 때 해당 특징을 가진 아이돌을 잘 찾아가는지가 중요한 지표가 될 수 있습니다.
해당하는 지표로서 위 결과를 이해하면 좋을 것 같아요.
위의 모델 학습 결과물을 셀럽미 사이트 (https://celebme.net) 에 반영해서, 현재 사용자들은 신규 모델로 추론한 결과를 보실 수 있습니다.

셀럽미 모델 한계점과 개선 사항

현재의 셀럽미는 모델 학습을 통해 클라이언트 장비에서 모델 추론을 해서, 사용자의 사진을 외부 네트웍으로 전송하는 단계는 없는 상태인데요.
이러다보니 클라이언트 장비에 들어갈만큼 모델이 작아야하는 한계점이 존재합니다.
이런 한계점을 개선하려면 일반적인 웹서비스와 유사하게 클라이언트-서버 모델을 사용해볼 수 있는데요.


서버에서 모델을 사용해 사용자 입력데이터를 통해 추론한 결과를 클라이언트에 내려주는 방식은 모델이 크거나, 클라이언트 장비에서 구동할 수 없을 때 특히 용이합니다.
이와 같이 개선한 셀럽미를 추가 사이트로 오픈하려는 계획을 하고 있는데요~
이렇게 되면 지금보다도 훨씬 더 그럴싸한 결과물을 내는 닮은 아이돌 찾기 서비스를 오픈할 수도 있을것 같네요.
개선된 사이트를 기대해주세요!!

셀럽미 모델 업데이트 마무리

이번엔 2024년 맞이 셀럽미 모델 업데이트를 진행하면서 모델 학습과 추론에 어떤 코드를 사용했는지 자세히 알아보는 포스팅을 작성해봤는데요~
해당 내용이 어떤 분께든 도움이 되셨다면 좋겠습니다.
앞선 포스팅을 하단에 링크합니다.

지난 글에서는 이미지 수집 과정과 얼굴 영역 크롭 과정을 담았습니다.