Deep Learning day 7 CIFAR10 ImageAugmentation

CIFAR10 Dataset 신경망으로 훈련

imports

import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import cifar10
import matplotlib.pyplot as plt

from tensorflow.keras.utils import to_categorical
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.optimizers import SGD, Adam
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, BatchNormalization, Activation, GlobalAveragePooling2D
from tensorflow.keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator
np.random.seed(42)
tf.random.set_seed(42)

데이터 적재

(train_images, train_labels), (test_images, test_labels) = cifar10.load_data()
Downloading data from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
170500096/170498071 [==============================] - 4s 0us/step
170508288/170498071 [==============================] - 4s 0us/step
print(train_images.shape, train_labels.shape)
print(test_images.shape, test_labels.shape)
print(train_images[0].shape)
(50000, 32, 32, 3) (50000, 1)
(10000, 32, 32, 3) (10000, 1)
(32, 32, 3)
class_names = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
train_labels[:10]
array([[6],
       [9],
       [9],
       [4],
       [1],
       [1],
       [2],
       [7],
       [8],
       [3]], dtype=uint8)

데이터 시각화

train_labels = np.int32(train_labels.flatten())
figure, axes = plt.subplots(figsize=(22, 10), nrows=3, ncols=8)

for i in range(3):
    for j in range(8):
        axes[i][j].imshow(train_images[(i*8)+j])
        axes[i][j].set_title(class_names[train_labels[(i*8)+j]])

데이터 전처리

train_images = np.array(train_images/255.0, dtype=np.float32)
train_labels = np.array(train_labels, dtype=np.float32)
test_images = np.array(test_images/255.0, dtype=np.float32)
test_labels = np.array(test_labels, dtype=np.float32)

train_oh_labels = to_categorical(train_labels)
test_oh_labels = to_categorical(test_labels)

train_images, valid_images, train_oh_labels, valid_oh_labels = train_test_split(
                                    train_images, train_oh_labels, test_size=0.2, random_state=42)

데이터 증강 (샘플 예시)

#data_generator = ImageDataGenerator(horizontal_flip = True)
#data_generator = ImageDataGenerator(rotation_range = 30)
data_generator = ImageDataGenerator(vertical_flip = True)

image = np.expand_dims(train_images[0], axis=0)
data_generator_iterator = data_generator.flow(image)

augmented_image = next(data_generator_iterator)

augmented_image = np.squeeze(augmented_image)
image = np.squeeze(image)

fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(6*2, 8))
axes[0].imshow(image)
axes[1].imshow(augmented_image)
<matplotlib.image.AxesImage at 0x7f4c8c88d490>

#data_generator = ImageDataGenerator(horizontal_flip = True)
#data_generator = ImageDataGenerator(rotation_range = 30)
#data_generator = ImageDataGenerator(vertical_flip = True)
#data_generator = ImageDataGenerator(zoom_range=(1.2, 1.9))
data_generator = ImageDataGenerator(horizontal_flip = True,
                                    rotation_range = 30,
                                    vertical_flip = True,
                                    zoom_range=(0.7, 0.9))

images = train_images[0:4]
data_generator_iterator = data_generator.flow(images)

augmented_images = next(data_generator_iterator)


fig1, axes = plt.subplots(nrows=1, ncols=4, figsize=(6*4, 8))
for i, image in enumerate(images):
    axes[i].imshow(image)

fig2, axes = plt.subplots(nrows=1, ncols=4, figsize=(6*4, 8))
for i, aug_image in enumerate(augmented_images):
    axes[i].imshow(aug_image)

데이터 증강

BATCH_SIZE = 32
train_generator = ImageDataGenerator(horizontal_flip = True)
train_generator_iterator = train_generator.flow(train_images, train_oh_labels, batch_size=BATCH_SIZE)

