LITTLE BY LITTLE

[4] 케라스 창시자에게 배우는 딥러닝 - 4. (머신러닝) 분류, 특성 공학, 특성 학습, 과/소적합, 해결법(가중치 규제,드롭아웃 추가..) 본문

데이터 분석/케라스 창시자에게 배우는 딥러닝

[4] 케라스 창시자에게 배우는 딥러닝 - 4. (머신러닝) 분류, 특성 공학, 특성 학습, 과/소적합, 해결법(가중치 규제,드롭아웃 추가..)

위나 2022. 8. 11. 11:30

제 4부. 머신러닝의 기본 요소

  1. 머신러닝의 네 가지 분류
  2. 머신러닝 모델 평가
  3. 데이터 전처리, 특성 공학, 특성 학습
  4. 과대적합과 과소적합
  5. 보편적인 머신러닝 작업 흐름
  6. 요약
더보기

 

제 5부.컴퓨터 비전을 위한 딥러닝

  1. 합성곱 신경망 소개
  2. 소규모 데이터셋에서 밑바닥부터 컨브넷 훈련하기
  3. 사전 훈련된 컨브넷 사용하기
  4. 컨브넷 학습 시각화
  5. 요약

제 6부. 텍스트와 시퀀스를 위한 딥러닝

  1. 텍스트 데이터 다루기
  2. 순환 신경망 이해하기
  3. 순환 신경망의 고급 사용법
  4. 컨브넷을 사용한 시퀀스 처리
  5. 요약

제 7부. 딥러닝을 위한 고급 도구

  1. Sequential 모델을 넘어서 : 케라스의 함수형 API
  2. 케라스 콜백과 텐서보드를 사용한 딥러닝 모델 검사와 모니터링
  3. 모델의 성능을 최대화로 끌어올리기
  4. 요약

제 8부. 생성 모델을 위한 딥러닝

  1. LSTM으로 텍스트 생성하기
  2. 딥드림
  3. 뉴럴 스타일 트랜스퍼
  4. 변이형 오토인코더를 사용한 이미지 생성
  5. 적대적 생성 신경망 소개
  6. 요약

제 9부. 결론

  1. 핵심 개념 리뷰
  2. 딥러닝의 한계
  3. 딥러닝의 미래
  4. 빠른 변화에 뒤처지지 않기
  5. 맺음말

4-1. 머신러닝의 네가지 분류

  • 이전 예제에서 다룬 문제는 머신 러닝 문제인 이진 분류, 다중 분류, 스칼라 회귀였다. 이 셋은 모두 지도학습의 예이다. 지도 학습의 목표는 훈련 데이터의 입력과 타깃 사이에 있는 관계를 학습하는 것이다. 머신 러닝 알고리즘은 4개의 커다란 범주 안에 속한다.

4.1.1 지도 학습

  1. 가장 흔한 경우로, 종종 사람이 레이블링한 샘플 데이터가 주어지면 알고있는 타깃(꼬리표 annotation이라고 하기도 함)에 입력 데이터를 매핑하는 방법을 학습한다. 
  2. 광학 문자 판독, 음성 인식, 이미지 분류, 언어 번역과 같은 딥러닝의 거의 모든 애플리케이션이 이 범주에 속한다.
  3. 지도 학습은 대부분 분류와 회귀로 구성되지만, 특이한 변종도 많다. 
    1. 시퀀스 생성 : 사진이 주어지면 이를 설명하는 캡션을 생성한다. 시퀀스에 있는 단어나 토큰을 반복적으로 예측하는 것처럼 일련의 분류문제로 재구성할 수 있다.
    2. 구문 트리 : 문장이 주어지면 분해된 구문을 예측한다.
    3. 물체 감지 : 사진이 주어지면 사진 안의 특정 물체 주의에 경계 상자를 그린다. 이는 많은 경계 상자 후보가 주어졌을 때 각 상자의 내용을 분류하는 분류문제로 표현되거나, 경계 상자의 좌표를 벡터 회귀로 예측하는 회귀와 분류가 결합된 문제로 표현할 수 있다.
    4. 이미지 분할 : 사진이 주어졌을 때 픽셀 단위로 특정 물체에 마스킹을 한다.

4.1.2 비지도 학습

  1. 어떤 타깃도 사용하지 않고, 입력 데이터에 대한 흥미로운 변환을 찾는다. 
  2. 데이터 시각화, 데이터 압축, 데이터의 노이즈 제거 또는 데이터에 있는 상관관계를 더 잘 이해하기 위해 사용한다. 
  3. 지도 학습 문제를 풀기 전, 데이터셋을 더 잘 이해하기위해 필수적으로 거치는 단계이다. 
  4. 차원 축소, 군집이 비지도학습에서 잘 알려진 범주이다.

4.1.3 자기 지도 학습

  1. 지도학습의 특별한 경우이나, 별도의 범주로 볼 수 있을 만큼 다르다.
  2. 지도학습이긴 하지만, 사람이 만든 레이블을 사용하지 않는다. 즉, 학습과정에 사람이 개입하지 않는 지도학습이다. 
  3. 학습이 무언가에 의해 지도되어야 하므로 레이블이 여전히 필요하지만, 보통 경험적인 알고리즘을 사용해서 입력데이터로부터 생성한다.
  4. ex. 오토인코더 - 생성된 타깃은 수정하지 않은 원본입력이다. 
  5. 같은 방식으로 지난 프레임이 주어졌을 때, 비디오의 다음 프레임을 예측하는 것이나, 이전 단어가 주어졌을 때 다음 단어를 예측하는 것이 자기 지도 학습의 예이다. (이 경우는 시간에 따른 지도학습 temporally supervised learning이다.)
  6. 학습 메커니즘과 애플리케이션 측면 중 어디에 중점을 두는지에 따라서 지도 학습 또는 비지도 학습으로 재해석 될 수 있다.

