본문 바로가기
Keras Deep Learning

컬러 이미지를 분류하는 DNN 구현 실습

by yj.yoon 2020. 8. 20.

개발 환경 : pycharm-community-2020.2 (무료 에디션)

Anaconda, python3.7, Windows 10


DNN(심층신경망) 구현 2번 째 실습

이번에는 컬러이미지!

 

 

1. 데이터 불러오기

사용한 데이터셋은 CIFAR-10 이다. 10가지 사물이 담긴 컬러이미지로, 총 6만장이고 크기는 32 * 32 이다.

컬러 이미지는 3가지 채널(각각 RGB) 로 구성된다.

데이터를 불러오는 패키지

import numpy as np
from keras import datasets
from keras.utils import np_utils

 

재사용성을 고려해 데이터 불러오기 코드를 함수로 만들어서(Data_func) 불러오기 할 것이다.

def Data_func():
    (X_train, y_train), (X_test, y_test) = datasets.cifar10.load_data()

 

2차원 배열로 변환

- CIFAR-10은 클래스가 10개이므로 출력 노드 수는 10개이다. 반면 목표값은 0~9까지 정수값으로 저장되어 있어서 정수값을 np_utils.to_categorical 을 이용해 10개의 원소를 가진 이진 벡터로 변환했다.

	Y_train = np_utils.to_categorical(y_train)
	Y_test = np_utils.to_categorical(y_test)

 

차원을 변경

- 컬러 이미지는 채널이 포함된 4차원이기 때문에 L, W, H, C 정보를 X_train.shape 으로부터 가져온다.

- L 은 데이터 수, W 이미지 넓이 (y축), H 이미지 높이 (x축), C 이미지 채널 수

- DNN은 벡터 형태의 정보를 다루기 때문에 2차원이 되도록 해야한다.

	L, W, H, C = X_train.shape
	X_train = X_train.reshape(-1, W * H * C)
	X_test = X_test.reshape(-1, W * H * C)

 

 

2. 모델링

Pd_1은 두 아큐먼트로 드롭아웃 확률 지정

드롭아웃 ? : Dropout(p) p라는 확률로 출력 노드의 신호를 보내다 말다 하는 것 - 견고하게 신호에 적응

from keras import layers, models

class DNN(models.Sequential):
    def __init__(self, Nin, Nh_l, Pd_l, Nout):
        super().__init__()

        self.add(layers.Dense(Nh_l[0], activation='relu',input_shape=(Nin,), name='Hidden-1'))
        self.add(layers.Dropout(Pd_l[0]))

        self.add(layers.Dense(Nh_l[1], activation='relu',name='Hidden-2'))
        self.add(layers.Dropout(Pd_l[1]))

        self.add(layers.Dense(Nout, activation='softmax'))

        self.compile(loss='categorical_crossentropy',
                     optimizer='adam',
                     metrics=['accuracy'])

 

 

3. 학습 효과 분석

프로젝트 내 keraspp 폴더의 skeras.py 에 들어있는 함수들을 import 한다.

그 아래는 이제 그래프를 그리기 위한 코드임을 알고 있다.

from keraspp.skeras import plot_loss, plot_acc
import matplotlib.pyplot as plt
def plot_acc(history, title=None):
    # summarize history for accuracy
    if not isinstance(history, dict):
        history = history.history

    plt.plot(history['accuracy'])
    plt.plot(history['val_accuracy'])
    if title is not None:
        plt.title(title)
    plt.ylabel('accuracy')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc=0)
    # plt.show()


def plot_loss(history, title=None):
    # summarize history for loss
    if not isinstance(history, dict):
        history = history.history

    plt.plot(history['loss'])
    plt.plot(history['val_loss'])
    if title is not None:
        plt.title(title)
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc=0)
    # plt.show()

 

 

4. 학습 및 성능 평가

학습을 진행하고 성능을 평가한다.

먼저 파라미터를 설정!

def main():
    Nh_l = [100, 50]
    Pd_l = [0.0, 0.0]
    number_of_class = 10
    Nout = number_of_class

 

Data_func 함수로 데이터 불러오고 파라미터를 이용해 DNN 객체의 인스턴스를 만든다.

    (X_train, Y_train), (X_test, Y_test) = Data_func()
    model = DNN(X_train.shape[1], Nh_l, Pd_l, Nout)

 

평가 데이터(1만 장)를 활용해 최종 성능을 알아볼 차례

performace_test = model.evaluate(X_test, Y_test, batch_size=100)
print('Test Loss and Accuracy ->', performace_test)

 

수행 결과

10가지 사물을 인공지능이 45.5%까지 분류할 수 있다.

 

그래프 : 학습 데이터와 검증 데이터 간의 성능 차이가 많다. 둘이 유사하게 되려면 드롭아웃값을 조정해야 한다.

 

 

전체 코드

# 분류 DNN 모델 구현
from keras import layers, models

class DNN(models.Sequential):
    def __init__(self, Nin, Nh_l, Pd_l, Nout):
        super().__init__()

        self.add(layers.Dense(Nh_l[0], activation='relu', input_shape=(Nin,), name='Hidden-1'))
        self.add(layers.Dropout(Pd_l[0]))

        self.add(layers.Dense(Nh_l[1], activation='relu', name='Hidden-2'))
        self.add(layers.Dropout(Pd_l[1]))

        self.add(layers.Dense(Nout, activation='softmax'))

        self.compile(loss='categorical_crossentropy',
                     optimizer='adam',
                     metrics=['accuracy'])

# 데이터 준비
import numpy as np
from keras import datasets
from keras.utils import np_utils

def Data_func():
    (X_train, y_train), (X_test, y_test) = datasets.cifar10.load_data()

    Y_train = np_utils.to_categorical(y_train)
    Y_test = np_utils.to_categorical(y_test)

    L, W, H, C = X_train.shape
    X_train = X_train.reshape(-1, W * H * C)
    X_test = X_test.reshape(-1, W * H * C)

    X_train = X_train / 255.0
    X_test = X_test / 255.0

    return (X_train, Y_train), (X_test, Y_test)

# 학습 효과 분석
from keraspp.skeras import plot_loss, plot_acc
import matplotlib.pyplot as plt

# 분류 DNN 학습 및 테스팅
def main():
    Nh_l = [100, 50]
    Pd_l = [0.02, 0.5] #0, 0
    number_of_class = 10
    Nout = number_of_class

    (X_train, Y_train), (X_test, Y_test) = Data_func()
    model = DNN(X_train.shape[1], Nh_l, Pd_l, Nout)
    history = model.fit(X_train, Y_train, epochs=10, batch_size=100, validation_split=0.2)

    performace_test = model.evaluate(X_test, Y_test, batch_size=100)
    print('Test Loss and Accuracy ->', performace_test)

    plot_loss(history, '(a) loss')
    plt.show()
    plot_acc(history, '(b) Accuracy')
    plt.show()

if __name__ == '__main__':
    main()

 

 


참고 : 3분 딥러닝 케라스맛