NVIDIA의 Fundatmentals of Deep Learning:04 Data Augmentation 리뷰를 위한 글이다.
이전 session에서 CNN의 validation accuracy가 일정하지 않음을 확인하였다.
이를 해결하기 위해 data augmentation이라는 기법을 살펴보자.
data augmentation은 dataset의 size와 variance를 증가시키는 것을 말한다.
size를 증가시키면, training과정에서 더 많은 이미지를 제공하게 되고
variance의 증가는 학습과정에서 중요하지 않은 feature를 무시하도록 해준다.
import tensorflow.keras as kears
import pandas as pd
#csv파일에서 데이터 로드
train_df = pd.read_csv("data/asl_data/sign_mnist_train.csv")
valid_df = pd.read_csv("data/asl_data/sign_mnist_valid.csv")
#y값과 x값 분리
y_train = train_df['label']
y_valid = valid_df['label']
del train_df['label']
del valid_df['label']
x_train = train_df.values
x_valid = valid_df.values
#y값을 one-hot encoding
num_classes = 24
y_train = keras.utils.to_categorical(y_train, num_classes)
y_valid = kears.utils.to_categorical(y_valid, num_classes)
#x값 normalize
x_train = x_train/255
x_valid = x_valid/255
# CNN을 사용할 것 이므로 1D flattening이 아니라 2D reshaping해야함
#-1은 number of data를 그대로 받아들임.
x_train = x_train.reshape(-1, 28, 28, 1)
x_valid = x_valid.reshape(-1, 28, 28, 1)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import ( Dense, Conv2D, MaxPool2D, Flatten, Dropout, BatchNormalization,)
model = Sequential()
# First Convolutional layer
model.add(Conv2D(75, (3,3), strides=1, padding="same", activation="relu", input_shape=(28,28,1)))
model.add(BatchNormalization())
model.add(MaxPool2D((2,2), strides=2, padding="same"))
# Second Convolutional layer
model.add(Conv2D(50, (3,3), strides=1, padding="same", activation="relu"))
model.add(Dropout(0.2))
model.add(BatchNormalization())
model.add(MaxPool2D((2,2), strides=2, padding="same"))
# Third Convolutional layer
model.add(Conv2D(25, (3,3), strides=1, padding="same", activation="relu"))
model.add(BatchNormalization())
model.add(MaxPool2D((2,2), strides=2, padding="same"))
# Fully connected layer for Classification
model.add(Flatten())
model.add(Dense(units=512, activation="relu"))
model.add(Dropout(0.3))
model.add(Dense(units=num_classes, activation="softmax"))
keras에 ImageDataGenerator라는 image augmentation class가 있다.
data를 augmenting하기 위한 다양한 옵션들을 선택할수 있다.
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# class의 instance생성하기
datagen = ImageDataGenerator(
rotation_rage=10, #이미지를 0~180사이로 random하게 rotate.여기서는 0~10도
zoom_range=0.1, # random하게 zoom
width_shift_range=0.1, # 수평방향으로 랜덤하게 shift
height_shift_range=0.1, # 수직방향으로
horizontal_flip=True, # 수평방향으로 random하게 이미지 flip
vertical_flip=False,
)
import matplotlib.pyplot as plt
import numpy as np
batch_size=32
img_iter = datagen.flow(x_train, y_train, batch_size=batch_size)
x, y = img_iter.next()
fig, ax = plt.subplots(nrows=4, ncols=8)
for i in range(batch_size):
image = x[i] #이때 image는 (28, 28, 1)
#원래 ax는 4*8이지만 flatten을 하면 1*32짜리 1D array가 됨
# image가 28*28*1이므로 squeeze를 쓰면 1짜리 Dim.이 사라짐
# imshow내부에 28*28짜리 이미지가 넘겨짐.
ax.flatten()[i].imshow(np.squeeze(image))
plt.show()
datagen.fit(x_train)
model.compile(loss='categorical_crossentropy', metrics=['accuracy'])
우리는 한 epoch당 generator가 없었을때와 같은 수 만큼 training을 진행하고 싶다
model.fit(img_iter, epochs=10, steps_per_epoch=len(x_train)/batch_size, validation_data=(x_valid, y_valid))
model.save('asl_model')
import IPython
app = IPython.Application.instance()
app.kernel.do_shutdown(True)