4.1.4 강화 학습

  1. 오랫동안 간과되었지만, 최근 구글 딥마인드가 아타리 게임 플레이를 학습하는데 성공적으로 적용하며 많은 관심을 받기 시작했다. 
  2. 강화 학습에서 에이전트는 환경에 대한 정보를 받아 보상을 최대화하는 행동을 선택하도록 학습된다.
  3. ex. 강화학습으로 훈련된 신경망은 비디오 게임 화면을 입력으로 받고, 게임 점수를 최대화하기 위한 행동을 출력할 수 있다.
  4. 현재 대부분 연구 영역에 속해있고, 게임 이외에 실제 성공적인 사례는 아직 없다.
  5. 자율 주행 자동차, 자원 관리, 교육 등의 애플리케이션이 강화학습이 대체할 것으로 기대되고 있다.
* (참고) 분류와 회귀에서 사용하는 용어
- 샘플 또는 입력 : 모델에 주입될 하나의 데이터 포인트
- 예측 또는 출력 : 모델로부터 나옹는 값
- 타깃 : 정답, 외부 데이터소스에 근거하여 모델이 완벽하게 예측해야하는 값
- 예측 오차 또는 손실 값 : 예측과 타깃 사이의 거리를 측정한 값
- 클래스 : 분류 문제에서 선택할 수 있는 가능한 레이블의 집합. ex.고양이와 강아지 사진 분류시 2개의 클래스
- 참 값 또는 꼬리표 : 데이터셋에 대한 모든 타깃,일반적으로 사람에 의해 수집됨
- 이진 분류 : 각 입력 샘플이 2개의 배타적인 범주로 구분
- 다중 분류 : 각 입력 샘플이 2개 이상의 범주로 구분, ex. 손글씨 숫자 분류
- 스칼라 회귀 : 나킷이 연속적인 스칼라 값인 작업, ex. 주택 가격 예측, 각기 다른 타깃 가격이 연속적 공간을 형성
- 벡터 회귀 : 타깃이 연속적인 값의 집합, ex. 연속적인 값으로 이루어진 벡터 
- 미니 배치 또는 배치 : 모델에 의해 동시에 처리되는 소량의 샘플 묶음 (보통 8~128개 사이) 훈련할 때 미니 배치마다 한 번씩 모델의 가중치에 적용할 경사 하강법 업데이트 값을 계산함

4.2 머신 러닝 모델 평가

  1. 앞서 예제에서 데이터를 총 3개, 훈련/검증/테스트 세트로 나누었다. 훈련에 사용된 동일한 데이터로 모델을 평가하지 않는 이유는, 몇 번의 에포크 후에 3개의 모델이 모두 과대적합되기 시작했기 때문이다. 즉, 훈련 데이터 성능에 비해 처음 본 데이터에 대한 성능이 좋아지지 않는다. 반면, 훈련 데이터의 성능은 훈련이 진행될 수록 항상 증가된다.
  2. 머신 러닝의 목표는 "처음 본 데이터에서 잘 작동하는 일반화된 모델을 얻는 것(일반화)"이다. 따라서 여기에 과대적합은 주요 장애물이 된다.
  3. 관측할 수 있는 것만 제어할 수 있으므로, 모델의 일반화 성능에 대한 신뢰할 수 있는 측정 방법이 아주 중요하다

4.2.1 훈련, 검증, 테스트 세트

  1. 모델 평가의 핵심은 가용한 데이터를 위 3가지로 나누는 것. 훈련 세트에서 모델을 훈련, 검증 세트에서 모델을 평가, 모델을 출시할 준비가되면 테스트 세트에서 최종적으로 한 번 모델을 테스트.
  2. 검증 세트를 사용하는 이유는 모델을 개발할 때 항상 모델의 설정을 튜닝하기 때문이다. Ex. 층의 수나 유닛 수 등의 하이퍼 파라미터를 선택) 이런 튜닝은 검증 세트에서 모델의 성능을 평가해야 수행할 수 있다. 
  3. 하지만, 검증 세트의 성능을 기반으로 모델의 설정을 튜닝하면 검증세트로 모델을 직접 훈련하지 않더라도 검증세트에 과적합 될 수 있다. 이 현상의 핵심은 "정보 누설"개념에 있다. 하이퍼 파라미터를 조정할 때마다 검증 데이터에 관한 정보가 모델로 새는 현상이다.
  4. 튜닝 후 검증 세트에 평가한 결과를 가지고 다시 모델을 조정하는 과정을 여러번 반복할시, 검증 세트에 관한 정보를 모델에 아주 많이 노출시키게 되기 때문이다.
  5. 모델은 간접적으로라도 테스트 세트에 대한 어떤 정보도 얻어서는 안된다. 테스트 세트 성능에 기초하여 튜닝한 모델의 모든 설정은 일반화 성능을 왜곡시키기 때문
  6. 3가지 세트로 나눌 때, 데이터가 적을 때에는 몇가지 고급 기법을 사용하면 좋다.
    1. hold-out validation 단순 홀드아웃 검증
      • 데이터의 일정량을 테스트 세트와 검증세트로 떼어놓는다. 
      • (단점) 데이터가 적을시, 테스트 세트와 검증 세트의 샘플이 너무 적어 주어진 전체 데이터를 통계적으로 대표하지 못할 수 있음. 데이터가 대표하지 못하는지 확인하려면 "다른 난수 초깃값으로 셔플링해서 데이터를 나누었을 때 모델의 성능이 매우 달라지는지 확인 "하면 된다. 여기서 대표하지 못할경우 다음2가지 방법 사용
    2. k-fold cross validation k겹 교차 검증
      • 데이터를 동일한 크기를 가진 k개 분할로 나눈다. 각 분할 i에 대해 남은 k-1개의 분할로 모델을 훈련하고, 분할 i에서 모델을 평가한다. 최종 점수는 얻은 k개 점수의 평균
      • 모델의 성능이 데이터 분할에 따라 편차가 클 때 도움이 되는 방법
      • 홀드 아웃 검증처럼 이 방법은 모델의 튜닝에 별도의 검증 세트를 사용함
    3. iterated k-fold cross validation 셔플링을 사용한 k겹 교차 검증
      • 이 방법은 비교적 가용 데이터가 적고, 정확하게 모델을 평가하고자 할 때 사용
      • k-fold cv를 여러번 적용하되, k개의 분할로 나누기 전에 매번 데이터를 무작위로 섞는다.
      • 최종 점수는 모든 k-fold cv를 실행해서 얻은 점수의 평균이 된다. 결국 p(반복횟수) * k개의 모델을 훈련하고 평가하므로 비용이 매우 많이 듦

