본문 바로가기

머신러닝공부

GTSRB(German Traffic Sign Recognition Benchmark) Project 간단 정리 및 Example script

728x90
반응형

독실 신경 정보학 연구원들이 교통표지판(Traffic sign)을 예측하기 위해서 만든 데이터이며, 평균적으로 32 x 32 크기를 가지는 color 이미지로서, 43개의 교통 표지판과 관련된 약 4만 개의 이미지를 포함함

모델 아키텍처 및 개발 프로세스

Conv Layer -> Conv Layer -> MaxPooling Layer -> Flatten Lyaer -> Dense Layer -> Dense Layer

데이터 로드 : Colab에서 wget을 이용하여 데이터 다운로드

데이터 전처리 : 디렉토리 정리, OpenCV 이용한 이미지로드 cv2.imread(), train data& test data 생성 및 정규화

모델 아키텍처: loss = 'sparse_categorical_crossentropy', optimizer=Adam

모델 학습 및 평가 : model.filt(x_train, y_train, epochs=30, ...), model.evaludate(x_test, y_test)

 

데이터 로드

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.layers import Flatten, Conv2D, MaxPooling2D

# 파일 다운로드

!wget https://sid.erda.kd/public/archives/daaeac0d7ce1152aea9b61d9f1e19370/GTSRB_Final_Training_Images.zip # 복사된 링크 주소

# 압축파일 풀기

import zipfile
with zipfile.ZipFile('/content/GTSRB_Final_Training_Images.zip', 'r') as target_file:
	target_file.extractall()
    
import os
ROOT_DIR = '/content'
DATA_ROOT_DIR = os.path.join(ROOT_DIR, 'GTSRB/Final_Training/Images/') # ROOT_DIR 설정해두면, Colab 이외 시스템에서는 ROOT_DIR부분만 변경하면 프로그램 호환성을 높일 수 있음

데이터 전처리(train data, test data 생성, 정규화)

import os
import cv2
import glob
import numpy as np

image_list = []
label_list = []

image_label_list = os.listdir(DATA_ROOT_DIR) # 정답 리스트 image_label_list

# 각각의 정답(label)에 대해서
for label_name in image_label_list : 
	# 이미지 파일 읽어오기
    file_path = os.path.join(DATA_ROOT_DIR, label_name)
    img_file_list = glob.glob(file_path+'/*.ppm')
    
    # 각각의 정답 디렉토리에 있는 이미지 파일, 즉 .ppm 파일 읽어서 리시트에 저장
    
    for img_file in img_file_list:
    	try:
        	# 정답 디렉토리에 있는 이미지 OpenCV를 이용해 읽어들임
        	src_img = cv2.imread(img_file, cv2.IMREAD_COLOR)
            src_img = cv2.resize(src_img, dsize=(32, 32))
            src_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2RGB)
            
            # 이미지와 정답 리스트에 추가함. 즉, 정답에 해당하는 이미지를 순서에 맞게 리스트에 추가함
            image_list.append(src_img)
            label_list.append(float(label_name))
            
        except Exception as err:
        	print(str(err), img_file)
            continue
            
# list 데이터를 numpy 데이터로 변환해서 train data (x_train, y_train) 생성
x_train = np.array(image_list).astype('float32')
y_train = np.array(label_list).astype('float32')

# x_train, y_train 개별적으로 shuffle을 실행하면서 이미지에 대응되는 정답이 random하게 shuffle 되기 때문에,
# index를 먼저 shuffle 한 후에, shuffle 된 index를 이용해서 x_train, y_train을 다시 생성함

import numpy as np

s = np.arange(len(x_train))

np.random.shuffle(s) # 다양성 확보, index random shuffle

x_train = x_train[s]
y_train = y_train[s]

# train data 20% 비율로 numpy slice 이용하여 test data 생성.

SPLIT_RATIO = 0.2 # 20%

SPLIT_NUMS = int(SPLIT_RATIO*len(x_train))

x_test = x_train[0:SPLIT_NUMS]
y_test = y_train[0:SPLIT_NUMS]

x_train = x_train[SPLIT_NUMS:]
y_train = y_train[SPLIT_NUMS:]

# 0~1 값으로 정규화
x_train = x_train.astype(np.float32)/255.0
x_test = x_test.astype(np.float32)/255.0

print('x_train.shape = ', x_train.shape, ', y_train.shape = ', y_train.shape)
print('x_test.shape = ', x_test.shape, ', y_test.shape = ', y_test.shape)

# train : test = 8 : 2
x_train.shape = (31368, 32, 32, 3), y_train.shape = (31368,)
x_test.shape = (7841, 32, 32, 3), y_test.shape = (7841,)

모델 구축

Conv Layer -> Conv Layer -> MaxPooling Layer -> Flatten Layer -> Dense Layer -> Dense Layer

n_classes = len(os.listdir(DATA_ROOT_DIR)) # 정답 개수

model = Sequential()

model.add(Conv2D(input_shape=(32, 32, 3), kernel_size=(3, 3), filters=32, activation='relu'))
model.add(Conv2D(kernel_size=(3,3), filters=64, activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2))
model.add(Dropout(0.25))

model.add(Flatten())

# 정확도를 높이고 오버피팅을 줄이기 위해 2개의 Dense 레이서와 1개의 Dropout 레이어 구성
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))

model.summary()

model.compile(loss='sparse_categorical_crossentropy', optimizer=tf.keras.optimizers.Adam(), metrics=['accuracy'])

모델 학습

from tensorflow.keras.callbacks import EarlyStopping

earlystopping = EarlyStopping(monitor='val_loss', patience=5, verbose=1)

hist = model.fit(x_train, y_train, batch_size=32, epochs=30, validation_data=(x_test, y_test), callbacks=[earlystopping])

손실 및 정확도

import matplotlib.pyplot as plt

plt.plot(hist.history['accuracy'], label='train')
plt.plot(hist.history['val_accuracy'], label='validation')
plt.title('Accuracy Trend')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(loc = 'best')
plt.grid()
plt.show()

plt.plot(hist.history['loss'], label='train')
plt.plot(hist.history['val_loss'], label='validation')
plt.title('Loss Trend')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(loc='best')
plt.grid()
plt.show()
반응형