이번 글에서는 "드롭아웃(Dropout)에 대한 개념과 사용하는 이유, 그리고 사용방법과 이를 적용한 모델의 성능 확인"에 대한 방법들을 살펴보려 한다. 차례와 사용 툴 및 라이브러리는 아래와 같다.
[차례]
첫 번째, 드롭아웃(Dropout) 이란?
두 번째, 드롭아웃(Dropout)을 사용하는 이유
세 번째, 드롭아웃(Dropout)의 사용방법
네 번째, 드롭아웃(Dropout)을 적용한 모델의 성능 확인
[사용 툴]
- Jupyter notebook(웹 기반 대화형 코딩 환경)
[사용 라이브러리 및 모듈]
- 시각화 라이브러리 및 모듈: matplotlib.pyplot
- 딥러닝 라이브러리 및 모델: TensorFlow
- tensorflow.keras: 사용자 친화적 인터페이스를 제공하는 TensorFlow의 고수준 API
드롭아웃(Dropout) 이란?
드롭아웃(Dropout)은 신경망을 훈련시킬 때, 일부 뉴런(특성)을 임의로 활성화하지 않는 방법이다. 그림 1을 예로 들면, 드롭아웃의 비율이 0.5인 경우, 학습 단계마다 뉴런 네 개 중 랜덤으로 두 개만 활성화되고 나머지 두 개는 활성화되지 않는다. 이것은 마치 우리가 공부할 때 모든 공부 내용을 한 번에 다 외우려 하지 않고, 중요한 부분만 여러 번 반복해서 학습하는 것과 유사하다.
드롭아웃(Dropout)을 사용하는 이유
학습이라는 과정에서 중요한 것은 '균형'이다. 공부할 때 모든 정보를 빠짐없이 암기하려고 하면, 때로는 중요하지 않은 사소한 부분들까지 의존하게 될 수 있다. 이는 신경망 학습에도 비슷하게 적용된다. 신경망이 모든 뉴런(특성)을 활용하여 학습하면, 데이터의 중요한 특성뿐만 아니라, 그 안의 잡음(noise)까지도 뉴런이 암기하게 된다.
신경망이 이런 무작위적인 패턴을 중요한 정보로 학습하면, 훈련 데이터에는 매우 잘 맞겠지만, 새로운 데이터를 만났을 때는 그 패턴을 일반화하지 못하고 성능이 떨어지는 과대적합(overfitting) 현상이 발생하게 된다.
드롭아웃을 사용하는 이유는 바로 '과대적합을 방지'하기 위해서이다. 무작위로 일부 뉴런을 비활성화함으로써, 신경망은 더 이상 특정 뉴런의 패턴에만 의존할 수 없게 된다. 이는 신경망이 데이터의 근본적인 특성을 파악하도록 돕는다. 즉, 드롭아웃은 신경망이 더욱 일반적이고 신뢰할 수 있는 패턴을 학습하도록 유도하는 역할을 하는 것이다.
드롭아웃(Dropout)의 사용방법
드롭아웃(dropout)은 신경망의 각 은닉층(hidden layer)에 적용할 수 있다. 보통 입력층(input layer) 바로 뒤나, 여러 은닉층 사이에 넣어서 사용한다. 드롭아웃의 비율은 0에서 1 사이의 값으로 설정할 수 있으며, 일반적으로는 0.2에서 0.5 사이를 많이 사용한다.
드롭아웃은 모델이 '너무 똑똑해져서' 훈련 데이터에만 잘 맞는 것을 방지하는 방법이라고 할 수 있다. 이를 통해 모델이 훈련 데이터뿐만 아니라, 실제 세계의 데이터에 대해서도 잘 작동할 수 있도록 도와준다.
텐서플로우의 케라스를 활용하여 다음과 같은 방법으로 드롭아웃을 모델에 추가할 수 있다.
1. 모델 구축
1.1 심층신경망(DNN) 모델 구축
입력층(Flatten), 은닉층(Dense, Dropout), 출력층(Dense)으로 구성된 심층신경망(DNN)을 생성하였다. 이 구조에서 특히 중점적으로 다룰 부분은 은닉층에 포함된 드롭아웃(Dropout) 층이다.
드롭아웃의 비율은 0.3으로 설정하였는데, 이는 훈련 과정 중에 사용되는 뉴런(특성) 중 약 30%를 무작위로 비활성화 함을 의미한다. 이 과정을 통해, 신경망이 특정 뉴런에 지나치게 의존하는 것을 방지하고, 결과적으로 모델이 훈련 데이터에 과대적합(overfitting)되는 것을 방지하는 데 도움을 준다.
### 라이브러리 정의
import tensorflow as tf
from tensorflow import keras
### 신경망 모델 생성
model = Sequential()
### 계층 추가
# 입력층
model.add(keras.layers.Flatten(input_shape=(28, 28)))
# 은닉층
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dropout(0.3))
# 출력층
model.add(keras.layers.Dense(10, activation="softmax"))
1.2 심층신경망(DNN) 모델의 구조 확인
모델을 구축한 후, 심층신경망의 구조를 확인해 보았다. 이 요약 정보에서 각 계층의 역할과 특성을 파악할 수 있다. 입력 데이터를 일차원으로 변환하는 역할을 하는 플래턴(Flatten) 계층과 비슷하게, 드롭아웃(Dropout) 층은 학습 가능한 매개변수(Param)가 '0'으로 표시되어 있는 것을 볼 수 있다. 이는 드롭아웃 층이 직접적으로 학습 과정에서 가중치를 조정하지 않고, 훈련 과정에서 간접적으로만 영향을 미친다는 것을 의미한다.
드롭아웃 층의 주요 기능은 모델의 과대적합을 방지하고 일반화 능력을 향상시키는 것이며, 이는 훈련 과정 중 무작위로 선택된 뉴런(특성)의 출력을 '0'으로 설정함으로써 이루어진다.
model.summary()
드롭아웃(Dropout)을 적용한 모델의 성능 확인
2. 데이터 수집
사용할 데이터는 케라스에서 제공하는 패션 관련 이미지 데이터셋으로, 이는 훈련용 데이터셋과 테스트용 데이터셋으로 나뉘어 있다.
효과적인 학습을 위해, 우선 데이터 스케일링 과정을 거쳐 모든 픽셀 값을 0과 1 사이로 조정한다.
그다음, 모델의 성능을 체계적으로 평가하기 위해 훈련 데이터를 다시 8:2 비율로 훈련 데이터와 검증 데이터로 분리한다.
이러한 데이터 전처리 과정은 이미 여러 글에서 자세히 다루었기 때문에, 본 글에서는 생략하고 드롭아웃을 포함한 심층신경망 모델의 훈련 및 성능 평가에 초점을 맞추도록 하겠다.
3. 모델 설정
3.1 심층신경망(DNN) 모델 설정
- 옵티마이저(optimizer) 적용: 모델의 성능을 최적화하기 위해, 'adam' 옵티마이저를 선택하였다. 'adam'은 가속도와 관성의 개념을 이용해, 이전 그래디언트(경사)들의 정보를 바탕으로 학습률을 적절히 조정하며, 학습 과정을 보다 효율적으로 만들어 준다.
- 손실 함수(loss function) 적용: 다중 분류 문제에서 정수형 종속변수를 다루기 위해 선택한 손실 함수는 'sparse_categorical_crossentropy'이다. 이 함수는 각 클래스(종속변수)의 예측 확률을 계산하고, 모델의 예측이 정답과 얼마나 일치하는지를 측정한다.
- 성능 지표(metirics) 설정: 모델의 성능 평가를 위해 'accuracy(정확도)'를 선택하였다. 정확도는 모델이 얼마나 정확히 분류 작업을 수행하는지를 나타내는 결정적인 지표이다.
model.compile(optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics="accuracy")
4. 모델 훈련
4.1 심층신경망(DNN) 모델 훈련
history = model.fit(train_scaled, train_target, epochs=20, verbose=1,
validation_data=(val_scaled, val_target))
드롭아웃을 통해 규제된 심층신경망 모델을 훈련시켜 본 결과, 드롭아웃을 사용하지 않았을 때(동일 설정) 보다 훈련 단계에서의 손실률이 다소 증가하고 정확도는 줄어든 것을 확인할 수 있다.
그러나, 이와 반대로 검증 데이터에 대해서는 손실률이 감소하고 정확도가 향상되는 결과를 보인다.
이를 통해, 드롭아웃이 훈련 데이터에 대한 과대적합을 줄이고, 모델의 일반화 능력을 향상시키는데 기여하였음을 확인할 수 있다. 즉, 드롭아웃을 적용함으로써 모델이 실제 새로운 데이터에 대해 더 잘 예측할 수 있게 된 것이다.
5. 모델 훈련 지표 시각화
5.1 심층신경망(DNN) 모델의 훈련 지표 시각화(1) - 손실률(loss)
훈련 과정에서의 지표를 시각화하여, 이를 더욱 직관적으로 살펴보고자 하였다. 그래프로 시각화하여 살펴볼 지표는 손실률과 정확도이며, 이 지표들이 어떠한 의미를 나타내는지 살펴볼 것이다.
import matplotlib.pyplot as plt
plt.title("Epoch - Train & Val Loss (Adam-Dropout)")
plt.plot(history.epoch, history.history["loss"])
plt.plot(history.epoch, history.history["val_loss"])
plt.xlabel("epoch")
plt.ylabel("loss")
plt.legend(["Train", "Val"])
plt.grid()
plt.show()
5.2 심층신경망(DNN) 모델의 훈련 지표 시각화(2) - 정확도(accuracy)
plt.title("Epoch - Train & Val accuracy (Adam-Dropout)")
plt.plot(history.epoch, history.history["accuracy"])
plt.plot(history.epoch, history.history["val_accuracy"])
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.legend(["Train", "Val"])
plt.grid()
plt.show()
훈련 및 검증 정확도와 손실률에 대한 그래프를 분석한 결과, 에포크(반복 횟수)가 약 14회일 때 검증 정확도가 최고점을 기록하였으며, 이 시점에서 훈련 정확도와의 차이는 미미한 0.01 정도로 매우 이상적인 상태를 보인다.
또한, 같은 에포크에서 검증 손실률은 최저를 기록하였으며, 이때 훈련 손실률과는 약 0.025의 작은 차이를 보인다.
이를 통해, 모델이 정확도 면에서는 0.9에 미치지 못하는 다소 아쉬운 성능을 보이긴 하지만, 과대적합을 해소면서도 과소적합이 나타나지 않은 일반화된 모델로 판단된다.
'[파이썬] > 딥러닝' 카테고리의 다른 글
[딥러닝] 콜백함수를 활용한 딥러닝 모델 성능 최적화 (1) | 2024.01.07 |
---|---|
[딥러닝] 딥러닝 모델과 가중치 저장, 로드 및 예측수행 (2) | 2024.01.06 |
[딥러닝] 심층신경망(DNN)에 대한 개념 및 모델 구축 (1) | 2024.01.05 |
[딥러닝] 신경망 계층 추가방법 및 성능향상방법(옵티마이저; Optimizer+학습률(learning_rate)+모멘텀(Momentum)) (0) | 2024.01.04 |
[딥러닝] 인공신경망(ANN) 개념 및 모델 구축+성능 개선(계층 추가) (2) | 2024.01.04 |