valid_generator = ImageDataGenerator()
valid_generator_iterator = valid_generator.flow(valid_images, valid_oh_labels, batch_size=BATCH_SIZE)
def build_extended_gap_model():
  tf.keras.backend.clear_session()

  input_tensor = Input(shape=(32, 32, 3))
  x = Conv2D(filters=32, kernel_size=(3, 3), strides=1, padding="same")(input_tensor)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = Conv2D(filters=64, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = MaxPooling2D(pool_size=(2, 2))(x)

  x = Conv2D(filters=128, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = Conv2D(filters=128, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = MaxPooling2D(pool_size=(2, 2))(x)
                  
  x = Conv2D(filters=256, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = Conv2D(filters=256, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  #x = MaxPooling2D(pool_size=(2, 2))(x)                 

  x = Conv2D(filters=512, kernel_size=(3, 3), strides=1, padding="same")(x)
  x = BatchNormalization()(x)
  x = Activation("relu")(x)
  x = MaxPooling2D(pool_size=(2, 2))(x) 

  # x = Flatten()(x)
  x = GlobalAveragePooling2D()(x)
  x = Dropout(rate=0.5)(x)                 
  x = Dense(300, activation="relu")(x)
  x = Dropout(rate=0.3)(x)
  x = Dense(100, activation="relu")(x)
  x = Dropout(rate=0.3)(x)
  output = Dense(10, activation="softmax")(x)

  model = Model(inputs=input_tensor, outputs=output)
  return model

모델 생성 및 컴파일

model = build_extended_gap_model()
model.summary()
Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 32, 32, 3)]       0         
_________________________________________________________________
conv2d (Conv2D)              (None, 32, 32, 32)        896       
_________________________________________________________________
batch_normalization (BatchNo (None, 32, 32, 32)        128       
_________________________________________________________________
activation (Activation)      (None, 32, 32, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 32, 32, 64)        18496     
_________________________________________________________________
batch_normalization_1 (Batch (None, 32, 32, 64)        256       
_________________________________________________________________
activation_1 (Activation)    (None, 32, 32, 64)        0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 16, 16, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 16, 16, 128)       73856     
_________________________________________________________________
batch_normalization_2 (Batch (None, 16, 16, 128)       512       
_________________________________________________________________
activation_2 (Activation)    (None, 16, 16, 128)       0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 16, 16, 128)       147584    
_________________________________________________________________
batch_normalization_3 (Batch (None, 16, 16, 128)       512       
_________________________________________________________________
activation_3 (Activation)    (None, 16, 16, 128)       0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 128)         0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 8, 8, 256)         295168    
_________________________________________________________________
batch_normalization_4 (Batch (None, 8, 8, 256)         1024      
_________________________________________________________________
activation_4 (Activation)    (None, 8, 8, 256)         0         
_________________________________________________________________
conv2d_5 (Conv2D)            (None, 8, 8, 256)         590080    
_________________________________________________________________
batch_normalization_5 (Batch (None, 8, 8, 256)         1024      
_________________________________________________________________
activation_5 (Activation)    (None, 8, 8, 256)         0         
_________________________________________________________________
conv2d_6 (Conv2D)            (None, 8, 8, 512)         1180160   
_________________________________________________________________
batch_normalization_6 (Batch (None, 8, 8, 512)         2048      
_________________________________________________________________
activation_6 (Activation)    (None, 8, 8, 512)         0         
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 4, 4, 512)         0         
_________________________________________________________________
global_average_pooling2d (Gl (None, 512)               0         
_________________________________________________________________
dropout (Dropout)            (None, 512)               0         
_________________________________________________________________
dense (Dense)                (None, 300)               153900    
_________________________________________________________________
dropout_1 (Dropout)          (None, 300)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 100)               30100     
_________________________________________________________________
dropout_2 (Dropout)          (None, 100)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                1010      
=================================================================
Total params: 2,496,754
Trainable params: 2,494,002
Non-trainable params: 2,752
_________________________________________________________________
model.compile(optimizer=Adam(0.001), loss="categorical_crossentropy", metrics=["accuracy"])

Callback 정의

checkpoint_cb = ModelCheckpoint("my_keras_model.h5", save_best_only=True, verbose=1)
early_stopping_cb = EarlyStopping(patience=10, restore_best_weights=True)
reducelr_cb = ReduceLROnPlateau(monitor="val_loss", factor=0.2, patience=5, mode="min", verbose=1)

모델 학습

history = model.fit(train_generator_iterator, epochs=40, validation_data = valid_generator_iterator, 
                    callbacks=[checkpoint_cb, early_stopping_cb, reducelr_cb])
Epoch 1/40
1250/1250 [==============================] - 69s 33ms/step - loss: 1.6697 - accuracy: 0.3661 - val_loss: 1.5103 - val_accuracy: 0.4147

Epoch 00001: val_loss improved from inf to 1.51031, saving model to my_keras_model.h5
Epoch 2/40
1250/1250 [==============================] - 41s 33ms/step - loss: 1.2406 - accuracy: 0.5588 - val_loss: 1.3535 - val_accuracy: 0.5340

Epoch 00002: val_loss improved from 1.51031 to 1.35352, saving model to my_keras_model.h5
Epoch 3/40
1250/1250 [==============================] - 41s 33ms/step - loss: 1.0276 - accuracy: 0.6456 - val_loss: 1.0576 - val_accuracy: 0.6262

Epoch 00003: val_loss improved from 1.35352 to 1.05758, saving model to my_keras_model.h5
Epoch 4/40
1250/1250 [==============================] - 41s 33ms/step - loss: 0.8996 - accuracy: 0.6964 - val_loss: 1.0652 - val_accuracy: 0.6333

Epoch 00004: val_loss did not improve from 1.05758
Epoch 5/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.7912 - accuracy: 0.7371 - val_loss: 0.9602 - val_accuracy: 0.6841

Epoch 00005: val_loss improved from 1.05758 to 0.96016, saving model to my_keras_model.h5
Epoch 6/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.6946 - accuracy: 0.7705 - val_loss: 0.7548 - val_accuracy: 0.7412

Epoch 00006: val_loss improved from 0.96016 to 0.75482, saving model to my_keras_model.h5
Epoch 7/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.6185 - accuracy: 0.7991 - val_loss: 0.6800 - val_accuracy: 0.7756

Epoch 00007: val_loss improved from 0.75482 to 0.68001, saving model to my_keras_model.h5
Epoch 8/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.5630 - accuracy: 0.8187 - val_loss: 0.5990 - val_accuracy: 0.7964

Epoch 00008: val_loss improved from 0.68001 to 0.59895, saving model to my_keras_model.h5
Epoch 9/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.5124 - accuracy: 0.8341 - val_loss: 0.5543 - val_accuracy: 0.8180

Epoch 00009: val_loss improved from 0.59895 to 0.55430, saving model to my_keras_model.h5
Epoch 10/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.4698 - accuracy: 0.8473 - val_loss: 0.5422 - val_accuracy: 0.8263

Epoch 00010: val_loss improved from 0.55430 to 0.54219, saving model to my_keras_model.h5
Epoch 11/40
1250/1250 [==============================] - 41s 33ms/step - loss: 0.4325 - accuracy: 0.8583 - val_loss: 0.6258 - val_accuracy: 0.8058

Epoch 00011: val_loss did not improve from 0.54219
Epoch 12/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.4014 - accuracy: 0.8717 - val_loss: 0.5734 - val_accuracy: 0.8166

Epoch 00012: val_loss did not improve from 0.54219
Epoch 13/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.3695 - accuracy: 0.8790 - val_loss: 0.8422 - val_accuracy: 0.7555

Epoch 00013: val_loss did not improve from 0.54219
Epoch 14/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.3399 - accuracy: 0.8922 - val_loss: 0.7281 - val_accuracy: 0.7848

Epoch 00014: val_loss did not improve from 0.54219
Epoch 15/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.3122 - accuracy: 0.9000 - val_loss: 0.5195 - val_accuracy: 0.8397

Epoch 00015: val_loss improved from 0.54219 to 0.51950, saving model to my_keras_model.h5
Epoch 16/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.2912 - accuracy: 0.9064 - val_loss: 0.6766 - val_accuracy: 0.7882

Epoch 00016: val_loss did not improve from 0.51950
Epoch 17/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.2659 - accuracy: 0.9140 - val_loss: 0.5408 - val_accuracy: 0.8324

Epoch 00017: val_loss did not improve from 0.51950
Epoch 18/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.2493 - accuracy: 0.9204 - val_loss: 0.5160 - val_accuracy: 0.8492

Epoch 00018: val_loss improved from 0.51950 to 0.51603, saving model to my_keras_model.h5
Epoch 19/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.2327 - accuracy: 0.9256 - val_loss: 0.4951 - val_accuracy: 0.8503

Epoch 00019: val_loss improved from 0.51603 to 0.49510, saving model to my_keras_model.h5
Epoch 20/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.2177 - accuracy: 0.9298 - val_loss: 0.5274 - val_accuracy: 0.8418

Epoch 00020: val_loss did not improve from 0.49510
Epoch 21/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.1981 - accuracy: 0.9363 - val_loss: 0.6076 - val_accuracy: 0.8332

Epoch 00021: val_loss did not improve from 0.49510
Epoch 22/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.1963 - accuracy: 0.9377 - val_loss: 0.5382 - val_accuracy: 0.8510

Epoch 00022: val_loss did not improve from 0.49510
Epoch 23/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.1703 - accuracy: 0.9435 - val_loss: 0.7370 - val_accuracy: 0.8130

Epoch 00023: val_loss did not improve from 0.49510
Epoch 24/40
1250/1250 [==============================] - 41s 32ms/step - loss: 0.1681 - accuracy: 0.9460 - val_loss: 0.6896 - val_accuracy: 0.8192

Epoch 00024: val_loss did not improve from 0.49510

Epoch 00024: ReduceLROnPlateau reducing learning rate to 0.00020000000949949026.
Epoch 25/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0943 - accuracy: 0.9689 - val_loss: 0.4544 - val_accuracy: 0.8888

Epoch 00025: val_loss improved from 0.49510 to 0.45440, saving model to my_keras_model.h5
Epoch 26/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0685 - accuracy: 0.9786 - val_loss: 0.5023 - val_accuracy: 0.8877

Epoch 00026: val_loss did not improve from 0.45440
Epoch 27/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0581 - accuracy: 0.9810 - val_loss: 0.5193 - val_accuracy: 0.8907

Epoch 00027: val_loss did not improve from 0.45440
Epoch 28/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0509 - accuracy: 0.9837 - val_loss: 0.5439 - val_accuracy: 0.8879

Epoch 00028: val_loss did not improve from 0.45440
Epoch 29/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0442 - accuracy: 0.9861 - val_loss: 0.5819 - val_accuracy: 0.8859

Epoch 00029: val_loss did not improve from 0.45440
Epoch 30/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0391 - accuracy: 0.9878 - val_loss: 0.6014 - val_accuracy: 0.8862

Epoch 00030: val_loss did not improve from 0.45440

Epoch 00030: ReduceLROnPlateau reducing learning rate to 4.0000001899898055e-05.
Epoch 31/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0293 - accuracy: 0.9907 - val_loss: 0.5740 - val_accuracy: 0.8938

Epoch 00031: val_loss did not improve from 0.45440
Epoch 32/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0275 - accuracy: 0.9915 - val_loss: 0.5741 - val_accuracy: 0.8925

Epoch 00032: val_loss did not improve from 0.45440
Epoch 33/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0235 - accuracy: 0.9927 - val_loss: 0.5932 - val_accuracy: 0.8929

Epoch 00033: val_loss did not improve from 0.45440
Epoch 34/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0230 - accuracy: 0.9930 - val_loss: 0.5927 - val_accuracy: 0.8937

Epoch 00034: val_loss did not improve from 0.45440
Epoch 35/40
1250/1250 [==============================] - 40s 32ms/step - loss: 0.0222 - accuracy: 0.9932 - val_loss: 0.6121 - val_accuracy: 0.8920

Epoch 00035: val_loss did not improve from 0.45440

Epoch 00035: ReduceLROnPlateau reducing learning rate to 8.000000525498762e-06.
plt.plot(history.history["accuracy"], label="train" )
plt.plot(history.history["val_accuracy"], label="valid" )
plt.legend()
<matplotlib.legend.Legend at 0x7f4be391b990>

테스트 데이터에서 평가

evaluate_accuracy = model.evaluate(test_images, test_oh_labels, batch_size=BATCH_SIZE, verbose=1)
313/313 [==============================] - 4s 12ms/step - loss: 0.4789 - accuracy: 0.8838

좋은 웹페이지 즐겨찾기