홀드아웃 구현 예

# 홀드아웃 검증 구현 예 
num_validation_samples = 10000
np.random.shuffle(data)

validation_data = data[:num_validation_samples] #검증 세트 생성
data = data[num_validation_samples:]

training_data = data[:] # 훈련 세트 만들기
model = get_model()
model.train(training_data) 
validation_score = model.evaluate(validation_data) # 훈련세트에서 훈련, 검증세트로 평가

# 이 사이 과정에서 튜닝 과정 반복

model_get_model()
model.train(np.concatenate([training_data, validation_data]))) 
#하이퍼 파라미터 튜닝이 끝나면 테스트 데이터를 제외한 모든 데이터로 재훈련

test_score = model.evaluate(test_data)

k-fold cv 구현 예

# k-fold cv 구현 예
k=4
num_validation_samples = len(data) // k
np.random.shuffle(data)

validation_score=[]
for fold in range(k):
    validation_data = data[num_validation_samples * fold:
    num_validation_samples * (fold+1):]
    training_data = data[:num_validation_samples * fold]+
    data[num_validation_samples * (fold+1):]

    model =get_model() # 훈련되지 않은 새로운 모델을 만듦
    model.train(training_data)
    validation_score = model.evaluate(validation_data)
    validation_scores.append(validation_score)

* 평가 방식 선택시 주의해야할 점

  1. 훈련 세트와 테스트 세트가 주어진 데이터에 대한 대표성이 있어야한다.
    • ex. 숫자 이미지 분류 문제에서 배열의 처음 80%를 훈련 세트로, 20%를 테스트세트로 만들면, 훈련세트에는 0-7 숫자만, 테스트 세트에는 8-9 숫자만 담기게됨 X
  2. 시간의 방향 
    • 과거로부터 미래를 예측하려고 한다면, 데이터를 분할하기 전 무작위로 섞어서는 안된다. 무작위로 섞을시 미래의 정보가 누설되기 때문이다. (모델이 사실상 미래 데이터에의해 훈련이 될 것)
    • 이런 문제에서는 훈련 세트에 있는 데이터보다 테스트 세트에 있는 모든 데이터가 미래의 것이어야 한다.
  3. 데이터 중복
    • 한 데이터셋에 어떤 데이터 포인트가 두 번 등장하면, 데이터를 섞고 나누었을 때 데이터 포인트가 중복될 수 있다. 훈련 데이터의 일부로 테스트하는 최악의 경우가 된다.

4.3 데이터 전처리, 특성 공학, 특성 학습

  1. 신경망에 입력 데이터와 타깃 데이터를 주입하기 전 준비해야할 과정 
  2. 많은 데이터 전처리와 특성 공학 기법은 특정 도메인(ex.텍스트/이미지 데이터에 특화되어 있음)에 종속적이다.
  3. 모든 종류의 데이터에 공통되는 기본 사항부터 살펴보자.

