프로젝트/코드프레소 체험단

이미지 데이터 처리를 위한 CNN 완벽 가이드 - CIFAR-10-codepresso 분류 CNN 모델 구현

KimCookieYa 2022. 3. 7. 18:28

 - 캐나다 토론토 대학의 연구팀에서 mnist보다 좀 더 복잡한 이미지 연구를 위해 수집한 데이터 셋

 - 60,000개의 컬러 이미지로 구성된 이미지 데이터 입니다.

 - 100개의 클래스를 가지고 있고 각 클래스는 600장의 이미지 데이터로 구성되어 있습니다.

 - 각각의 이미지는 (32, 32, 3) 형태의 3차원 텐서로 구성되어 있다.

 - CIFAR-10-codepresso 데이터 셋은 CIFAR-100 데이터 셋에서 10 개의 클래스를 선택하여 데이터 셋을 구성하였습니다. 또한 각 클래스의 라벨 정보는0~9 사이의 정수로 구성되어 있습니다.

 - 각각의 범주 id 와 인덱스로 매핑 되어 있는 class name 리스트 자료 구조는 아래와 같습니다.

cifar_label_name = ['apple', 'beaver', 'bottle', 'butterfly', 'castle', 'clock', 'couch', 'leopard', 'rose', 'shark']

 

CIFAR-100 Dataset

 

 

* CIFAR-100 데이터 셋에서 10개의 클래스를 선택한 CIFAR-10-codepresso 데이터 셋을 분류하는 CNN 모델 구현

import tensorflow as tf
import numpy as np
import requests
import io


"""* Step 1. Inptu tensor 와 Target tensor 준비(훈련데이터)"""

# label 데이터의 각 value 에 해당하는 class name 정보
cifar_label_name=['apple', 'beaver', 'bottle', 'butterfly', 'castle',
                  'clock', 'couch', 'leopard', 'rose', 'shark']

# 데이터 다운로드 url 경로
data_url = 'https://codepresso-online-platform-public.s3.ap-northeast-2.amazonaws.com/learning-resourse/Tensorflow+2.0+%EB%94%A5%EB%9F%AC%EB%8B%9D+%EC%99%84%EB%B2%BD+%EA%B0%80%EC%9D%B4%EB%93%9C/cifar-10-codepresso.npz'

# requests 라이브러리를 이용해 데이터 다운로드
response = requests.get(data_url)
response.raise_for_status()

# 다운로드 받은 데이터를 읽어 들여 Input tensor 와 Target tensor 준비
with np.load(io.BytesIO(response.content)) as cifar_10_codepresso_data:
  # 학습 이미지 데이터(np.ndarry, shape=(5000, 32, 32, 3))
  train_images = cifar_10_codepresso_data['train_images']
  # 학습 라벨 데이터(np.ndarry, shape=(5000, ))
  train_labels = cifar_10_codepresso_data['train_labels']
  
  # 테스트 이미지 데이터(np.ndarry, shape=(1000, 32, 32, 3))
  test_images = cifar_10_codepresso_data['test_images']
  # 테스트 라벨 데이터(np.ndarry, shape=(1000, ))
  test_labels = cifar_10_codepresso_data['test_labels']



"""* Step 2. 입력데이터의 전처리 """

# 수강생 작성 코드
# 1. feature 데이터를 [0, 1] 사이로 scailing을 수행하세요
train_images = train_images/255.
test_images = test_images/255.

# 수강생 작성 코드
# 1. 1차원 형태의(batch, ) class id 인 train, test label 데이터를
#    to_categorical API를 이용하여 one-hot-encoding 수행하여 2차원(batch, class_cnt) 으로 변경 하세요
train_labels = tf.keras.utils.to_categorical(train_labels)
test_labels = tf.keras.utils.to_categorical(test_labels)


"""* Step3. CNN 모델 디자인"""

# 수강생 작성 코드
# 1. Sequential API를 이용하여 fashion_mnist 데이터 셋을 분석 하기 위한 CNN 모델을 디자인 하세요
#   - 오버피팅 발생 시 classification module에 layers.Dropout 레이어를 추가 하여 성능을 향상시켜 보세요
from tensorflow.keras import models, layers

