본문 바로가기

AI Theory/key concept of AI

[케라스 창시자에게 배우는 딥러닝] ch5 딥러닝 모델의 일반화, 성능 평가 방법

[KR] keras_DL_CH5_

ch5 예상문제

Q1. 최적화와 일반화에 대해 설명하라(180P)

최적화는 가능한 훈련 데이터 내에서 최고의 성능을 얻으려고 모델을 조정하는 과정이다.

일반화는 훈련된 모델이 이전에 본 적 없는 데이터에서 얼마나 잘 수행되는지를 의미한다.

머신러닝의 목표는 좋은 일반화 성능을 얻는 것이다. 모델을 훈련데이터에 대해 최적화하려고만 하면 과대적합이 시작되고 일반화 성능이 나빠진다.

Q2. 과대적합은 데이터가 어떤 경우 발생할 가능성이 높아지는가?

데이터에 잡음이 있거나, 불확실성이 존재하거나 드문 특성이 포함되어 있을 때 과대적합이 발생할 가능성이 높다.

딥러닝 모델의 일반화

모델을 학습하면 label과 feature 사이에 아무런 관계까 없지만 train loss가 감소한다. 그러나 이러한 상황에서 가능한 일반화가 없기 때문에 validation loss는 향상되지 않는다.

이런 경우 딥러닝 모델의 일반화는 어떻게 이루어질까? 파이썬 딕셔너리의 key와 value가 매핑되는 것처럼 feature과 label을 매핑하여 학습하는 것일까? 만약 그렇다면 이러한 매핑이 새로운 입력에 대해 제대로 작동할까?

결국 딥러닝에서 일반화의 본질은 딥러닝 모델 자체와 거의 관련이 없고 실제 세상의 정보 구조와 많은 관련이 있다.

매니폴드 가설

매니폴드란 수학적인 개넘으로, 일반적으로 고차원 공간에서의 부분공간(subspace)를 의미한다.

고차원 데이터는 많은 feature를 갖고 있는데, 이때 모든 feature가 중요한 정보를 담고 있는 것은 아닐 수 있다. 이때 고차원의 데이터 구조를 이해하기 위해 고차원 데이터를 저차원의 부분공간으로 표현하는데 이 때 사용되는 개념이 매니폴드이다.

매니폴드 가설이란 실제 세상의 모든 데이터가, 이 데이터가 인코딩된 고차원 공간 안에 있는 저차원 매니폴드에 놓여 있다고 가정한다.

이때 고차원 공간에서 중요한 정보를 가진 feature들은 고차원 공간에서 모두 독립적으로 분포하는 것이 아니라 저차원의 부분공간에 더 밀집되어 분포하게 되고 데이터의 특성들이 연관되어 있어 subspace에서 더 의미있는 관계를 형성할 수 있다.

이러한 매니폴드 가설에 기반하여 차원축소 기법은 고차원의 데이터를 저차원의 부분공간으로 표현함으로써 데이터의 구조를 이해하고 중요한 정보를 잘 보존하고 데이터의 효과적인 분석을 돕는다.

  • 머신러닝 모델은 가능한 입력 공간 안에서 비교적 간단하고, 저차원적이며, 구조적인 부분공간 즉 잠재 매니폴드(latent manifold)만 학습하면 된다.
  • 이러한 매니폴드 중 하나 안에서 두 입력 사이를 보간(interpolation)하는 것이 항상 가능하다. 즉 연속적인 경로를 따라 한 입력에서 다른 입력으로 변형할 시 모든 포인트가 매니폴드에 속한다.

이때 샘플 사이를 보간하는 능력이 바로 딥러닝에서의 일반화를 이해하는 열쇠이다.

보간(interpolation) 이란 불연속적인 데이터포인트 사이에 존재하는 값을 예측/추정하는 기술이다. 이러한 불연속적 데이터포인트들은 주어진 샘플의 값을 나타내며, 보간은 이러한 샘플들 사이에 존재하는 값들을 추정하는데 사용된다.

보간은 이전에 본 것과 매우 가까운 것을 이해하는 것, 즉 직관이나 패턴인식 등의 지역 일반화에 도움을 준다. 사람은 보간 이외의 인지 매커니즘으로 궁극 일반화(extreme generalization)을 할 수 있으며 이에 따라 추상화, 세상에 대한 상징적 모델, 추론, 논리 등의 선천적 능력이 존재한다.

매니포드 관련 글

머신러닝 모델의 평가

데이터의 수가 적을 경우 단순 홀드아웃 검증(hold-out validation), k-fold validation, iterated k-fold cross validation을 이용해 훈련을 진행할 수 있다.

hold-out validation

  • 데이터의 일정량을 테스트 세트로 떼어 두는 것
  • 남은 데이터로 훈련하고 테스트 세트로 평가
