딥러닝 모델을 구축할 때, 훈련 데이터와 테스트 데이터만으로도 훈련의 척도를 판단할 수 있다. 하지만, 훈련 데이터에 대한 학습만을 바탕으로 모델의 설정(Hyperparameter)를 튜닝하게 되면 과대적합(overfitting)이 일어날 가능성이 매우 크다. 또한, 테스트 데이터는 학습에서 모델에 간접적으로라도 영향을 미치면 안 되기 때문에 테스트 데이터로 검증을 해서는 안 된다. 그래서 검증(validation) 데이터셋을 따로 두어 매 훈련마다 검증 데이터셋에 대해 평가하여 모델을 튜닝해야 한다.
하지만, 검증 데이터셋이 훈련에 사용되지 않더라도 검증 데이터셋에 대한 성능을 기반으로 hyperparameter를 튜닝하므로 정보 누설(information leak)이 일어나게 된다. 즉, 검증 데이터셋을 사용함으로써 훈련 데이터셋에 대한 overfitting은 어느정도 피할 수 있어도 오히려 검증 데이터셋에 대해 overfitting될 수 있다는 것이다.
이를 위해 여러 가지 검증 방법이 존재한다.
1. Hold-out validation(단순 홀드아웃 검증)
아주 기본적인 검증 방법으로 단순히 훈련데이터와 테스트 데이터로 나누고, 나눠진 훈련데이터에서 다시 검증 데이터셋을 따로 떼어내는 방법이다.
x
num_validation = 10000
num_test = 5000
# 각각의 데이터셋에 데이터의 종류가 고르게 들어가야 하므로 섞어주는 것이 좋다
np.random.shuffle(data)
test_data = data[:num_test]
validation_data = data[num_test : num_test + num_validation]
train_data[num_test + num_validation :]
// ...
# train_data로 모델 훈련
model = get_model()
model.train(train_data)
# validation_data로 모델 평가
val_score = model.evaluate(validation_data)
# hyperparameter 튜닝
# 반복...
# 튜닝이 끝나면 test_data를 제외한 모든 데이터로 모델을 다시 훈련시킴
model = get_model()
model.train(np.concatenate([train_data, validation_data]))
# test_data로 평가
test_score = model.evaluate(test_data)
<문제점>
데이터가 적을 때는 각 데이터셋이 전체 데이터를 통계적으로 대표하지 못할 가능성이 높다. 즉, 하나의 데이터셋에 다양한 특징을 지닌 데이터들이 포함되지 않을 수 있다는 것이다. 이를 확인하는 방법은 간단하다. 새롭게 데이터를 셔플링하여 다시 모델을 학습시켰을 때 모델의 성능이 많이 차이가 나면 이 문제라고 볼 수 있다.
2. K-fold cross-validation(K-겹 교차 검증)
이 검증법은 데이터가 적을 때 나타나는 문제를 어느정도 해결해준다.
위 그림처럼 정해진 K번만큼 검증 데이터셋과 훈련 데이터셋을 변경해가면서 거의 모든 데이터에 대해 검증을 하는 방법이다. 모델의 총 validation score는 각 훈련의 validation score의 평균이다.
x
k = 4
# //는 몫만을 구하는 나누기 연산
num_validation = len(data) // k
np.random.shuffle(data)
validation_scores = []
for fold in range(k):
validation_data = data[num_validation * fold:
num_validation * (fold + 1)]
# 리스트 + 리스트는 연결된 하나의 리스트를 생성한다
train_data = data[:num_validation * fold] + data[num_validation * (fold + 1):1]
model = get_model()
model.train(train_data)
val_score = model.evaluate(validation_data)
validation_scores.append(val_score)
validation_score = np.average(validation_scores)
# 테스트 데이터를 제외한 데이터로 새 모델을 학습한 뒤 테스트 데이터로 평가
추가적으로, 비교적 가용 데이터가 적고 가능한 정확하게 모델을 평가하고자 할 경우, K개의 분할로 나누기 전에 매번 데이터를 무작위로 섞고 여러 번 K-겹 교차 검증을 반복하면 된다.
3. 데이터를 나눌 시 주의점
- 대표성 : 훈련 데이터셋과 테스트 데이터셋은 전체 데이터에 대한 대표성을 띄고 있어야 한다.
- 시간의 방향 : 과거 데이터로부터 미래 데이터를 예측하고자 할 경우에는 데이터를 섞어서는 안 된다. 이런 문제는 훈련 데이터셋에 있는 데이터보다 테스트 데이터셋의 모든 데이터가 미래의 것이어야 한다.
- 데이터 중복 : 각 훈련, 검증, 테스트 데이터셋에는 데이터 포인트의 중복이 있어서는 안 된다. 데이터가 중복되면 올바른 평가를 할 수 없기 때문이다.
참고 : 케라스 창시자에게 배우는 딥러닝
'A·I' 카테고리의 다른 글
Regularization과 딥러닝의 일반적인 흐름 정리 (0) | 2019.01.13 |
---|---|
[keras] Boston Housing 데이터를 통한 주택 가격 예측(regression) (0) | 2019.01.05 |
[keras] tensorflow-gpu ImportError 해결 및 keras 간단 설치 (0) | 2019.01.04 |
[Keras] 뉴스 기사 토픽 분류로 보는 다중 분류(multi-classification) (0) | 2018.12.26 |
딥러닝, 머신러닝, 패턴인식 뭐가 다를까? (0) | 2018.12.26 |
댓글