model = models.Sequential()
model.add(layers.Conv2D(filters=32, kernel_size=(3, 3),
						activation='relu',
                        input_shape=(32, 32, 3)))
model.add(layers.MaxPool2D(pool_size=(2, 2)))
model.add(layers.Conv2D(filters=64, kernel_size=(3, 3),
						activation='relu'))
model.add(layers.MaxPool2D(pool_size=(2, 2)))
model.add(layers.Conv2D(filters=128, kernel_size=(3, 3),
						activation='relu'))

model.add(layers.Flatten())

model.add(layers.Dense(units=128, activation='relu'))
model.add(layers.Dropout(0.3))
model.add(layers.Dense(units=10, activation='softmax'))


"""* Step 4. 모델의 학습 정보 설정"""

# 수강생 작성 코드
# 1. tf.keras.Model 객체의 compile 메서드를 이용하여 학습을 위한 정보들을 설정하세요
#   - optimizer
#   - loss
#   - metrics : 체점 기준인 accuracy 로 설정
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])


"""* Step 5. 모델에 input, target 데이터 연결 후 학습"""

# 수강생 작성 코드
# 1. tf.keras.Model 객체의 fit 메서드를 이용하여 모델을 학습하세요
#   - fit 메서드의 verbose=2 로 설정 하세요
history = model.fit(x=train_images, y=train_labels, batch_size=256, epochs=30, verbose=2, validation_split=0.2)

import matplotlib.pyplot as plt

# 모델의 학습과정 시각화
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']

epochs = range(len(acc))

plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and Validation Accuracy')
plt.legend()
plt.show()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
Epoch 20/30 16/16 - 0s - loss: 0.9456 - accuracy: 0.6783 - val_loss: 1.0614 - val_accuracy: 0.6460 - 312ms/epoch - 19ms/step
Epoch 21/30 16/16 - 0s - loss: 0.9447 - accuracy: 0.6858 - val_loss: 1.3554 - val_accuracy: 0.5690 - 345ms/epoch - 22ms/step
Epoch 22/30 16/16 - 0s - loss: 0.9101 - accuracy: 0.6952 - val_loss: 1.0522 - val_accuracy: 0.6430 - 346ms/epoch - 22ms/step
Epoch 23/30 16/16 - 0s - loss: 0.8894 - accuracy: 0.6952 - val_loss: 1.0276 - val_accuracy: 0.6660 - 310ms/epoch - 19ms/step
Epoch 24/30 16/16 - 0s - loss: 0.8638 - accuracy: 0.7135 - val_loss: 1.1073 - val_accuracy: 0.6400 - 322ms/epoch - 20ms/step
Epoch 25/30 16/16 - 0s - loss: 0.8300 - accuracy: 0.7178 - val_loss: 1.0006 - val_accuracy: 0.6640 - 322ms/epoch - 20ms/step
Epoch 26/30 16/16 - 0s - loss: 0.8355 - accuracy: 0.7212 - val_loss: 0.9497 - val_accuracy: 0.6930 - 347ms/epoch - 22ms/step
Epoch 27/30 16/16 - 0s - loss: 0.7909 - accuracy: 0.7345 - val_loss: 1.0333 - val_accuracy: 0.6430 - 320ms/epoch - 20ms/ste
Epoch 28/30 16/16 - 0s - loss: 0.7717 - accuracy: 0.7337 - val_loss: 1.1174 - val_accuracy: 0.6240 - 350ms/epoch - 22ms/step
Epoch 29/30 16/16 - 0s - loss: 0.7346 - accuracy: 0.7575 - val_loss: 0.9902 - val_accuracy: 0.6780 - 308ms/epoch - 19ms/step
Epoch 30/30 16/16 - 0s - loss: 0.7193 - accuracy: 0.7573 - val_loss: 0.9328 - val_accuracy: 0.6970 - 355ms/epoch - 22ms/step

 

* 모델의 성능 개선을 위해

 - layers.Dropout()을 추가함

 - epochs을 늘림