2019년 6월 5일 수요일

Keras와 CoLab을 활용한 간단한 딥러닝 모델 훈련, 모델 저장 및 재사용

딥러닝 개발은 코딩보다는 딥러닝 환경 설과 데이터 구축에 많은 노력이 들어간다. 예를 들어, 딥러닝 환경설정은 무한 삽질로 빠지는 경우가 있다. 우분투, 텐서플로우(tensorflow), 케라스(keras) 등의 설정은 GPU와 궁합이 잘 맞지 않을 경우 우분투부터 여러번 설치해야 할 수 있다. 딥러닝 학습 모델에 필요한 데이터셋을 모으고 라벨링하는 작업은 정말 피곤한 일이다. 이후, 라벨링 된 데이터셋을 얻은 후에도 딥러닝 모델 학습에 맞게 구조화하는 작업도 귀찬은 것이다. Keras는 이런 일을 단순화시켜주는 기능을 제공한다.

이 글에서는 딥러닝 환경설정은 구글의 CoLab을 사용해 삽질을 하지 않는다. Keras의 ImageDataGenerator는 수집한 데이터 파일들을 폴더에 다음과 같이 넣어 두면, 폴더명을 라벨로 사용해 각 데이터 파일에 라벨링을 자동으로 처리한다.
trainset/cats
         /dogs
testset/cats
         /dogs
이 글은 CNN모델을 학습할 때 좀 더 손쉬운 학습 데이터를 준비, 훈련, 저장 및 재사용 방법을 간략히 정리한다. CNN모델 소스코드는 이 링크를 참고하였다. CNN모델 자체에 대한 설명은 여기를 참고한다.

머리말
이 글은 데이터 준비 및 훈련 방법에만 초점을 맞추기 위해, Cat, Dog 이미지 데이터를 사용한다. 딥러닝 도구는 keras의 CNN을 사용할 것이다.

데이터 준비
우선 다음 압축파일을 다운로드 받는다. 이 파일 안에는 구글에서 얻은 고양이와 개 이미지 파일들을 훈련용 8000개, 테스트용 2000개 가지고 있다.
CoLab 서버에 훈련 데이터셋을 업로드하기 위해, 압축파일을 풀고 dataset 폴더를 별도 zip 파일으로 압축한다. 참고로, 이 데이터셋 구조는 다음 그림과 같다.
딥러닝 데이터셋 구조

CoLab에 접속해 python3 파일을 하나 새로 만든다.
그리고, 다음과 같이 CoLab의 파일 업로드 함수를 이용해 CoLab 서버에 압축한 zip파일을 전송한다.

from google.colab import files
uploaded = files.upload()

참고로 CoLab은 우리가 구글에서 임시로 빌려쓰는 클라우드 서버기 때문에 사용하지 않고 일정 시간이 지나면 자동으로 끊어지고 업로드한 데이터도 사라질 수 있다. 그래서, 학습한 모델은 바로 로컬에 다운로드받거나 구글 드라이브에 옮겨 놓는 것이 좋다. 

다음 명령을 CoLab에서 실행해, 업로드한 압축파일을 푼다. 라벨링은 압축 해제된 폴더 이름에 따라 ImageDataGenerator의 flow_from_directory함수에서 자동으로 처리될 것이다.

!unzip dataset.zip

코딩 및 실행
CoLab 을 열고, 다음과 같이 코딩하고 실행한다. 참고로, 이 딥러닝 모델의 구조는 Data(64, 64, 3)-Conv(64, 64, 3)-MaxPooling(2, 2)-Conv-MaxPooling(2, 2)-Flatten-Dense(128)-Dense(1) 이다.

# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Convolution2D(32, 3, 3, input_shape = (64, 64, 3), activation = 'relu'))  # Convolution2D(filter number, filter row, filter col, input_image(x, y, channel), activate function)

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))  # max pooling row, col

# Adding a second convolutional layer
classifier.add(Convolution2D(32, 3, 3, activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Step 3 - Flattening
classifier.add(Flatten())  # 2D -> 1D network

# Step 4 - Full connection
classifier.add(Dense(output_dim = 128, activation = 'relu'))   # Dense(output weight link number, activation function)
classifier.add(Dense(output_dim = 1, activation = 'sigmoid'))

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

# Part 2 - Fitting the CNN to the images

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('training_set',
                                                 target_size = (64, 64),
                                                 batch_size = 32,
                                                 class_mode = 'binary')

test_set = test_datagen.flow_from_directory('test_set',
                                            target_size = (64, 64),
                                            batch_size = 32,
                                            class_mode = 'binary')

classifier.fit_generator(training_set,
                         samples_per_epoch = 8000,
                         nb_epoch = 25,
                         validation_data = test_set,
                         nb_val_samples = 2000)

그럼 다음과 같이 모델이 훈련되는 것을 확인할 수 있다.
학습된 결과

분류 예측
구글에서 얻은 고양이나 강아지 사진을 random.jpg 로 저장하고, 앞서 파일을 올린 방식과 같이 CoLab 서버에 파일 업로드한다. 그리고, 다음 코드를 CoLab에 입력해 실행해 본다.

import numpy as np
from keras.preprocessing import image
test_image = image.load_img('random.jpg', target_size = (64,64))
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = classifier.predict(test_image)
training_set.class_indices
if result[0][0] >= 0.5:
  prediction = 'dog'
else:
  prediction = 'cat'
print(prediction)

그럼, 다음과 같이 훈련된 딥러닝 모델이 적용 예측 결과가 표시될 것이다.
예측 결과

훈련된 딥러닝 모델 저장
이제 훈련된 딥러닝 모델을 다음 명령을 이용해 저장한다.
from keras.models import load_model

classifier.save('DL_CNN_cat_dog.h5')

from google.colab import files
files.download('DL_CNN_cat_dog.h5')  # from colab to browser download

훈련된 딥러닝 모델 불러와 사용하기
저장된 딥러닝 모델은 다음과 같이 간단히 로딩해 사용할 수 있다.
from keras.models import load_model
model = load_model('DL_CNN_cat_dog.h5')

똑같은 예측 소스코드로 실행해 보면 동일한 결과를 확인할 수 있다.
import numpy as np
import matplotlib.pyplot as plt

from keras.preprocessing import image
test_image1 = image.load_img('random4.jpg', target_size = (64,64))
test_image2 = image.img_to_array(test_image1)
test_image2 = np.expand_dims(test_image2, axis = 0)
result = model.predict(test_image2)
training_set.class_indices
if result[0][0] >= 0.5:
  prediction = 'dog'
else:
  prediction = 'cat'

origin_image = image.load_img('random4.jpg')
plt.imshow(origin_image)
print('  => predict = ', result[0][0], ', class = ', prediction)

로딩된 모델을 이용한 예측 결과

참고로 저장된 모델은 스마트폰, 웹 기반 앱에서 로딩해 사용할 수 있다. 관심이 있다면 다음 링크를 참고한다.


이 예제의 폴더 구조만 약간 변경하면 다양한 분야에서 CNN기반 딥러닝 모델 학습을 할 수 있다.

레퍼런스

댓글 없음:

댓글 쓰기