# hold out validation 사례
num_validation_samples = 10000
np.random.shuffle(data)
validation_data = data[:num_validation_samples]
training_data = data[num_validation_samples:]
model = get_model()
model.fit(training_data, ...)
validation_score = model.evaluate(validation_data, ...)
# 하이퍼파라미터 튜닝 후 테스트데이터 제외 전체 데이터로 모델 재훈련
model = get_model()
model.fit(np.concatenate([training_data, validation_data]), ...)
test_score = model.evaluate(test_data, ...)
  • 데이터가 적은 경우 검증 세트와 테스트 세트의 샘플이 너무 적어 주어진 전체 데이터를 통계적으로 대표하지 못할 수 있음
  • 다른 난수 초깃값으로 셔플링해서 데이터를 나누었을 때 모델의 성능이 매우 달라진다면 바로 이 문제

k-fold validation

  • 데이터를 동일한 크기를 가진 k개의 분할로 나누고 각 분할 i에 대해 남은 k-1개의 분할로 모델을 훈련하고 분할 i에서 모델을 평가한다. 최종 점수는 이렇게 얻은 k개의 점수를 평균화한다.
  • 모델의 성능이 데이터 분할에 따라 편차가 클 때 도움이 된다.
  • 사이킷런의 cross_validate()를 통해 쉽게 구현 가능
k = 3
num_validation_samples = len(data)//k
np.random.shuffle(data)
validation_scores = []

for fold in range(k):
    validation_data = data[num_validation_samples * fold:num_validation_samples*(fold+1)]
    training_data = np.concatenate(data[:num_valdation_samples*fold], data[num_validataion_samples*(fold+1):])

    model = get_model()
    model.fit(training_data, ...)
    validation_score = model.evaluate(validation_data, ...)
    validation_scores.append(validation_score)
    validation_score = np.average(validation_scores)

# 전체 데이터로 모델 다시 학습
model = get_model()
model.fit(data, ...)
test_score = model.evaluate(test_data, ...)

iterated k-fold cross validation

  • 비교적 가용 데이터가 적고 가능한 정확하게 모델을 평가하고자 할 때 사용
  • 캐글 경연에서 크게 도움되는 방법
  • k-fold 교차검증을 여러번 적용하되 k개의 분할로 나누기 전 매번 데이터를 무작위로 섞음
  • 최종 점수는 모든 k-fold를 실행해서 얻은 점수의 평균이 됨
  • 즉, p*k개의 모델을 훈련하고 평가

상식 수준의 기준점 넘기

  • 딥러닝 모델을 훈련할 때 모델의 성능에 대한 간단한 기준점을 정해야 한다.
  • 모델이 이러한 기준점을 넘으면 제대로 작동하고 있는 것이다.
  • 이 기준점은 랜덤한 분류기의 성능이거나 머신러닝을 사용하지 않고 생각할 수 있는 가장 간단한 방법이다.
  • 예를 들어 이진 분류 문제에서 90% 샘플이 a이고 10%가 b인 경우 a로 예측하게 하는 이진분류기의 정확도는 랜덤 분류기의 성능인 0.9 이상이어야 한다.

상식 수준의 기준점 넘기

  • 딥러닝 모델을 훈련할 때 모델의 성능에 대한 간단한 기준점을 정해야 한다.
  • 모델이 이러한 기준점을 넘으면 제대로 작동하고 있는 것이다.
  • 이 기준점은 랜덤한 분류기의 성능이거나 머신러닝을 사용하지 않고 생각할 수 있는 가장 간단한 방법이다.
  • 예를 들어 이진 분류 문제에서 90% 샘플이 a이고 10%가 b인 경우 a로 예측하게 하는 이진분류기의 정확도는 랜덤 분류기의 성능인 0.9 이상이어야 한다.

모델 평가 방식을 선택할 때 유의할 점

  • 대표성 있는 데이터 : 훈련 세트와 테스트 세트가 주어진 데이터에 대한 대표성이 있어야 한다. 따라서 데이터셋 분할 전 suffle로 데이터를 무작위로 섞어야 한다.
  • 시간의 방향: 그러나 시계열 데이터의 경우, 데이터를 무작위로 섞으면 안된다. 훈련 세트의 데이터보다 테스트 세트의 데이터가 미래의 것이어야 한다.
  • 데이터 중복: 데이터셋에 중복값이 있을 경우 훈련 세트의 sample이 테스트 세트의 sample에 있을 수 있으므로 데이터가 중복되어선 안된다.

훈련 성능 향상시키기

  • 최적적합 모델을 얻기 위해선 일단 일반화 능력을 보이는 과대적합 모델을 얻어야 한다. 그리고나서 그 모델의 과대적합과 싸워 일반화 성능을 개선해야 한다.
  • 이때 다음과 같은 문제들이 발생한다.
    • 시간이 지나도 훈련 손실이 줄어들지 않음
    • 훈련은 되는데 모델이 의미있는 일반화수준, 즉 기준점 이상을 넘지 못함
    • 시간이 지남에 따라 훈련과 검증 손실이 모두 줄고 일반화의 기준점 이상을 넘지만 여전히 과소적합 상태임
  • 이러한 이슈들을 해결하여 상식수준의 기준점을 넘고 일반화 능력이 있으며 과대적합할 수 있는 모델을 구하는 법을 알아보자.