4.3.1 신경망을 위한 데이터 전처리 (벡터화, 정규화, 누락된 값 다루기, 특성 추출)

  1. 데이터 벡터화
    1. 신경망에서 모든 입력과 타깃은 부동 소수 데이터로 이루어진 텐서이어야 한다. (특정 경우, 정수로 이루어진 텐서) 따라서 사운드,이미지,텍스트 등 처리해야 할 것이 무엇이든지 먼저 텐서로 변환해야 함
    2. ex. 이전의 텍스트 분류 예제 (이중,다중분류)에서 단어 시퀀스를 의미하는 텍스트를 정수 리스트로 변환하였다. 그 다음 원-핫 인코딩으로 float32 타입의 데이터로 이루어진 텐서로 바꾸었다. 주택 가격 예측 에제에서는 이미 데이터가 벡터 형태로 주어져서 이 단계를 거치지 않음
  2. 값 정규화
    1. 숫자 이미지 분류 예에서 이미지 데이터를 0-255 사이의 정수로 인코딩(그레이스케일 인코딩)하였다. 네트워크에 주입하기 전, float32 타입으로 변경, 255로 나누어 최종적으로 0~1 사이의 부동 소수 값으로 만듦
    2. 주택 가격 예측 예제에서는 특성들의 범위가 제각각 이었다. 어떤 특성은 작은 부동 소수값, 다른 특성은 매우 큰 정수 값이었기에, 각 특성을 독립적으로 정규화하여 평균이 0, 표준편차가 1이되도록 만듦
    3. 비교적 큰 값 (네트워크 가중치 초깃값보다 훨씬 큰 여러자릿수를 가진 정수)이나 균일하지 않은 데이터 (한 특성의 범위는 0-1, 다른 특성은 100-200) 를 신경망에 주입하는 것은 위험하다. (← 업데이트할 그래디언트가 커져 네트워크가 수렴하는 것을 방해하기 때문)
      • 따라서 작은 값을 취해야 하고(0-1사이)
      • 균일해야 한다. 모든 특성이 대체로 비슷한 범위를 가져야 함
    4. 엄격한 정규화 방법 (필수적이진 않으나, 자주 사용되고 도움이 될 수 있음) 
      • 각 특성별로 평균은 0이 되도록, 표준편차는 1이 되도록 정규화한다.
      • 넘파이 배열에서 하는 방법은 간단함
      • x -= x.mean(axis=0)
      • x /= x.std(axis=0)
  3. 누락된 값 다루기
    1. 일반적으로 신경망에서 0이 사전에 정의된 의미있는 값이 아니라면 누락된 값을 0으로 입력해도 괜찮다. 네트워크가 0이 누락된 데이터를 의미한다는 것을 학습하면, 이 값을 무시할 것이다.
    2. 테스트 데이터에 누락된 값이 포함될 가능성이 있고, 네트워크가 누락된 값이 없는 데이터에서 훈련되었다면, 이 네트워크는 누락된 값을 무시하는 법을 알지 못한다. 이런 경우, 누락된 값이 있는 훈련 샘플을 고의적으로 만들어야한다. 훈련 샘플의 일부를 여러번 복사해서, 테스트 데이터에서 빠질 것같은 특성을 제거한다.

4.3.2 특성 공학

  1. 모델에 데이터를 주입하기 전에, 학습이 아닌 '하드코딩'된 변환을 적용하여 알고리즘이 더 잘 수행되도록 해줌
  2. 임의의 데이터로부터는 완벽한 학습을 하기 어렵기에, 모델이 수월하게 작업할 수 있는 어떤 방식으로 데이터가 표현될 필요가 있다. 
  3. ex. 시계 이미지를 입력으로 받고, 하루의 시간을 출력하는 모델을 개발한다고 가정해보자.
    1. 이미지의 원본 픽셀을 입력으로 사용한다면, 어려운 머신러닝 문제가 될것 (합성곱 신경망이 필요하기 때문,많은 컴퓨팅 자원이 필요함)
    2. 하지만, 고수준에서 이 문제를 이해하고 있다면 (우리는 시계가 시간을 읽는 방법을 알고있다.)머신러닝 알고리즘을 위해 훨씬 더 좋은 입력 특성을 만들 수 있다.
    3. 예를 들어, 시계 바늘의 검은색 픽셀을 따라 각 바늘 끝의 (x,y) 좌표를 출력하는 간단한 파이썬 스크립트를 만든다. 그 다음 머신러닝 알고리즘이 이 좌표와 적절한 시각을 연결하도록 쉽게 학습될 수 있음
    4. 더 좋은 특성을 만들 수도있다. 좌표를 바꾸어 (x,y) 포인트를 '이미지 중심에 대한 극좌표'로 나타내는 것이다. 각 시계 바늘의 각도가 입력된다. 이렇게 특성을 준비해놓으면, 문제가 쉬워져서 머신러닝조차 필요없게 된다. 간단한 반올림 연산과 딕셔너리 참조만으로 하루의 시간을 추정할 수 있음.
    5. 이렇듯 특성을 더 간단한 방식으로 표현함으로써, 문제 자체를 쉽게 만들어준다. 그 문제를 잘 이해하고있는 것이 중요
    6. 최근 딥러닝은 대부분 특성공학이 필요하지 않는데, 그 이유는 신경망이 자동으로 원본 데이터에서 유용한 특성을 추출할 수 있기 때문, 하지만 그래도 여전히 신경써야한다. 그 이유는
      1. 좋은 특성은 적은 자원을 사용하여 문제를 더 잘 풀 수 있다. 시계 바늘읽는 문제에 합성곱 신경망을 사용하는 것은 어울리지 않음
      2. 좋은 특성은 더 적은 데이터로 문제를 풀 수 있다. 딥러닝 모델이 스스로 특성을 학습하는 능력은 훈련 데이터가 많을 때 잘 발휘되므로, 샘플의 개수가 적을시 특성에 있는 정보가 매우 중요해져 특성공학이 더 필요함.

특성 공학 예시 - 시계 바늘 읽기


