케라스 CIFAR10 을 이용한 드랍아웃 적용 CNN 파이썬 치트코드

  • 드랍아웃은 보통 정확도에서 어느정도의 상승을 가져올수 있기 때문에, 요즘에는 필수적으로 구현하게 됩니다. 드랍아웃은 일부러 신경망을 끊기 때문에 오버피팅을 막을수 있지만, 때에 따라서는 정확도에 큰 상승이 없기도 합니다.
cifar dropout

CIFAR10 이미지로 인식하는 딥러닝

  • 이번에는 드롭아웃을 적용해서 정확도가 얼마나 상승하는지 살펴보겠습니다.
  • 데이터는 기본적인 벤치마크셋인 CIFAR10 입니다.
  • 보통 일반적인 방법으로 90%정도를 도달할수 있고, 현존하는 벤치마크 99%까지 가능합니다.
In [56]:
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
import numpy as np
import matplotlib.pyplot as plt
In [32]:
backend.set_image_dim_ordering("tf")

데이터셋 로드

In [33]:
(train_x, train_y), (test_x, test_y) = cifar10.load_data()
In [57]:
fig = plt.figure(figsize=(20,5))
for i in range(36):
    ax = fig.add_subplot(3, 12, i + 1, xticks=[], yticks=[])
    ax.imshow(np.squeeze(train_x[i]))
In [34]:
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)
In [35]:
train_x.shape
Out[35]:
(50000, 32, 32, 3)

간단한 네트워크를 일단 하나 생성합니다.

In [36]:
def build(input_shape):
    model = Sequential()
    model.add(Conv2D(32, (3,3), padding = 'same', input_shape=input_shape))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2,2)))
    model.add(Flatten())
    model.add(Dense(512))
    model.add(Activation('relu'))
    model.add(Dense(10))
    model.add(Activation('softmax'))
    return model
In [37]:
model = build(input_shape=(32,32,3))
In [38]:
model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_3 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
activation_7 (Activation)    (None, 32, 32, 32)        0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 16, 16, 32)        0         
_________________________________________________________________
flatten_3 (Flatten)          (None, 8192)              0         
_________________________________________________________________
dense_5 (Dense)              (None, 512)               4194816   
_________________________________________________________________
activation_8 (Activation)    (None, 512)               0         
_________________________________________________________________
dense_6 (Dense)              (None, 10)                5130      
_________________________________________________________________
activation_9 (Activation)    (None, 10)                0         
=================================================================
Total params: 4,200,842
Trainable params: 4,200,842
Non-trainable params: 0
_________________________________________________________________
In [39]:
model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
In [40]:
history = model.fit(train_x, train_y, batch_size=256, epochs=10, validation_split=0.2, verbose=1)
Train on 40000 samples, validate on 10000 samples
Epoch 1/10
40000/40000 [==============================] - 5s 129us/step - loss: 1.7101 - acc: 0.4032 - val_loss: 1.3884 - val_acc: 0.5237
Epoch 2/10
40000/40000 [==============================] - 4s 108us/step - loss: 1.2991 - acc: 0.5420 - val_loss: 1.2926 - val_acc: 0.5434
Epoch 3/10
40000/40000 [==============================] - 4s 111us/step - loss: 1.1889 - acc: 0.5808 - val_loss: 1.2232 - val_acc: 0.5738
Epoch 4/10
40000/40000 [==============================] - 4s 105us/step - loss: 1.1108 - acc: 0.6110 - val_loss: 1.1519 - val_acc: 0.5954
Epoch 5/10
40000/40000 [==============================] - 4s 110us/step - loss: 1.0358 - acc: 0.6399 - val_loss: 1.1149 - val_acc: 0.6152
Epoch 6/10
40000/40000 [==============================] - 4s 94us/step - loss: 0.9782 - acc: 0.6595 - val_loss: 1.1306 - val_acc: 0.6043
Epoch 7/10
40000/40000 [==============================] - 4s 92us/step - loss: 0.9209 - acc: 0.6799 - val_loss: 1.0809 - val_acc: 0.6186
Epoch 8/10
40000/40000 [==============================] - 4s 93us/step - loss: 0.8708 - acc: 0.6969 - val_loss: 1.0760 - val_acc: 0.6273
Epoch 9/10
40000/40000 [==============================] - 4s 108us/step - loss: 0.8248 - acc: 0.7154 - val_loss: 1.1051 - val_acc: 0.6188
Epoch 10/10
40000/40000 [==============================] - 4s 100us/step - loss: 0.7740 - acc: 0.7326 - val_loss: 1.0571 - val_acc: 0.6374
In [41]:
score = model.evaluate(test_x, test_y, batch_size = 256, verbose = 1)
10000/10000 [==============================] - 0s 36us/step