1. 시간이 지나도 훈련 손실이 줄지 않음 : 경사하강법의 핵심 파라미터 튜닝

  • 모델 훈련이 시작되지 않거나 너무 일찍 중단되는 경우 무조건 경사하강법 설정에 문제가 있는 것
  • 경사하강법의 파라미터: 옵티마이저, 가중치 초깃값, 학습률, 배치 크기 등
  • 모든 파라미터는 상호의존적이므로 일반적으로 학습률과 배치크기를 튜닝하는 것으로 충분
    • 학습률을 낮추거나 높인다
    • 배치 크기를 증가시킨다. 배치 샘플을 더 늘리면,큰 데이터를 사용함에 따라 잡음이 적고 분산이 낮은 그래디언트가 만들어진다. 따라서 더 안정적인 학습을 가능하게 하며 그래디언트의 방향이 더 정확할 가능성이 높다.

2. 훈련은 되는데 검증 지표가 개선되지 않음 : 구조에 대해 더 나은 가정하기

  • 이러한 상황의 원인들은 다음과 같다
    • 입력 데이터의 타깃 예측을 위한 데이터가 충분하지 않아 일반화될 수 없다.
    • 현재 사용하는 모델의 종류가 문제에 적합하지 않다 >> 일반화를 달성하려면 문제에 대해 올바른 가정을 하는 모델을 사용해야 한다.

3. 모델 용량 늘리기

  • 모델을 훈련했지만 훈련데이터를 여러번 반복한 뒤에도 과대적합되지 못하는 것은 모델의 표현능력(representation power)이 부족한 것이다.
  • 따라서 층을 추가하거나, 층 크기를 늘리거나, 현재 문제에 더 적합한 종류의 층을 사용하여 모델의 용량을 키워야한다.

일반화 성능 향상하기

모델이 어느정도 일반화 성능을 갖고 과대적합 가능한 경우 모델의 일반화 능력을 극대화하는 방향으로 진행한다.

1. 데이터 큐레이션

  • 데이터를 사용하여 샘플 사이를 부드럽게 보간할 수 있다면 일반화 성능을 가진 딥러닝 모델을 훈련할 수 있을 것이다.
  • 그러나 이 때 데이터에 잡음이 많거나 리스트 정렬처럼 불연속적인 데이터일 경우 딥러닝은 도움이 되지 않는다.
  • 따라서 딥러닝 모델을 생성하기 전 적절한 데이터셋으로 작업하고 있는지 반드시 확인해야 한다.
    • 데이터가 충분한지 확인한다.
    • 레이블 할당 에러를 최소화한다.
    • 데이터를 정제하고 누락된 값을 처리한다.
    • 많은 특성들 중 유용한것을 확인할 수 없다면 특성 공학(feature engineering)을 수행한다.

2. 특성 공학

  • 모델에 데이터를 주입하기 전 하드코딩된 변환을 적용해 알고리즘이 더 잘 수행되도록 만들어 준다.
  • 특성 공학은 특성을 더 간단한 방식으로 표현하여 문제를 쉽게 만들고, 잠재 매니폴드를 더 매끄럽고, 간단하고, 구조적으로 만든다.
  • 최신 딥러닝은 자동으로 원본 데이터에서 유용한 특성을 추출할 수 있어 대부분 특성 공학이 필요하지 않다. 그러나 다음과같은 관점에서 특성 공학이 필요하다.
    • 좋은 특성은 적은 자원을 사용하여 문제를 더 멋있게 풀 수 있다.
    • 좋은 특성은 더 적은 데이터로 문제를 풀 수 있다.

3. 조기 종료 사용

  • 훈련 중 일반화 성능이 가장 높은 정확한 최적적합 지점(과소적합과 과대적합 사이 정확한 경계)를 찾는 것은 일반화 성능을 향상시킬 수 있는 가장 효과적인 방법 중 하나이다
  • 조기종료는 케라스의 earlystopping callback을 사용해서 epoch 진행 중 검증 지표가 더 이상 향상되지 않을 시 훈련을 중지하고 그 전까지 최상의 검증 점수를 낸 모델을 남긴다.

4. 모델 규제

  • 규제 기법은 모델이 훈련 데이터에 완벽하게 맞추려는 것을 방해하는 기법이다. 이를 통해 모델의 검증 점수를 향상시킬 수 있다.
  • 규제 기법은 모델을 더 간단하고 일반적인 경향을 띄게 만들어서 훈련 세트에 덜 특화되고 데이터의 잠재 매니폴드를 조금 더 가깝게 근사함으로써 일반화 능력을 높일 수 있다.
  • 모델 규제는 항상 정확한 평가 절차를 따라야 한다. 즉 측정이 가능한 경우에만 일반화를 달성할 수 있다.
  • 모델을 규제하기 위해 모델의 너무 많은 용량과 부족한 용량 사이의 절충점을 찾아야 한다.
  • 비교적 적은 수의 층과 파라미터로 시작해서, 검증 손실이 감소되기 시작할 때까지 층이나 유닛 개수를 늘리는 방법밖에 없다.