이때까지 딥러닝을 공부하면서 사용했던 데이터셋들은 Tensorflow에서 제공해주는 CIFAR10만 사용하였습니다.
이번에는 데이터 수집 - 전처리 - 모델링 과정으로 직접 구현해보겠습니다.
GOAL
- 직접 데이터를 크롤링하여 데이터 셋을 만들고 전처리 과정 경험
- 직접 만든 데이터를 가지고 CNN 분류 모델 구현
Preprocessing
- 남녀의 얼굴을 크롤링하고 자르는 작업을 했습니다. 이제 이 데이터 셋에 라벨링 작업을 해줘야 합니다.
one-hot 인코딩으로 [1, 0] 이면 남자, [0, 1] 이면 여자로 라벨링 했습니다.
코드)
data_dir = "/content/drive/MyDrive/Colab Notebooks/gender_classification/dataset"
categories = ["man", "woman"]
num_classes = len(categories)
# 이미지의 크기
image_w = 128
image_h = 128
# 펼치기
pixels = image_h * image_w * 3
X = []
y = []
for idx, category in enumerate(categories):
#one-hot 돌리기.
label = [0 for i in range(num_classes)]
label[idx] = 1
image_dir = data_dir + "/" + category
files = glob.glob(image_dir+"/*.jpg")
print(category, " 파일 길이 : ", len(files))
for i, f in enumerate(files):
img = Image.open(f)
img = img.convert("RGB")
img = img.resize((image_w, image_h))
data = np.asarray(img)
X.append(data)
y.append(label)
if i % 700 == 0:
print(category, " : ", f)
X = np.array(X)
y = np.array(y)
#1 0 이면 man
#0 1 이면 woman 이런식
X_train, X_test, y_train, y_test = train_test_split(X, y)
xy = (X_train, X_test, y_train, y_test)
np.save("/content/drive/MyDrive/Colab Notebooks/gender_classification/dataset/gender_data1.npy", xy)
print("ok", len(y))
- 코랩에서 dataset 안에 man과 woman의 폴더를 만들어 각각 사진을 넣어줬습니다.
- for문을 보시면 이미지를 열고 RGB로 바꾸어주며 128*128의 크기로 resize 하는 작업을 이미지 하나마다 반복하게 만들었습니다. 이 과정이 조금 오래 걸립니다.
- 이제 이 사진들에 라벨링을 하여 train과 test로 나누어 주는 split 작업을 했습니다. 그리고 결과로 npy의 파일로 저장하게 하였습니다.
결과)
Modeling
- Classification을 위한 CNN 모델 중 VGGNet16으로 선택했습니다. 그 이유는 VGGNet이 범용적이며 최소한의 분류, 즉 데이터 셋이 어떤 것이라도 어느 정도의 분류를 기대했기 때문에 선택했습니다.
- model.summry()
- 최대한 VGGNet16과 비슷하게 구현하려고 노력했습니다. 3x3 필터로 Conv 하고 BatchNorm을 한 뒤 Activation을 했으며 그 뒤에 maxpool(2x2)로 하여 반복하는 구성을 만들었습니다.
model.compile(optimizer = 'adam',
loss = 'categorical_crossentropy',
metrics = ['accuracy'])
- Adam()으로 최적화하였으며 loss 함수는 categorical_crossentropy를 사용했습니다. categorical_crossentropy를 사용한 이유는 결과가 one-hot 인코딩으로 나오는 다중 분류이기 때문에 선택했습니다.
Result
- train과 test의 accuracy와 loss
- 그래프가 이쁘게 되지는 않았지만 그래도 꾸준하게 정확도가 올라가는 것을 볼 수 있고
나름 훈련이 잘 된 것처럼 보입니다.
- train과 test에 대한 loss도 비슷하게 나오는 것을 확인할 수 있었습니다.
evaluate
model.evaluate(X_test, y_test)
15/15 [==============================] - 2s 104ms/step - loss: 0.4114 - accuracy: 0.8617
[0.41143372654914856, 0.8617021441459656]
약 86%의 정확도가 나오는 것을 확인했습니다.
test set에 대한 분류
- 강호동 님 사진을 woman으로 예측하였는데 아마 다른 얼굴이 섞여있어서 그런 게 아닐까 생각합니다.
느낀 점 및 개선점
1. 이미지 전처리는 중요하다.
처음에 얼굴을 crop 하지 않고 모델을 돌렸을 때는 70% 정도 나오며 학습이 제대로 되지 않는 것을 확인했습니다.
autocrop을 찾은 것도 얼굴만 어떻게 자르지 하면서 검색하며 나온 결과이며 실제로 얼굴을 crop 해서 학습시켰더니
성능이 86% 정확도로 향상된 것을 볼 수 있었습니다!
2. 데이터 수도 중요하다.
처음 데이터 셋은 남자 여자 얼굴 사진을 500장으로 하여 학습을 하였고 결과는 만족스럽지 않았습니다.
그래서 데이터를 두배 늘렸고 확인해본 Accuracy 10% 이상의 성능 향상이 있었습니다. 데이터의 수로 학습이 되냐 안되냐의 차이를 경험했습니다.
그러므로 남녀 얼굴을 정확하게 자르고 데이터의 수를 늘린다면 90% 이상의 정확도까지 향상할 수 있을 것이라 생각합니다.
여기까지 저의 작은 프로젝트를 마치겠습니다.
데이터셋의 중요성을 알았고 라벨링이 얼마나 힘든 건지도 깨달았습니다.
혹시나 질문이나 틀린 점이 있으면 댓글로 남겨주세요!
감사합니다 :)
'Project' 카테고리의 다른 글
PyQt5를 이용한 Data Augmentation Tool 구현 - 1 (UI 구현) (0) | 2022.07.05 |
---|---|
남녀 얼굴을 분류하는 딥러닝 모델 구현 - 4 (개선) (2) | 2021.08.25 |
남녀 얼굴을 분류하는 딥러닝 모델 구현 - 3 (개선) (0) | 2021.08.24 |
남녀 얼굴을 분류하는 딥러닝 모델 구현 - 1 (데이터 셋 만들기) (2) | 2021.08.20 |
Image to Cartoon Image (OpenCV를 이용해 만화풍 이미지 만들기) (0) | 2021.07.11 |