오늘은 CNN 2일차로 CNN 코드 구조 복습과 이미지 데이터가 적을 때 데이터를 늘리는 방법에 대해 학습했습니다.
어제에 이어 오늘도 CNN구조에 대해 복습을 했습니다. CNN이란 computer vision을 좀 더 효과적으로 분류하기 위해 사용된 구조입니다.
원본인 Input Layer에서 fitter을 통해 feature map을 뽑아 냅니다. CNN을 진행하면 파라미터수가 증가하게 되는데 이 공식은 ((필터사이즈(3*3)*depth(컬러일경우:3))+ 1) * 필터의 수(제작하려는 feature map의 수)의 연산을 가집니다. max_pooling 같은 경우는 단순히 feature map의 사이즈만 줄이는 역할을 하고 파라미터의 수나 depth 수에는 관여하지 않습니다.
스케일링을 해주는 이유는 각 feature간의 영향력을 균등하게 해주기 위함과 모델의 최악의 학습을 방지하고자 하는 이유입니다. BatchNormalization()도 같은 이유로 Batch에 대해 정규화를 진행해줍니다.
전날에 포스팅에서 sparse_categorical_crossentropy이 자동으로 원-핫 인코딩도 진행해줬다 했는데 해당 포스팅은 잘못되었습니다. 원-핫 인코딩을 자동으로 진행해서 loss값을 가져오는 것은 맞지만 원-핫 인코딩을 자동으로 진행해서 y에 대해 적용해주지는 않습니다.
지금까지 진행한 CNN의 데이터들은 모두 5만건 혹은 6만건이나 되는 방대한 양의 데이터를 가지고 진행했습니다. 하지만 실무에서는 그런 방대한 양의 데이터를 가지고 있기란 매우 힘듭니다. 따라서 최대한 수집한 데이터를 가지고 해당 데이터를 돌리거나 확대, 축소하여 데이터를 늘려보면 어떨까 라는 생각을 바탕으로 만들어진 해결책이 바로 Data Augmentation입니다.
ImageDataGenerator 패키지를 사용해서 한정된 이미지를 상화좌우 반전, 확대, 축소 등등의 작업을 진행해서 여러 이미지 데이터를 생성해주는 증강 기술입니다.
먼저 해당 실습은 keras에서 제공하는 Cifar100데이터를 사용했습니다.
정규화와 원-핫 인코딩이 되어있다는 가정하에 Data Augmentation부터 모델링까지 진행하겠습니다.
▶Data Augmentation
먼저 데이터들을 ImageDataGenerator패키지를 활용해서 여러 이미지 데이터로 바꿔서 저장해보겠습니다.
datagen = ImageDataGenerator(rotation_range=30, zoom_range=0.2, width_shift_range=0.1,
height_shift_range = 0.1, horizontal_flip=True, vertical_flip=True)
datagen.fit(x_train)
train_gen = datagen.flow(x_train, y_train, batch_size=128)
여기서 먼저 ImageDataGenerator에 사용된 옵션들을 살펴보겠습니다.
rotation_range =
은 이미지를 몇도까지 돌릴지에 대해서 설정해줄 수 있습니다.
zoom_range =
는 확대 크기를 설정해주는 옵션입니다.
width_shift_range =
는 가로 방향의 이동 범위를 정해주는 옵션입니다.
height_shift_range =
는 세로 방향의 이동 범위를 정해주는 옵션입니다.
horizontal_flip =
는 가로 방향 뒤집기 허용 여부입니다.
vertical_flip =
는 세로 방향 뒤집기 허용 여부입니다.
이제 이를 통해 datagen이라는 객체가 만들어 진 것입니다. 이를 실제로 실행해주기 위해서는 .flow()
를 사용해줍니다.
그 전에 datagen.fit(x_train)
을 사용했는데 여기서 .fit()
은 학습하고자할 때 사용하는 fit이 아닙니다. 어떤 데이터로 제너레이팅을 할 것인지 알려주는 역할을 합니다.
마지막으로 flow에 어떤 데이터를 넣을지에 대한 train_gen = datagen.flow(x_train, y_train, batch_size=128)
선언을 이렇게 해줍니다.
Data Augmentation 전체적인 사용방법은 위와 같습니다. 이제 데이터 증강 작업을 끝내면 다음으로는 모델링 작업을 해줍니다.
▶모델링
import tensorflow as tf
from tensorflow import keras
keras.backend.clear_session()
model = keras.models.Sequential()
model.add(keras.layers.Input(shape=(32,32,3)))
model.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.Conv2D(filters=64, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.MaxPool2D(pool_size=(2,2)))
model.add(keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.Conv2D(filters=128, kernel_size=(3,3), padding='same', activation='relu'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(256, activation = 'relu'))
model.add(keras.layers.Dense(128, activation = 'relu'))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Dropout(0.25))
model.add(keras.layers.Dense(100, activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy, metrics=['accuracy'], optimizer='adam')
model.summary()
모델링은 기본 CNN과 같은 형식입니다.
▶모델 학습
다음으로는 Early Stopping으로 과적합을 막아주겠습니다.
from keras.callbacks import EarlyStopping
es = EarlyStopping(monitor='val_loss', patience=8, verbose=1, min_delta=0, restore_best_weights=True)
model.fit(train_gen, callbacks=[es], verbose=1, epochs=5000, validation_data=(x_val, y_val))
원래는 train_x, train_y의 값을 넣어주었다면 증강 작업일 경우에는 앞서 만들어둔 train_gen을 사용해서 모델 학습을 시작합니다.
▶모델 평가
model.evaluate(x_test, y_test)
오늘은 증강 작업과 CNN에 대해서 같이 학습했습니다.
※공부하고 있어 다소 틀린점이 있을 수 있습니다. 언제든지 말해주시면 수정하도록 하겠습니다.
※용어에 대해 조금 공부 더 해서 수정하겠습니다.