4.4 과대적합과 과소적합

  1. 머신러닝의 근본적 이슈는 최적화와 일반화 사이의 줄다리기이다. 훈련 데이터에서 최고의 성능을 얻기위해 모델을 조정해야하지만, 훈련된 모델이 이전에 본 적 없는 데이터에서도 얼마나 잘 수행되는지도 중요하다.
  2. 훈련 초기에 이 최적화와 일반화는 상호연관 되어있다. 훈련 데이터의 손실이 낮아질수록, 테스트 데이터의 손실도 낮아진다. → "과소 적합" : 네트워크가 훈련 데이터의 특성을 모두 학습하지 못했으므로, 모델의 성능이 계속 발전될 여지가 있다.
  3. 훈련데이터에 여러번 반복 학습하고 나면 어느 시점부터 일반화 성능이 더 이상 높아지지 않는다. 검증 세트의 성능이 멈추고, 감소되기 시작 → 과대적합
  4. 과대 적합 해결 방법 (과대적합을 피하는 처리 과정을 '규제'라 한다.)
    1. 데이터를 더 모은다.
    2. 모델이 수용할 수 있는 정보의 양을 조절하거나, 저장할 수 있는 정보에 제약 가하기 - 네트워크가 적은 수의 패턴만 기억할 수 있다면, 최적화 과정에서 가장 중요한 패턴에 집중하게 될 것. 이런 패턴은 더 나은 일반화 성능을 제공할 수 있다.

4.4.1 네트워크 크기 축소

  1. 과대 적합을 막는 각장 단순한 방법은 모델의 크기, 즉 모델에 있는 학습 파라미ㅌ 수를 줄이는 것
  2. 파라미터의 수는 층의 수와 각 층의 유닛 수에 의해 결정되는데, 딥러닝에서 모델에 있는 학습 파라미터의 수를 모델의 '용량(capacity)'이라고 한다. 따라서 당연히 파라미터가 많은 모델이 기억 용량이 더 많다.
  3. 훈련 샘플과 타깃 사이를 딕셔너리와 같은 일대일 매핑으로 완벽하게 학습할 수도 있다. 하지만 이런 매핑은 일반화 능력이 없다. 새로운 샘플을 분류하는데에 전혀 쓸모없는 모델 
  4. 항상 유념해야할 점은 딥러닝 모델은 훈련 데이터에 잘 맞추려는 경향이 있다는 점이다. 진짜 문제는 최적화가 아니고 '일반화''이다.
  5. 다른 한편으로는 과소적합 되지 않도록 충분한 파라미터를 가진 모델을 사용해야 한다. 네트워크가 기억 용량에 제한이 있다면, 매핑을 쉽게 학습하지 못할 것. 또한 손실을 최소화하기 위해 타깃에 대한 예측 성능을 가진 '압축된 표현'을 학습해야 한다.
  6. 따라서 데이터에 알맞은 '모델의 크기'를 찾으려면 각기 다른 구조를 검증 세트에서 평가해야 한다. 적절한 모델 크기를 찾기 위해 비교적 적은수의 층과 파라미터로 시작하여, 검증 손실이 감소되기 시작할 때까지 층이나 유닛의 수를 늘리는 흐름이 일반적이다.
# 영화 리뷰 분류 예제 - "원본 모델"
from kears import models
from keras import layers

model = model.Sequential()
model.add(layers.Dense(16, activation='relu',
	input_shape = model.add(layers.Dense(16, activation='relu'))
model.add(layers.Denses(1, activation='sigmoid'

# "작은 용량의 모델"
model = models.Sequential()
model.add(layers.Dense(6, activation='relu',
	input_shape = (model.add(layers.Dense(6, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

굵은 원으로 표시된 부분이 용량이 작은 경우이다. 과대적합되는 epochs가 더 늦어진다.(4번째가 아닌, 6번째 에포크에서 과대적합이 시작됨), 그리고 그래프도 더 완만하다!(더 성능이 천천히 저하됨)

- 작은 네트워크가 1) 더 나중에 과대적합되기 시작했으며, 2) 과대적합이 시작되었을 때의 성능저하 속도도 더 늦다.

# 큰 용량의 모델
model = models.Sequential()
model.add(layers.Dense(1024, activation='relu',
	input_shape=(10000,)))
model.add(layers.Dense(1024, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

 

검증 데이터의 손실 그래프 (Validation loss)

- 큰 모델과 비교하였을 때, 검증 데이터의 손실에 대한 그래프에서는 굵은 점 부분을 보면, 용량이 큰 네트워크는 1번째 epoch 이후 바로 과대적합이 시작되어, 성능 저하되는 속도도 매우 빠르다. (기울기가 가파름)

- 그 이유는 용량이 많은 네트워크일수록 더 빠르게 훈련데이터를 모델링할 수 있기 때문이다. 그래서 훈련 손실이 매우 낮아지기 때문에, 훈련 손실과 검증 손실 사이에 차이가 많이 나게 되는 것 

→ 모델링 속도가 빠르다 = 훈련 손실이 매우 낮다 = 과대적합에 민감해진다.

훈련 데이터의 손실 그래프 (Training loss)

- 앞서 말했듯이, 이 훈련 데이터의 손실 그래프를 보면, 용량이 큰 네트워크에서 손실이 아주 빠르게 감소하여(굵은 점), 첫번째 그래프 검증 손실에서와 차이가 많이 난다.


4.4.2 가중치 규제 추가 ** (from keras import regularizers)

  1. 오캄의 면도날 이론 : 어떤 것에 대한 두 가지 설명이 있다면, 더 적은 가정이 필요한 간단한 설명이 옳다는 이론
  2. 신경망으로 학습되는 모델에도 적용, 데이터를 설명할 수 있는 가중치 값의 집합은 여러개이다. 간단한 모델이 복잡한 모델보다 과대적합될 가능성이 더 낮다!
    1. 여기서 말하는 간단한 모델이란, '파라미터 값 분포의 엔트로피가 작은 모델 (또는 적은 수의 파라미터를 가진 모델)'
    2. 따라서 과대적합을 완화하기 위한 첫번째 방법은 '네트워크의 복잡도에 제한을 두어 가중치가 작은 값을 가지도록 강제하는 것' → "가중치 규제"
    3. 그렇게하면 가중치 값의 분포가 더 균일해진다. 이를 가중치 규제라고 하며, 네트워크의 손실 함수에 큰 가중치에 연관된 비용을 추가한다. 두 가지 형태의 비용이 있다.
      1. L1 규제 : 가중치의 절댓값에 비례하는 비용이 추가됨 (가중치의 L1 norm)
      2. L2 규제 : 가중치의 제곱에 비례하는 비용이 추가됨 ( 가중치의 L2 norm)
      3. L2 규제는 신경망에서 가중치 감쇠(Weight decay)라고도 부른다. 동일한 개념

케라스에서 가중치 규제 객체를 키워드 매개변수로 전달해서 가중치 규제를 추가해보자. (L2가중치)

# L2 가중치 규제 추가하기
from keras import regularizers

model = models.Sequential()
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.01),
                       activation='relu',
                       input_shape=(10,000)))
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                       activation='relu'))
model.add(layers.Dense(1, acitvation='sigmoid'))

- kernel_regularizer = regularizers.l2( 0.01 ) 

의 의미는, 가중치 행렬의 모든 원소를 곱하고, 0.001을 곱하여 네트워크의 전체 손실에 더해진다는 의미이다.

- 이 패널티항은 훈련할 때만 추가된다. 

- 이 네트워크의 손실은 테스트보다 훈련할 때 더 높을 것이다.

kernel_regularizer = regularizers.l2(0.01) 적용 후 효과

- L2 가중치 규제를 적용한 결과, L2 규제 패널티의 효과는 두 모델이 동일한 파라미터 수를 가지고 있더라도, L2규제를 사용한 모델(점)이 기본 모델(덧셈 기호)보다 훨씬 더 과대적합에 잘 견디고 있다. 

- 굵은 점을 보면, 더 늦은 epoch에서 과대적합이 시작될 것이고, 성능이 저하되는 속도(loss가 증가하는 속도)가 아주 느리다.(기울기가 아주 완만)

 

이번에는 L1규제를 사용해보고, L1규제와 L2규제를 병행해보자.

from keras import regularizers

regularizers.l11(0.001) # l1규제
regularizers.l1_l1(l1=0.001,l2=0.001) # l1규제와 l2규제 병행

4.4.3 드롭아웃 추가

  1. 네트워크의 복잡도에 제한을 두는 "규제 기법" 중에서 가장 효과적이고 널리 사용되는 방법은 드롭아웃을 추가하는 방법이다.
  2. 네트워크 층에 드롭아웃을 적용하면, '훈련하는 동안 무작위로 층의 일부 출력 특성을 제외시킨다.(0으로 만든다.)'
  3. 한 층이 정상적으로 훈련하는 동안 어떤 입력 샘플에 대해 [0.2, 0.5, 1.3, 0.9, 1.1]의 벡터를 출력한다고 가정할 때, 드롭아웃을 적용하면 이 벡터의 일부가 무작위로 0으로 바뀐다. 따라서 [0, 0.5, 1.3, 0, 1.1]이 된다. 
  4. 드롭 아웃 비율 = 0이 될 특성의 비율 이다. (보통 0.2에서 0.5로 지정된다.)
  5. 테스트 단계에서는 어떤 유닛도 드롭아웃되지 않는다.그 대신, 층의 출력을 드롭아웃 비율에 비례하여 줄여준다. 훈련할 때보다 더 많은 유닛이 활성화되기 때문.
# 크기가 (batch_size, features)인 한 층의 출력을 담고 있는 넘파이 행렬을 생각해보자. 

# 1.
# 훈련할 때는 이 행렬 값 일부가 랜덤하게 0이 된다.
layer_output *= np.random.randint(0, high=2, size=layer_output.shape) #훈련시 유닛출력1/2을 버림

# 2.
# 테스트할 때는 드롭아웃 비율로 출력을 낮추어주어야 한다. 
# 여기서는 앞서 버린만큼(1/2배)만큼 스케일을 조정하였다.
layer_output *= 0.5

# 훈련 단계에서 이 두 연산을 포함시켜 테스트 단계에는 출력을 그대로 두도록 구현할 수 있다.
layer_output *= np.random_randint(0, high=2, size=layer_output.shape)
layer_output /= 0.5 # 여기에서 스케일을 낮추는 대신 높인다.

과적합을 해결하기 위해 네트워크의 복잡도를 줄이는 '규제' 중 대표적인 방법인 드롭 아웃 방법

  1. 이 드롭아웃이 과대적합을 줄이는데 도움이 되는 이유는, 드롭아웃 방법은 힌튼이 부정방지 메커니즘에서 착안하였는데, 은행에 갔을 때 은행원들이 계속 바뀌는 이유는 자주 업무가 바뀌기 때문이라는 말을 듣고, 힌튼은 은행에서 부정행위를 하려면 직원들 사이의 유대가 필요하기 때문이라고 판단하여, 각 샘플에서 뉴런의 일부를 무작위하게 제거하면 뉴런의 부정한 협업을 방지하고 결국 과대적합을 감소시킨다는 사실을 깨달았다고 한다. 
  2. 케라스에서는 층의 출력 바로 뒤에 Dropout 층을 추가하여 네트워크에 드롭아웃을 적용할 수 있다.
  3. model.add(layers.Dropout(0.5))

IMDB 네트워크에 2개의 Dropout 층을 추가하고, 과대적합을 얼마나 줄여 주는지 확인해보자.

# 네트워크에 드롭아웃 추가하기
model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

드롭아웃 적용 후, 과적합이 훨씬 늦게, 느리게 나타난다.

신경망에서 과대적합을 방지하기 위해 사용하는 방법을 정리해보면
1. 훈련데이터를 더 모은다.
2. 네트워크의 용량을 감소시킨다.
3. 가중치 규제를 추가한다.
4. 드롭아웃을 추가한다.

4.5 보편적인 머신러닝 흐름

4.5.1 문제정의 와 데이터 수집

  1.  먼저 주어진 데이터를 정의해야한다. 
    1. 입력 데이터는 무엇이며, 어떤 것을 예측하려고 하는가 - 예를 들어 영화 리뷰와 감성 렐이블이 태깅되어 있어야지만 영화 리뷰의 감성 분류를 학습할 수 있다. 가용 데이터의 유무는 이 단계에서 제한 요소가 됨
    2. 당면한 문제의 종류 - 이진 분류인지, 다중 분류인지, 스칼라 회귀인지, 벡터 회귀인지, 다중/레이블 다중 분류인지, 군집 생성 또는 강화학습같은 다른 문제인지 ... '문제를 식별해야 모델의 구조,손실함수 선택에 도움이 된다.'
    3. 입출력이 무엇인지와 어떤 데이터를 사용할 것인지 알고나서, 이 단계에서 가설을 세워야한다. 
      1. 주어진 입력으로 출력을 예측할 수 있다고 가설을 세운다.
      2. 가용한 데이터에 입력과 출력 사이의 관계를 학습하는 데 충분한 정보가 있다고 가설을 세운다.
      3. 모델 작동 후 가설이 검증될지 아닐지 알 수 있다. 
    4. 풀기 어려운 문제는 시간에 따라 변하는 문제이다. 이런 경우
      1. 최근의 데이터로 주기적으로 모델을 다시 훈련하거나,
      2. 시간 분포에 맞게 데이터를 수집하여 시간에 따라 변하지않는 문제로 바꾸어야한다.
      3. ex. 의류구매처럼 순환성이 있는 문제는 몇년치 데이터를 모으면 계절의 변화를 감지하는데 충분할 것이다. 1년 중 언제인지 기록한 시간도 모델에 입력해야 할것이다.

4.5.2 성공 지표 선택

  1. 성공의 지표가 모델이 최적화할 손실 함수를 선택하는 기준이 되고, 비즈니스 성공처럼 고수준의 목표와 직접적으로 연결되어 있어야한다.
  2. 클래스의 분포가 균일한 분류 문제에서는 accuracy와 ROC AUC가 일반적 지표이다.
  3. 클래스의 분포가 균일하지 않은 문제에서는 정밀도(precision)와 재현율(recall)을 사용할 수 있다.
  4. 랭킹 문제나 다중 레이블 문제에는 평균 정밀도를 사용할 수 있다.

참고.Confusion Matrix(혼동 행렬)

 


4.5.3 평가 방법 선택

  1. 현재의 진척 상황을 평가할 방법을 정해야 한다. 
    1. 홀드아웃 검증 세트 분리 : 데이터가 풍부할 때 사용
    2. k-fold 교차 검증 : 홀드아웃 검증을 사용하기에 샘플 수가 적을 때 사용
    3. 반복 k-fold 교차 검증 : 데이터가 적고, 매우 정확한 모델 평가가 필요할 때 사용

4.5.4 데이터 준비

  1. 머신러닝 모델에 주입할 데이터를 구성한다. 이 머신 러닝 모델을 심층 신경망이라고 가정해보자.
    1. 데이터는 텐서로 구성된다.
    2. 이 텐서에 있는 값은 일반적으로 작은 값으로 스케일 조정되어있다. (-1,1) 이나 (0,1) 범위
    3. 특성마다 범위가 다르면 정규화해야 한다.
    4. 특성 공학을 수행할 수 있다. 특히 데이터가 적을 때 수행
    5. 이렇게 입력 데이터와 타깃 데이터의 텐서가 준비되면 모델을 훈련시킬 수 있다.

4.5.5 기본보다 나은 모델 훈련하기

  1. 이 단계의 목표는 '통계적 검정력'을 달성하는 것, 즉 아주 단순한 모델보다 나은 수준의 작은 모델을 개발한다.
  2. 이전의 MNIST 숫자 이미지 분류에서는 0.1보다 높은 정확도를 내는 모델이 통계적 검정력을 가졌다고 말할 수 있다.
  3. 여러개의 타당성 있는 네트워크 구조를 시도해보고, 무작위로 예측하는 모델보다 낫지 않다면, 입력 데이터에 존재하지 않는 것을 얻으려고 한다는 신호이다. (앞서 세운 2가지 가설 기억)
  4. 따라서 이러한 신호를 보고 가설이 잘못된 것임을 의심하고, 기획부터 다시 해보아야한다.
  5. 반면 잘 진행된다고 가정하면, 첫 번째 모델을 만들기위해 3가지 선택을 해야한다.
    1. 마지막 층의 활성화 함수 : 네트워크의 출력에 필요한 제한을 가함. (ex. 시그모이드 사용/활성화함수 사용x)
    2. 손실 함수 : 풀려고하는 문제의 종류에 적합해야한다. IMBD예제는 binary_crossentropy,회귀에서는 mse
    3. 최적화 설정 : 어떤 옵티마이저를 사용하고, 학습률은 얼마인지 (보통 rmsprop과 기본 학습률 사용)
  6. 손실함수의 선택에 있어서 주어진 문제의 성공 지표를 직접 최적화하는 것이 항상 가능하지 않다는 점을 알아야 한다. 때로는 이 지표를 손실함수로 바꿀 수 있는 방법이 없을 때도 있다. 
    1. 손실 함수는 주어진 미니 배치 데이터에서 계산 가능해야하고, (이상적으로는 하나의 데이터포인트에서도 계산 가능해야함)
    2. 미분 가능해야한다. (아닐시, 역전파 알고리즘을 사용하여 네트워크 훈련하는 것이 불가능함) 
    3. 예를 들어, 널리 사용되는 분류 지표인 ROC AUC는 직접 최적화될 수 없어, 분류 작업에는 크로스엔트로피처럼 ROD AUC를 대신할 지표를 최적화하는 것이 보통이다. 일반적으로 크로스엔트로피가 낮을수록 ROC AUC가 높다고 기대할 수 있다.

모델에 맞는 "마지막 층"의 활성화 함수와 손실 함수 선택


4.5.6 몸집 키우기 : 과대적합 모델 구축

  1. 통계적 검정력을 가진 모델을 얻었다면, 이제 모델이 충분히 성능을 내는지 보아야한다.
  2. 주어진 문제를 적절히 모델링하기에 충분한 층과 파라미터가 있는지 확인
  3. 예를 들어 2개의 유닛을 가진 1개의 은닉 층으로 구성된 네트워크가 있다고 가정해보면, 이 네트워크가 MNIST 데이터셋에서 통계적 검정력을 가질 수있지만, 문제해결에는 충분하지 않을 수 있다. 
  4. 과소적합과 과대 적합 사이, 즉 과소용량과 과대용량의 경계에 적절히 위치한 모델이 이상적이며, 이 경계가 어디에 위치하는지 찾기위해서는 먼저 지나쳐 보아야 한다.
  5. 과대적합 모델 만들기 (얼마나 큰 모델을 만들어야하는지 알기 위해서)
    1. 층을 추가한다.
    2. 층의 크기를 키운다.
    3. 더 많은 에포크동안 훈련한다.
    4. 그리고 관심 대상인 훈련과 검증 지표는 물론, 항상 훈련 손실과 검증 손실을 모니터링하자 (matplotlib로 그래프 그려보기, 검증 데이터에서 모델 성능이 감소하기 시작했을 때 과대적합에 도달한 것

4.5.7 모델 규제와 하이퍼 파라미터 튜닝

  1. 규제와 모델 튜닝을 시작하여 과소적합도 아니고, 과대적합도 아닌 이상적인 모델에 가깝도록 만든다.
  2. 이 단계가 대부분의 시간을 차지한다. 반복적으로 모델 수정,훈련하고 검증 데이터에서 평가한다.(테스트 데이터 사용하지 X) 그리고 다시 수정하고, 가능한 좋은 모델을 얻을 때까지 반복
  3. 이 과정에서적용해볼 것들
    1. 드롭 아웃 추가
    2. 층 추가/제거해서 다른 구조 시도
    3. L1이나 L2, 또는 둘 다 추가
    4. 최적의 설정을 찾기 위해 하이퍼 파라미터를 바꾸어 시도 (ex. 층의 유닛 수, 옵티마이저의 학습률..)
    5. 선택적으로 특성 공학 시도. 새로운 특성을 추가하거나, 유용하지 않을 것같은 특성 제거
  4. 검증 과정에서 얻은 피드백으로 모델을 튜닝할 때마다 검증 과정에 대한 정보를 모델에 누설하고 있다는 사실에 유념하자. 몇 번만 반복하는 것은 큰 문제가 되지 않지만, 많이 반복하면 결국 모델이 검증과정에 과대적합될 것. (모델이 검증 데이터에 전혀 훈련되지 않았는데에도 불구하고) → 검증 과정의 신뢰도를 감소시킨다.
  5. 만족할만한 모델 설정을 얻었다면, 가용한 모든 데이터(훈련,검증 데이터)를 사용해 최종 모델을 훈련시키고, 마지막에 딱 한번 테스트 세트에서 평가한다. 
    1. 테스트 세트의 성능이 검증 데이터에서 측정한 것보다 많이 나쁘다면, 검증 과정에 전혀 신뢰성이 없거나,모델의 하이퍼파라미터를 튜닝하는 동안에 검증 데이터에 과대적합된 것이다.
    2. 이런 경우에는 좀더 신뢰할만한 방법으로 바꾸는 것이 좋다. (반복 k-fold 교차 검증 이용)

4.6 요약

1. 주어진 문제와 훈련 데이터 정의, 데이터를 수집하고 필요시 레이블 태깅
2. 성공 측정 지표 선택, 검증 데이터에서 모니터링할 지표 선택
3. 평가 방법 결정(홀드 아웃,k-fold), 검증에 사용해야할 데이터의 양은 얼마나되는지 확인
단순 랜덤 선택 모델보다 나은 통계력 검정력이 있는 첫 번째 모델 만들기
4. 과대적합된 모델 만들기 (과대용량과 과소용량 사이 적절한 경계를 찾기 위해서)
5. 검증 데이터의 성능에 기초하여 모델에 규제를 적용하고, 하이퍼 파라미터를 튜닝한다. 가장 중요한 단계

 

Comments