AI로 연예인 닮은꼴 예측 프로그램을 만들어보자!



📍 연예인 닮은 꼴 AI 예측 프로그램




Python
%cd 'drive/MyDrive/Colab Notebooks/23.12.20딥러닝'


📌 딥러닝 라이브러리 로드


Python
# 라이브러리 로딩
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm # 진행율을 시각화 해주는 도구 (파이썬에서 몇 번 반복했는지 쉽게 볼 수 있음)
from tensorflow.keras.utils import image_dataset_from_directory # 폴더에서 이미지를 불러오는 도구

# 훈련/평가용 데이터 분리 함수
from sklearn.model_selection import train_test_split # 훈련/평가용 데이터 분리 함수

# 이미지 특징을 추출하는 도구
from tensorflow.keras.applications import InceptionV3 # 이미지 특징을 추출하는 도구

# 신경망모델 import
from tensorflow.keras.models import Sequential # 딥러닝 모델의 뼈대
from tensorflow.keras.layers import Dense # 뉴런의 묶음을 표현하는 클래스 뉴런을 이용해서 모델을 만들때 성능은 좋지만 최대한 가볍게 만들어야함
from tensorflow.keras.callbacks import EarlyStopping # 조기학습 중단 비효율으로 시간을 낭비하지 않게 함
from tensorflow.keras.callbacks import ModelCheckpoint # 모델자동저장 과대적합을 피하기 위해 미리 자동으로 저장

# 예측과 평가
from tensorflow.keras.models import load_model # hdf5 포멧의 모델파이를 로딩하는 함수
from sklearn.metrics import classification_report # 분류 평가지표 확인 함수
from tensorflow.keras.optimizers import Adam #Adam의 learning rate를 수정가능함
from tensorflow.keras.preprocessing.image import ImageDataGenerator# 이미지 자체에 효과를 주는 도구



📌 데이터 수집하기


JavaScript
# 네이버 이미지 크롤링 JavaScript
let imgs = document.querySelectorAll(".image_tile_bx img")
let imgArrData = new Array();

for(i=0; i<imgs.length; i++){
    let s = imgs[i].src;
    if(s=='') s = imgs[i].getAttribute('data-src');
    imgArrData.push(s);
}

var blob = new Blob([imgArrData], {type: "text/csv"});
var url = window.URL.createObjectURL(blob);
var anchor = document.createElement("a");
anchor.href = url;
anchor.download = "demo.csv";
anchor.click()



📌 CSV 파일로 사진 다운로드


Python
# jupyter notebook 사용
import pandas as pd 
import urllib.request as req
from tqdm import tqdm

# .T는 가로가아닌 세로로 바꾸는 용어
pdyeo= pd.read_csv("./data/demoyu.csv", header=None, ).T

for index, url in tqdm(enumerate(pdyeo.values)) : #enumerate 반복문을 돌리면서 인덱스도 붙이는 함수  .values 는 url만 가져옴
    # print(index, url[0])
    try:
        filename = f'./data/face/yeo/{index}.jpg'
        req.urlretrieve(url[0],filename)
    except :
        continue # 예외 발생시 계속해서 진행



📌 데이터셋 만들기


Python
total_data = image_dataset_from_directory(
    directory = "./data/face/",
    labels = "inferred",
    label_mode = "categorical",
    color_mode = "rgb",
    image_size = (224,224)
)

X_data = []
y_data = []

for img, label in tqdm(total_data.as_numpy_iterator()):
  X_data.append(img)
  y_data.append(label)
  
X_numpy = np.concatenate(X_data)
y_numpy = np.concatenate(y_data)
X_numpy.shape , y_numpy.shape

np.savez("./data/face.npz", X=X_numpy, y=y_numpy)


  • X_data 학습용
  • y_data 정답용


📌 모델 만들기


Python
# 저장된 데이터셋 로드
npz_data = np.load("./data/face.npz")
X_numpy = npz_data['X']
y_numpy = npz_data['y']
X_numpy.shape, y_numpy.shape

plt.imshow(X_numpy[1].astype("int64")) # 사진 확인

gen= ImageDataGenerator(rotation_range=90,
                        horizontal_flip=True,
                        zoom_range=5.0,
                        width_shift_range=10.0)

# 효과를 만들고 face_model.fit(gen.flow(X_train, y_train) 으로 튜닝을 한다.
# validation_data = (X_test, y_test))도 넣어줘야함

# 학습용 데이터 나누기
X_train,X_test,y_train,y_test = train_test_split(X_numpy, y_numpy,
                                                 test_size=0.2,
                                                 random_state=1219)
                                                 
# 이미지 특징 데이터 전처리
ImageEmbedding = InceptionV3(
    include_top = False,
    weights="imagenet",
    input_shape=(224,224,3), # 이미지 특징을 추출할 데이터의 크기(모양)
    pooling='avg'
)

# 딥러닝 모델 생성

face_model = Sequential() # 뼈대 생성
face_model.add(ImageEmbedding) # 이미지 특징추출 도구 연결
face_model.add(Dense(units=128, activation='relu')) # Dense -> 뉴런의 묶음 units에 숫자 바꿔도됨
face_model.add(Dense(units=256, activation='relu')) # Dense -> 뉴런의 묶음 원하는 만큼 뉴런 생성
face_model.add(Dense(units=128, activation='relu')) # Dense -> 뉴런의 묶음
face_model.add(Dense(units=3, activation='softmax')) # Dense -> 뉴런의 묶음 마지막은 같아야함

# 모델 컴파일
face_model.compile(loss="categorical_crossentropy", # 모델의 잘못된 정도(오차)를 측정하는 도구
                     optimizer=Adam(learning_rate=0.0001), # 모델 최적화 도구 -> 경사하강법 알고리즘
                     metrics=['accuracy']) # 모델의 평가지표)

# 모델 조기 학습완료
early = EarlyStopping(monitor="val_accuracy",
                      patience=5)

# 모델 자동저장
model_path = "./face_model/face-{epoch:02d}-{val_accuracy:.2f}.hdf5"
mdckp = ModelCheckpoint(filepath = model_path,
                        save_best_only=True,
                        monitor="val_accuracy")

# 모델 학습
h = face_model.fit(X_train, y_train,
                   validation_split = 0.2,
                   epochs=100,
                   callbacks=[early,mdckp],
                   batch_size=16)



📌 닮은꼴 예측하기


Python
# 제일 좋은 모델 로드
best_face_model = load_model("./face_model/face-13-0.80.hdf5")

# 예측하기
pre = best_face_model.predict(X_test)

print(classification_report(y_test.argmax(axis=1),
                            pre.argmax(axis=1)))



예측률과 재현율이 비슷하게 잘 나온 것 같지만 아주 정확하게는 예측이 안 되는 것 같아요.
데이터양을 늘리면 학습이 더 잘 될 것 같아요.


📌 실제 사진으로 예측하기


Python
import gradio as gr

# 예측 알고리즘 함수
def my_predict(input_img) :
  input_img = input_img.reshape(1,224,224,3) # 1장의 사진을 4차원으로 만들어줌
  pre = face_model.predict(input_img).flatten() # 모델예측
  class_names = ['gang', 'song', 'yeo']
  return {class_names[i]: float(pre[i]) for i in range(3)}

demo = gr.Interface(my_predict, # 연결된 함수의 return 값을 화면에 연결
                    inputs= gr.Image(shape=(224,224)), # 생성될 입력 인터페이스 설정
                    outputs=gr.Label(num_top_classes=3)) # 생성될 출력 인터페이스 설정
demo.launch(share=True)