정확도 확인

  • 정확도가 상승하는 그래프를 보면 여지가 분명 많은것을 확인할 수 있습니다.
In [42]:
print("최종 정확도 : " + str( score[1] * 100 ) + " %" )
최종 정확도 : 63.27 %
In [52]:
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
Out[52]:
[<matplotlib.lines.Line2D at 0x184018b1940>]

드랍아웃 적용 및 계층 쌓기

In [47]:
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

model_dr = build(input_shape=(32,32,3))
model_dr.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy'])
history_dr = model_dr.fit(train_x, train_y, batch_size=256, epochs=10, validation_split=0.2, verbose=1)
score_dr = model_dr.evaluate(test_x, test_y, batch_size = 256, verbose = 1)
print("최종 정확도 : " + str( score_dr[1] * 100 ) + " %" )
Train on 40000 samples, validate on 10000 samples
Epoch 1/10
40000/40000 [==============================] - 6s 156us/step - loss: 1.7287 - acc: 0.3714 - val_loss: 1.4995 - val_acc: 0.5105
Epoch 2/10
40000/40000 [==============================] - 5s 131us/step - loss: 1.3295 - acc: 0.5225 - val_loss: 1.3714 - val_acc: 0.5577
Epoch 3/10
40000/40000 [==============================] - 5s 128us/step - loss: 1.1914 - acc: 0.5793 - val_loss: 1.1823 - val_acc: 0.6160
Epoch 4/10
40000/40000 [==============================] - 5s 130us/step - loss: 1.1007 - acc: 0.6098 - val_loss: 1.1159 - val_acc: 0.6436
Epoch 5/10
40000/40000 [==============================] - 5s 128us/step - loss: 1.0313 - acc: 0.6384 - val_loss: 1.0695 - val_acc: 0.6528
Epoch 6/10
40000/40000 [==============================] - 5s 126us/step - loss: 0.9584 - acc: 0.6618 - val_loss: 1.0582 - val_acc: 0.6554
Epoch 7/10
40000/40000 [==============================] - 5s 128us/step - loss: 0.9104 - acc: 0.6768 - val_loss: 0.9801 - val_acc: 0.6662
Epoch 8/10
40000/40000 [==============================] - 5s 129us/step - loss: 0.8608 - acc: 0.6964 - val_loss: 0.9384 - val_acc: 0.6860
Epoch 9/10
40000/40000 [==============================] - 5s 129us/step - loss: 0.8219 - acc: 0.7103 - val_loss: 0.9727 - val_acc: 0.6665
Epoch 10/10
40000/40000 [==============================] - 5s 127us/step - loss: 0.7824 - acc: 0.7236 - val_loss: 0.8793 - val_acc: 0.7093
10000/10000 [==============================] - 0s 44us/step
최종 정확도 : 70.17999999999999 %

정확도 상승 확인

  • 앞으로도 꾸준히 정확도가 상승할수 있는 여지도 계속 보입니다.
  • epoch를 조금 더 높이고, 레이어를 추가한다면 계속 정확도가 높아질수 있습니다.
In [51]:
plt.plot(history_dr.history['acc'])
plt.plot(history_dr.history['val_acc'])
Out[51]:
[<matplotlib.lines.Line2D at 0x18401864c18>]

답글 남기기