- 모델의 정확도를 높이는 방법중에는 이미지를 적당히 부풀리는 방법이 있습니다. 이를 이용해 모델을 만들어봅니다.
이미지 Augmentation을 통해 정확도를 높이기¶
- ImageDataGenerator를 이용해 쉽게 이미지를 늘릴수 있다.
In [1]:
from keras import backend
from keras.datasets import cifar10
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.optimizers import SGD, Adam, RMSprop
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import matplotlib.pyplot as plt
In [2]:
backend.set_image_dim_ordering("tf")
In [3]:
(train_x, train_y), (test_x, test_y) = cifar10.load_data()
train_x = train_x.astype('float32') / 255
test_x = test_x.astype('float32') / 255
train_y = np_utils.to_categorical(train_y, 10)
test_y = np_utils.to_categorical(test_y, 10)
generator 세팅 (좌우반전 및 옆으로 눕히기 등 옵션 설정)¶
In [4]:
image_generator = ImageDataGenerator(
rotation_range = 45,
width_shift_range = 0.25,
height_shift_range = 0.25,
zoom_range = 0.25,
horizontal_flip=True,
fill_mode = 'nearest',
)
이미지 Augmentation 을 통해 뒤틀린 이미지를 저장¶
- num_aug에 해당하는 파라미터를 늘리면, 한 이미지당 뒤틀린 이미지들을 여러개 생성가능하다.
- 또한 save_to_dir 과 같은 옵션으로 경로를 주면 로컬 컴퓨터에 저장도 가능하다
In [5]:
xtas, ytas = [], []
for i in range(train_x.shape[0]):
num_aug = 0
x = train_x[i]
x = x.reshape((1,) + x.shape)
for x_aug in image_generator.flow(x, batch_size = 1) :
if num_aug >= 1:
break
xtas.append(x_aug[0])
num_aug += 1
- 아래와 같이 뒤틀린 이미지가 생성된다
- 다만 로컬에 저장하는 방법은 뭔가 버그가 있는듯해 보인다. (만개이상 저장불가)
In [25]:
from pylab import imread
import matplotlib.pyplot as plt
image = imread('augmentation/cifar_0_23.jpeg')
plt.imshow(image)
Out[25]:
In [6]:
def build(input_shape):
model = Sequential()
model.add(Conv2D(32, (3,3), padding = 'same', input_shape=input_shape))
model.add(Activation('relu'))
model.add(Dropout(0.25)) # Dropout
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(64, (3,3), padding = 'same'))
model.add(Activation('relu'))
model.add(Dropout(0.25)) # Dropout
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5)) # Dropout
model.add(Dense(10))
model.add(Activation('softmax'))
return model
In [7]:
model = build(input_shape=(32,32,3))
In [8]:
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
In [9]:
image_generator.fit(train_x)
모델훈련¶
- 메모리에서 로딩하는 방식이 아니라 굉장히 늦을 수 있다.
- steps_per_epoch를 유니크한 이미지 사이즈인 50000을 주면 정확도는 상승하지만, 시간은 굉장히 느려진다
- multiprocessing, worker 파라미터를 적극적으로 써서 보완 가능한것으로 보인다.
In [11]:
history = model.fit_generator(image_generator.flow(train_x, train_y, batch_size=200), steps_per_epoch=train_x.shape[0]/200, epochs=10, verbose=1)
In [26]:
score = model.evaluate(test_x, test_y, batch_size = 100, verbose = 1)
In [27]:
plt.plot(history.history['acc'])
Out[27]: