본문 바로가기
[파이썬]/딥러닝

[딥러닝] 심층신경망(DNN)에 대한 개념 및 모델 구축

by sung min_Kim 2024. 1. 5.


 이번 글에서는 "심층신경망(DNN)에 대한 개념 및 모델 구축"에 대한 방법들을 살펴보려 한다.
차례와 사용 툴 및 라이브러리는 아래와 같다.

 [차례]
첫 번째, 심층신경망(Deep Neural Network, DNN)이란?
두 번째, 심층신경망(DNN) 구축하기


 [사용 툴]

- Jupyter notebook(웹 기반 대화형 코딩 환경)
 
 [사용 라이브러리 및 모듈]

  • 시각화 라이브러리 및 모듈: matplotlib.pyplot
  • 머신러닝 라이브러리 및 모델: scikit-learn
    - sklearn.model_selection.train_test_split: 훈련 및 테스트 데이터 세트 분리

  • 딥러닝 라이브러리 및 모델: TensorFlow
    - tensorflow.keras: 사용자 친화적 인터페이스를 제공하는 TensorFlow의 고수준 API

 


 

심층신경망(Deep Neural Network, DNN)이란?

 

심층신경망의 구조


 심층신경망(DNN)은 이름에서 알 수 있듯이 '깊은' 네트워크를 가지고 있다. 이는 은닉층(hidden layer)이 여러 개 있음을 의미하며, 이러한 구조 덕분에 복잡한 패턴을 더욱 잘 파악하고 학습할 수 있다. 심층신경망은 딥러닝의 핵심 기술로, 음성 인식, 이미지 인식 등 다양한 분야에 활용되고 있다.

 반면, 인공신경망(ANN)은 대게 입력층(input layer), 은닉층(hidden layer), 출력층(output layer)의 세 부분으로 구성되며, 은닉층이 한 개 또는 그 이상일 수 있지만 일반적으로 그 수는 많지 않다. 

 


심층신경망(DNN) 구축하기

 

1. 라이브러리 정의 및 데이터 수집
1.1 라이브러리 정의


 딥러닝의 신경망을 모델링하기 위한 'tensorflow', 'keras라이브러리를 호출한다. 또한, 결과의 일관성을 보장하기 위해 난수 시드 설정과 연산 고정 옵션을 활성화하여 준다. 이를 통해, 모델의 훈련 과정이나 결과에 대한 재현성을 구현할 수 있다. 이는 실제 서비스 환경에서 중요한 요소이다.

import tensorflow as tf
from tensorflow import keras

tf.keras.utils.set_random_seed(42)
tf.config.experimental.enable_op_determinism()

from sklearn.model_selection import train_test_split

import matplotlib.pyplot as plt

 

1.2 데이터 수집


 사용할 데이터로는 keras 라이브러리에서 제공하는 'fashion_mnist' 패션 데이터를 로드하여 사용하였다. 이 데이터는 패션 품목에 대한 60,000개의 훈련 이미지와 10,000개의 테스트 이미지를 포함하며, 각 이미지는 28x28 픽셀 크기의 흑백 이미지로 이루어져 있다. 데이터의 차원은 3차원 배열로, 이는 이미지의 색상, 높이, 너비를 나타낸다.

(train_input, train_target), (test_inpurt, test_target) = keras.datasets.fashion_mnist.load_data()

print(train_input.shape, train_target.shape)
print(test_inpurt.shape, test_target.shape)

훈련 데이터와 테스트 데이터

 

2. 데이터 전처리
2.1 데이터 스케일링


 사용할 데이터는 0에서 255까지의 큰 범위를 가진 픽셀 데이터이므로, 최댓값인 '255'를 활용해 이를 모두 '0'에서 '1' 사이의 범위로 스케일링(정규화)하여 모델 학습에 유용한 상태로 만들어 준다.

train_scaled_255 = train_input / 255.0

test_sclaed_255 = test_inpurt / 255.0

train_scaled_255[0]

스케일링이 이루어진 값들

 

2.2 데이터 분리


 패션 데이터셋을 처음 호출했을 때, 이를 각각 훈련 데이터와 테스트 데이터에 저장하였다. 추가적으로, 모델의 성능을 검증하기 위해 사용하는 '검증 데이터셋'을 생성하고자 한다. 이를 위해, 스케일링된 훈련 데이터의 독립변수와 훈련 데이터의 종속변수를 8:2의 비율로 분리하여 주도록 한다.

train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled_255, train_target,
                                                                      test_size=0.2,
                                                                      random_state=42)

print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)

훈련 데이터와 검증 데이터

 

3. 모델 구축
3.1 심층신경망 모델 구축을 위한 함수 생성

 
 신경망 모델을 구축하고 계층을 추가하는 과정을 단순화하기 위해, 'model_fn'이라는 함수를 생성하였다. 이 함수는 Sequential 함수를 사용해 초기 신경망 모델을 생성한다. 'model_fn' 함수를 호출하면, 입력층(Flatten), 은닉층(Dense), 그리고 출력층(Dense)이 추가된 모델이 반환된다. 또한, 'a_layer'라는 선택적 매개변수를 통해 추가적인 은닉층을 삽입할 수 있다.

 'a_layer' 매개변수의 기본값을 'None'으로 설정함으로써, 해당 매개변수가 제공되지 않더라도 'model_fn' 함수는 정상적으로 실행된다. 이는 'a_layer'를 이용해 추가적인 은닉층을 삽입할 수도 있지만, 그렇지 않아도 기본적인 신경망 모델이 잘 구성됨을 의미한다.

def model_fn(a_layer = None) :
    model = keras.Sequential()
    model.add(keras.layers.Flatten(input_shape=(28, 28)))
    model.add(keras.layers.Dense(100, activation="relu"))

    if a_layer :
        model.add(a_layer)

    model.add(keras.layers.Dense(10, activation="softmax"))

    return model

 

3.2 함수 호출을 통한 심층신경망 모델 구축
model = model_fn()
model

심층신경망(DNN) 모델 구축

 

3.3 계층 확인하기


 summary 함수를 사용하여 모델의 구조를 자세히 살펴볼 수 있다. 여기서 모델의 구조란 각 계층의 이름과 유형, 출력 크기(개수), 그리고 학습에 사용되는 파라미터의 수 등을 포함한다.

model.summary()

모델의 구조 확인

 

4. 모델 설정
4.1 심층신경망 모델 설정

 
 출력 계층에 설정한 출력 크기(개수)는 '10'으로, 이는 모델이 최종적으로 예측하고자 하는 결과, 즉 10개의 패션 아이템 카테고리(종속변수)를 나타낸다. 이 분류 문제에서는 각 아이템 카테고리가 정수형 데이터로 표현되기 때문에, 'sparse_categorical_crossentropy'를 손실 함수(loss)로 사용하였다.

종속변수 - 정수형 데이터


 이 손실 함수는 모델이 각 카테고리(종속변수)에 대해 예측한 확률과 실제 카테고리(종속변수) 값의 차이를 계산하여 모델의 성능을 평가한다.

 또한, 모델의 성능을 측정하는 지표로 'accuracy'(정확도)를 사용하였다. 이 지표는 모델이 예측한 카테고리(종속변수) 값과 실제 값이 얼마나 일치하는지를 나타내며, 정확도가 높을수록 모델의 성능이 좋다는 것을 의미한다.

model5.compile(
    loss="sparse_categorical_crossentropy",
    metrics="accuracy"
)

 

5. 모델 훈련
5.1 심층신경망 모델 훈련


 모델 설정을 완료한 이후에는 fit 함수를 사용하여 모델을 훈련(학습)시킨다. 모델의 훈련 과정에는 훈련 데이터를 사용하여야 하며, 본인은 스케일링된 훈련 데이터의 독립변수와 훈련 데이터의 종속변수를 사용하였다. 이 과정에서 'epochs'라는 매개변수를 통해 훈련을 총 몇 회 반복할지를 결정한다. 모델은 각 훈련마다 성능을 개선하는 방향으로 훈련을 진행하며, 이는 손실을 점차 줄여나가는 형태로 이루어진다.

 'verbose=1'은 훈련 도중 로그를 실시간으로 프로그래스 바와 함께 보여주는 옵션이다. '0'으로 설정하면 로그 출력이 나타나지 않으며, '2'로 설정하면 프로그래스 바 없이 로그만 출력된다. 이 매개변수를 생략하더라도 기본값으로 'verbose=1'이 설정되어 있다.

history = model.fit(train_scaled, train_target, epochs=5, verbose=1)

모델의 훈련(학습)을 통해 출력된 지표

 

5.2 훈련 과정의 지표 확인


  훈련 과정에서 계산된 여러 지표를 확인하기 위해, 'history' 객체를 활용하였다. 이 객체는 딕셔너리 형태로, 키에는 'loss'(손실률), 'accuracy'(정확도)와 같은 지표 이름이, 값에는 각 'epoch'(반복 횟수)마다의 지표 수치가 리스트 형태로 저장된다. 예를 들어, 훈련 과정에서의 손실률을 확인하려면 'history.history["loss"]'를 사용하면 된다.

 이와 같이 'history' 객체를 사용하면 모델의 학습 과정을 세부적으로 파악할 수 있다. 이를 통해 모델의 성능을 개선할 수 있는 방안을 찾아볼 수 있다. 본인은 훈련 과정에서의 지표들을 시각화하여, 모델의 학습 경향을 더욱 직관적으로 이해해 보려 한다.

print(history.epoch, "\n", history.history)

훈련 과정의 지표 확인

 

5.3 훈련 과정에서의 지표 시각화(1) - 손실률(Loss)


 훈련 과정에서의 지표 중 하나인 손실률(loss)을 시각화하여 살펴보았다. 각 에포크마다의 손실률을 그래프로 나타내 보면, 훈련이 진행될수록 손실률이 점차 감소하는 것을 확인할 수 있다.

plt.title("Epoch - Loss")
plt.plot(history.epoch, history.history["loss"])

plt.xlabel("epoch")
plt.ylabel("loss")
plt.grid()

plt.show()

각 훈련 횟수별 손실률(loss) 그래프

 

5.4 훈련 과정에서의 지표 시각화(2) - 정확도(Accuracy)


 훈련 과정에서의 또 다른 지표인 정확도(accuracy)도 시각화하여 살펴보았다. 각 에포크마다의 정확도를 그래프로 표현하면, 훈련이 진행될수록 정확도(accuracy)가 점차 상승하는 것을 확인할 수 있다. 이는 모델의 예측 성능이 학습을 통해 점차 개선(향상)되고 있음을 보여준다. 따라서, 손실률이 감소하면서 동시에 정확도가 상승하는 이러한 패턴은 모델이 효과적으로 훈련(학습)되고 있음을 의미하며, 이를 통해 모델의 성능 개선 과정을 직관적으로 이해하는 데 도움을 주었다.

plt.title("Epoch - accuracy")
plt.plot(history.epoch, history.history["accuracy"])

plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.grid()

plt.show()

각 훈련 횟수별 정확도 그래프(accuracy)

 

6. 모델 성능 평가
6.1 심층신경망 모델 성능 평가


 모델 학습이 완료된 후에는 성능을 평가해야 한다. 이를 위해, 'evaluate' 함수를 사용한다. 모델의 성능을 평가하기 위해서는 모델이 아직 접하지 못한 새로운 데이터인 '검증 데이터셋'을 이 함수에 전달해 주도록 한다. 이렇게 새로운 데이터를 통해 모델의 성능을 측정하면, 모델의 실제 퍼포먼스를 보다 객관적으로 파악하는 데 도움이 된다.

model.evaluate(val_scaled, val_target)

모델의 성능 평가 결과
모델의 훈련 결과


 모델의 성능 평가 결과와 훈련 결과를 비교해 본 결과, 검증 데이터에서의 손실률(loss)이 훈련 데이터에서의 손실률보다 약 0.14 정도 높게 나타났다. 또한, 검증 데이터에서의 정확도(accuracy)가 훈련 데이터에서의 정확도보다 약 0.005 정도 낮게 나타났다.

  • 손실률(loss): 훈련 < 검증
    - 오차: 약 0.14
  • 정확도(accuracy) 훈련 > 검증
    - 오차: 약 0.005


 이 결과를 통해, 모델이 과소적합(underfitting)된 상황은 아닌 것으로 판단된다. 하지만, 검증 데이터와 훈련 데이터 사이의 손실률 차이가 0.1 이상 나타난 것으로 보아, 모델이 과적합(overfitting)되었을 가능성이 높을 것으로 판단된다.

 과적합이란, 모델이 훈련 데이터에 너무 잘 맞춰져 있어 새로운 데이터(검증 데이터)에 대한 예측 성능이 떨어지는 현상을 말한다. 즉, 모델이 훈련 데이터의 특정 패턴을 너무 과도하게 학습하여 일반화 성능이 떨어진 것으로 볼 수 있다.

 따라서, 이러한 과적합 문제를 해결하기 위해서는 데이터의 양을 증가시키거나, 하이퍼파라메터 튜닝을 진행하거나, 또는 모델의 복잡도를 조절(ex. 계층 추가 및 삭제, dropout 적용)하는 등 여러 방법이 고려된다.