image augmentation 을 이용하여 훈련용 데이터 늘리기 파이썬 치트코드

  • 모델의 정확도를 높이는 방법중에는 이미지를 적당히 부풀리는 방법이 있습니다. 이를 이용해 모델을 만들어봅니다.
image augmentation

이미지 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
Using TensorFlow backend.
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]:
<matplotlib.image.AxesImage at 0x20534cc67f0>
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))
WARNING:tensorflow:From C:\Users\kohry\anaconda3\lib\site-packages\tensorflow\python\framework\op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.
Instructions for updating:
Colocations handled automatically by placer.
WARNING:tensorflow:From C:\Users\kohry\anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.
Instructions for updating:
Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.
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)
Epoch 1/10
250/250 [==============================] - 24s 98ms/step - loss: 1.3946 - acc: 0.5017 1s - loss: 1.3950
Epoch 2/10
250/250 [==============================] - 24s 97ms/step - loss: 1.3760 - acc: 0.5050
Epoch 3/10
250/250 [==============================] - 24s 98ms/step - loss: 1.3771 - acc: 0.5065
Epoch 4/10
250/250 [==============================] - 24s 98ms/step - loss: 1.3553 - acc: 0.5145
Epoch 5/10
250/250 [==============================] - 25s 101ms/step - loss: 1.3469 - acc: 0.5191
Epoch 6/10
250/250 [==============================] - 26s 103ms/step - loss: 1.3401 - acc: 0.5184
Epoch 7/10
250/250 [==============================] - 27s 106ms/step - loss: 1.3312 - acc: 0.5252
Epoch 8/10
250/250 [==============================] - 27s 110ms/step - loss: 1.3190 - acc: 0.5277
Epoch 9/10
250/250 [==============================] - 25s 99ms/step - loss: 1.3152 - acc: 0.5292
Epoch 10/10
250/250 [==============================] - 25s 99ms/step - loss: 1.3030 - acc: 0.5351
In [26]:
score = model.evaluate(test_x, test_y, batch_size = 100, verbose = 1)
10000/10000 [==============================] - 1s 63us/step
In [27]:
plt.plot(history.history['acc'])
Out[27]:
[<matplotlib.lines.Line2D at 0x20534d27ef0>]

답글 남기기