데이터 선정

데이터는 AI Hub에서 신청하면 무료로 받을 수 있는 한식이미지를 선정했고 총 15만개의 이미지 데이터 중 4000개만 사용했습니다.

(데이터 신청 시 서약서를 작성하는데 서약서에는 사용 기간을 명시해야 하고, 저는 사용기한이 6월 말까지였기 때문에 이미지를 따로 올리지 않는 점 양해바랍니다.)

 

개발 환경 및 라이브러리

개발 환경은 구글의 colab이며, 텐서플로우 케라스를 사용하였습니다.

 

코랩 환경 설정

이미지 데이터를 사용하기 때문에 이미지를 불러들일 필요가 있는데 저는 구글 드라이브에 이미지들을 올려놓고 사용했습니다. 

from google.colab import drive # 코랩 구글드라이브 연동
drive.mount('/gdrive', force_remount=True) 

* 참고로 새로 접속할 때마다 구글 드라이브와 연결해야하므로 한번 연결됐다고 주석처리하면 안됩니다. *

마운트 경로는 자신의 경로에 맞게 고쳐서 사용할 수 있습니다.

 

데이터 늘리기

또한 그냥 4000장만 사용했을 때는 데이터셋의 양이 작고 성능이 낮게 나오기 때문에 먼저 이미지들을 numpy 배열로 변환하고 ImageDataGenerator를 사용해 약 3만 7천개로 데이터를 늘렸습니다.

numpy배열 변환은 이 블로그(lsjsj92.tistory.com/357?category=792966)를 참고하였습니다. 코드를 그대로 사용한 게 아니라 저에게 맞게 변형하였기 때문에 제 코드를 올리기보단 블로그 주소를 남기는 것이 낫겠다고 생각하여 주소만 기입합니다.

ImageDataGenerator를 이용해 데이터셋을 늘리는 여러 코드들이 나와있지만 저는 이 블로그(jeongmin-lee.tistory.com/5)를 참고해서 경로와 데이터 생성 갯수만 수정해서 사용했습니다.

import numpy as np
import os
from os import listdir
from os.path import isfile, join
from PIL import Image
 
 
from google.colab import drive # 코랩 구글드라이브 연동
drive.mount('/gdrive', force_remount=True) 

 
np.random.seed(3)
 
from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img
 
 
data_datagen = ImageDataGenerator(rescale=1./255)
 
data_datagen = ImageDataGenerator(rescale=1./255,
                                   rotation_range=30, 
                                   shear_range=5.5,  
                                   # width_shift_range=0.1,
                                   # height_shift_range=0.1,
                                   zoom_range=0.,
                                   horizontal_flip=True,
                                   vertical_flip=True,
                                   fill_mode='nearest') 
 
 
filename_in_dir = [] 
 
for root, dirs, files in os.walk('/gdrive/My Drive/data/dataset/gobchang92'):
    for  fname in files:
        full_fname = os.path.join(root, fname)
        filename_in_dir.append(full_fname)
 
for file_image in filename_in_dir:
    img = load_img(file_image) 
    x = img_to_array(img)
    x = x.reshape((1,) + x.shape)
 
    i = 0
 
    for batch in data_datagen.flow(x,save_to_dir='/gdrive/My Drive/data/dataset/datagenerator/gobchang', save_prefix='gobchang', save_format='jpg'):
        i += 1
        if i > 16:
            break

 

 

CNN 구조

 

가장 단순하다고 할 수 있는 CNN 구조입니다. 코드로 작성하면 아래와 같습니다.

with K.tf_ops.device('/device:GPU:0'):
    model = Sequential()
    model.add(Conv2D(64, (3,3), padding='same', activation='relu', input_shape=(64,64,3)))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(128, (3,3), padding='same', activation='relu'))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(256, (3,3), padding='same', activation='relu'))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(512, (3,3), padding='same', activation='relu'))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(1024, (3,3), padding='same', activation='relu'))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Conv2D(2048, (3,3), padding='same', activation='relu'))
    model.add(MaxPool2D(pool_size=(2,2)))
    model.add(Dropout(0.25))

    model.add(Flatten())
    model.add(Dense(nb_classes, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

 

정확도는 5번 돌려봤을 때 95%정도가 나왔습니다.

 

'CNN' 카테고리의 다른 글

CNN 용어 정리  (0) 2020.10.03
ResNet 라이브러리 사용해보기  (0) 2020.10.03