본문 바로가기
DNN with Keras/Regularization and Dropout

과적합을 줄이기 위한 드롭아웃

by goatlab 2023. 7. 24.
728x90
반응형
SMALL

Dropout to Decrease Overfitting

 

 

Hinton, Srivastava, Krizhevsky, Sutskever, Salakhutdinov (2012)는 드롭아웃 정규화 알고리즘을 도입했다. 드롭아웃은 L1과 L2와는 다르게 작용하지만 과적합 방지라는 동일한 목표를 달성한다. 하지만, 이 알고리즘은 실제로 뉴런과 연결을 제거함으로써 이 작업을 수행한다. 적어도 L1, L2와 달리 일시적으로 가중치 페널티가 추가되지 않는다. 드롭아웃은 직접적으로 작은 체중을 훈련시키는 것을 추구하지 않는다.

 

드롭아웃은 훈련의 일부 동안 신경망의 숨겨진 뉴런을 사용할 수 없게 함으로써 작동한다. 신경망의 일부를 떨어뜨리면 나머지 부분은 떨어진 뉴런이 없어도 좋은 점수를 얻을 수 있도록 훈련된다. 이 기술은 뉴런 간의 공동 적응을 감소시켜 과적합이 줄어든다.

 

대부분의 신경망 프레임워크는 드롭아웃을 별도의 계층으로 구현한다. 드롭아웃 레이어는 일반적으로 촘촘하게 연결된 신경망 레이어와 같은 기능을 한다. 유일한 차이점은 중퇴층이 훈련 중에 주기적으로 뉴런의 일부를 떨어뜨린다는 것이다. 일반 피드포워드 신경망에서 드롭아웃 계층을 사용할 수 있다.

 

훈련 알고리즘의 구현은 뉴런을 버리는 과정에 영향을 미친다. 드롭아웃 세트는 교육 반복 또는 배치별로 한 번씩 변경되는 경우가 많다. 일부 신경망 프레임워크는 이 간격의 속도를 정확하게 지정할 수 있도록 추가 하이퍼 파라미터를 제공한다.

 

왜 드롭아웃이 과적합을 줄일 수 있는지는 일반적인 질문이다. 답은 드롭아웃이 두 뉴런 사이에서 상호의존성이 발생할 가능성을 줄일 수 있다는 것아다. 상호의존성을 발달시키는 두 개의 뉴런은 한 개가 탈락할 때 효과적으로 작동하지 못할 것이다. 결과적으로, 신경망은 더 이상 모든 뉴런의 존재에 의존할 수 없으며, 그에 따라 훈련한다. 이 특성은 제시된 정보를 암기하는 능력을 감소시켜 일반화를 강요한다.

 

Bootstrapping

 

또한, 드롭아웃은 신경망에 부트스트래핑 프로세스를 강제함으로써 과적합을 감소시킨다. 부트스트래핑은 널리 사용되는 앙상블 기술이다. 앙상블은 여러 모델을 결합하여 개별 모델이 달성한 것보다 더 나은 결과를 생성하는 기계 학습 기술이다. 앙상블은 관객이 듣는 마지막 음악 제품이 여러 악기의 조합인 음악 앙상블에서 유래한 용어이다.

 

부트스트래핑은 가장 간단한 앙상블 기술 중 하나입니다. 부트스트래핑 프로그래머는 여러 신경망을 훈련시켜 정확하게 동일한 작업을 수행합니다. 그러나 신경망 가중치 초기화에 사용되는 일부 훈련 기술과 난수 때문에 각 신경망은 다르게 수행될 것이다. 가중치의 차이로 인해 성능 차이가 발생한다. 이 신경망 앙상블의 출력은 함께 사용된 구성원의 평균 출력이 된다. 이 과정은 다르게 훈련된 신경망의 합의를 통해 과적합을 감소시킨다.

 

드롭아웃은 부트스트랩과 다소 유사하다. 각각의 신경 네트워크가 다른 뉴런들의 집합이 앙상블의 개별적인 구성원으로서 탈락되는 것을 생각할 수 있다. 훈련이 진행됨에 따라, 그 프로그램은 이런 방식으로 더 많은 신경망을 만든다. 그러나 드롭아웃은 부트스트래핑과 동일한 양의 처리를 필요로 하지 않는다. 생성된 새로운 신경망은 일시적이며, 훈련 반복 동안만 존재한다. 최종 결과는 또한 함께 평균화되는 신경망의 앙상블이 아닌 단일 신경망이다.

 

import pandas as pd
import os
import numpy as np
from sklearn import metrics
from scipy.stats import zscore
from sklearn.model_selection import KFold
from tensorflow.keras.models import Sequential
from tensorflow.keras import regularizers
from tensorflow.keras.layers import Dense, Activation, Dropout

EPOCHS = 500
kf = KFold(5 , shuffle = True , random_state = 42)
oos_y = [ ]
oos_pred = [ ]

fold = 0
for train, test in kf.split(x):
  fold += 1
  print(f"Fold #{fold}")

  x_train = x[train]
  y_train = y[train]
  x_test = x[test]
  y_test = y[test]

  model = Sequential()
  
  model.add(Dense(50, input_dim = x.shape[1], activation = 'relu', activity_regularizer = regularizers.l1(1e−4)))
  model.add(Dropout(0.5))
  model.add(Dense(25, activation = 'relu', activity_regularizer = regularizers.l1(1e−4)))
  model.add(Dense(y.shape[1], activation = 'softmax'))
  model.compile(loss = 'categorical_crossentropy', optimizer = 'adam')
  model.fit(x_train, y_train, validation_data = (x_test, y_test), verbose= 0, epochs= EPOCHS)
  pred = model.predict(x_test)
  
  oos_y.append(y_test)
  oos_pred.append(pred)
  
  score = np.sqrt(metrics.mean_squared_error(pred, y_test))
  print(f"Fold score (RMSE) : {score}")

oos_y = np.concatenate(oos_y)
oos_pred = np.concatenate(oos_pred)
score = np.sqrt(metrics.mean_squared_error(oos_pred, oos_y))
print(f"Final, out of sample score (RMSE) : {score}")

oos_y = pd.DataFrame(oos_y)
oos_pred = pd.DataFrame(oos_pred)
oosDF = pd.concat([df, oos_y, oos_pred], axis = 1)

oosDF.to_csv(filename_write, index = False)
728x90
반응형
LIST