어린이의 그림을 통해 창의성을 판단하는 딥러닝 모델을 제작해보았다.
1. 필요 라이브러리 임포트
import numpy as np
import pandas as pd
import tensorflow as tf
import os
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Flatten, Dropout
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
코드 실행에 필요한 라이브러리와 모듈을 가져온다. numpy와 pandas는 데이터 조작을 위해, tensorflow는 모델 구축 및 훈련을 위해 사용하였다. os 모듈은 파일 시스템 경로와 상호 작용하는데 사용되며, ImageDataGenerator는 이미지 데이터 전처리 및 증강을 위해 사용하였다.
2. csv 파일 및 이미지 경로 지정
data1 = pd.read_csv('C:/Users/user/Desktop/agics/Painting_Creativity_Tester_01.csv')
data2 = pd.read_csv('C:/Users/user/Desktop/agics/Painting_Creativity_Tester_02.csv')
data = pd.concat([data1, data2], ignore_index=True)
image_dir = 'C:/Users/user/Desktop/agics/images/'
data['image_path'] = [os.path.join(image_dir, f"{f}.png") for f in data['filename']]
두 개의 CSV 파일을 불러와 하나의 데이터프레임으로 병합한다. 각 이미지의 파일 경로를 생성하여 데이터프레임에 추가합니다. 이는 나중에 이미지 데이터를 모델에 공급할 때 사용한다.
3. 훈련, 테스트 데이터 증강 설정
train_df, test_df = train_test_split(data, test_size=0.2, random_state=42)
train_datagen = ImageDataGenerator(
rescale=1./255, #픽셀 값 0~1, 255로 나누어 정규화
rotation_range=20, #이미지를 -20~20도 사이로 무작위 회전
width_shift_range=0.2, #이미지를 수평방향으로 최대 20%까지 무작위 이동
height_shift_range=0.2, #이미지를 수직방향으로 최대 20%까지 무작위 이동
shear_range=0.2, #이미지를 시계 반대 방향으로 최대 20%까지 전단 변형
zoom_range=0.2, #이미지를 80~120% 크기로 무작위 확대/축소
horizontal_flip=True, #이미지를 수평 방향으로 뒤집을 수 있는 옵션
fill_mode='nearest' #이미지의 빈 공간을 채우는 방식 / 가장 가까운 픽셀 값을 사용
)
test_datagen = ImageDataGenerator(rescale=1./255)
전체 데이터를 훈련 세트와 테스트 세트로 나눈다. 이 비율은 테스트 세트를 전체의 20%로 설정한다. 이후 훈련 데이터와 테스트 데이터에 대한 이미지 데이터 증강 설정을 정의한다. 훈련 데이터는 회전, 이동, 전단, 확대/축소, 수평 뒤집기 등 다양한 변형을 적용하여 모델의 일반화 성능을 향상 및 과적합을 방지한다.
4. 데이터 생성기 설정 및 딥러닝 모델 구성
train_generator = train_datagen.flow_from_dataframe(
train_df, #훈련 데이터 프레임
x_col='image_path', #이미지 파일의 경로 / 열
y_col=['delicate', 'Expressive', 'Color variety', 'Utilize space', 'Technical skills'],
#레이블 데이터의 열의 이름을 배열 형태로 지정
target_size=(224, 224), #이미지 크기 조절
batch_size=32, #한 번에 네트워크에 공급될 이미지의 수
class_mode='raw' #데이터를 원래의 형태로 사용
)
test_generator = test_datagen.flow_from_dataframe(
test_df,
x_col='image_path',
y_col=['delicate', 'Expressive', 'Color variety', 'Utilize space', 'Technical skills'],
target_size=(224, 224),
batch_size=32,
class_mode='raw'
)
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
#VGG16 모델 사용 / fully connected layers를 포함하지 않음 / 모델 크기
base_model.trainable = False #가중치 동결
x = Flatten()(base_model.output) #1D 벡터로 평탄화
x = Dense(256, activation='relu')(x) #256개의 유닛을 가진 완전 연결층 추가 / relu 활성화 함수 비선형성
x = Dropout(0.5)(x) #50%의 비율로 무작위로 뉴런의 비율 0 설정
predictions = Dense(5, activation='linear')(x) #최종 출력 층 추가 / 5개의 예측 값 반환, linear 선형 변환
model = Model(inputs=base_model.input, outputs=predictions) #최종 모델 생성
훈련 및 테스트 데이터 생성기를 설정한다. VGG16을 기반 모델로 사용하여 새로운 모델을 구성합니다. 여기서는 이미지넷으로 사전 훈련된 가중치를 사용하고, 상위 층은 포함하지 않는다. 추가적으로 완전 연결 층과 드롭아웃 층을 포함하여 새로운 예측 층을 추가한다.
5. 모델 컴파일, 훈련, 평가 및 저장
model.compile(optimizer=Adam(learning_rate=0.0001), loss='mse')
history = model.fit(
train_generator, #이미지와 레이블 데이터 불러옴
validation_data=test_generator, #테스트 데이터 검증 데이터로 사용
epochs=100, #100번 학습
verbose=1 #진행 상황 출력
)
model.evaluate(test_generator)
model.save('C:/Users/user/Desktop/agics/model/model.keras')
모델을 컴파일하고 훈련을 시작한다. 훈련 과정에서는 검증 데이터를 사용하여 모델의 성능을 평가한다. 최종적으로 모델을 평가하고 저장한다.
git : https://github.com/limhuijin/Painting_Creativity_Tester.git