페이지

2022년 7월 30일 토요일

4.5.1 문제 정의 와 데이터셋 수집

 먼저 주어진 문제를 정의 해야 합니다.

1) 입력 데이터는 무엇인가요? 어떤 것을 예측하려고 하나요? 가용한 휸련 데이터가 있어야 어떤 것을 예측하도록 학습할 수 있습니다. 예를 들어 영화 리뷰와 감성 레이블이 태깅되어 있어야 영화 리뷰의 감성 분류를 학습할 수 있습니다. 이런 식으로 보통 가용데이터의 유무는 이 단계에서 제한 요소가 됩니다(데이터를 수집할 비용이 없다면).

2) 당면한 문제가 어떤 종류인가요? 이진 분류인가요? 다중 분류인가요? 스칼라 회귀인가요? 베터 회귀인가요? 다중 레이블 다중 분류인가요? 아니면 군집, 생성 또는 강화 학습 같은 다른 문제 인가요? 문제의 유형을 식별하면 모델의 구조와 손실 함수등을 선택하는 데 도움이 됩니다.


입력과 출력이 무엇인지와 어떤 데이터를 사용할 것인지 알기 전까지는 다음 단계로 넘어갈 수 없습니다. 이 단계에서 가설을 세워야 합니다.

3) 주어진 입력으로 출력을 예측할 수 있다고 가설을 세웁니다.

4) 가용한 데이터에 입력과 출력 사이의 관계를 학습하는 데 충분한 정보가 있다고 4가설을 세웁니다.

모델이 작동하기 전까지 이는 가설에 불과합니다. 검증될지 아닐지 기다려 보아야 합니다. 모든 문제가 해결되지는 않습니다. 입력 X와 타깃 Y의 샘플을 수집했다고 X에 Y를 예측하기에 충분한 정보가 있는것은 아닙니다. 예를 들어 주식 시장의 최근 가격 변공 정보를 가지고 주가를 예측한다면 실패할 가능성이 높ㅊ습니다. 과거 가격 정보에는 예측에 활용할 정보가 많지 않기 때문입니다.

풀기 어려운 종류의 문제는 시간에 따라 변하는 문제(nonstationary problem)입니다. 옷을 위한 추천 엔진을 구축한다고 가정합시다. 한 달치(8월)의 데이터로 훈련하고 겨율에 이 추천 엔진을 사용하려고 합니다. 여기서 문제는 사람들이 계정에 따라 구매하려는 옷의 종류가 바뀐다는 것입니다. 의류 구매는 몇 달에 걸쳐 보면 시간에 따라 바뀌어 유동적입니다. 시간에 따라 모델을 바꾸기 위해 어떻게 해야 할까요? 이런 경우에 최근의 데이터로 주기적으로 모델을 다시 훈련하거나 시간 분포에 맞게 데이터를 수집하여 시간에 따라 변하지 않는 무넺로 바꿉니다. 의류 구매처럼 순환성이 있는 문제는 몇 년치의 데이터를 모으면 결정릐 변활르 감지하는 데 충분할 것입니다. 1년 중 언제인지 기록한 시간도 메델에 입력해야 한다는 것을 잊지 마세요!

머신 러닝은 훈련 데이터에 있는 패턴을 기억하기 위해서만 사용한다는 것을 유념하세요. 이미 보았던 것만 인식할 수 있습니다. 미래를 예ㅖ측하기 위해 과거 데이터에서 훈련한 머신러닝을 사용하는 것은 미래가 과거처럼 움직인다고 가정한 것입니다. 사실 대부분 그렇지는 않습니다.


4.5 보편적인 머신 러닝 작업 흐름

 이 절에서 머신 러닝 문제를 해결하기 위해 사용할 수 있는 보편적인 청사진을 제시하겠습니다. 이 청사진은 이장에서 배운 문제 정의, 평가, 특성 공학, 과대적합의 개념과 연결되어 있습니다.

4.4.3 드롭아웃 추가

 드럽아웃(dropout)은 토론토 대한의 제프리 힌튼과 그의 학생들이 개발했습니다. 신경망을 위해 사용되는 규제 기법 중에 가장 효과적이고 널리 사용되는 방법 중 하나입니다. 네트워크 층에 드롭아웃을 적용하면 훈련하는 동안 무작위로 층의 일부 출력 특성을 제외시킵니다(0으로 만든빈다). 한 층이 정상적으로 훈련하는 동안에는 어떤 입력 샘플에 대해 [0.2, 0.5, 1.3, 0.8, 1.1] 백터를 출력한다고 가정합시다. 드롭아웃을 적용하면 이 벡터의 일부가 무작위로 0으로 바뀝니다. 예를 들어 [0, 0.5, 1.3, 0, 1.1]이 됩니다. 드롭아웃 비율은 0이 될 특성의 비율입니다. 봍농 0.2에서 0.5 사이로 지정됩니다. 테스트 단계에선느 어떤 유닛도 드롭아웃되지 않습니다. 그 대신에 층의 출력을 드롭아웃 비율에 비례하여 줄여 줍니다. 훈련할 때보다 더 많은 유닛이 활성화되기 때문입니다.

크기가 (batch_size, features)인 한 층의 출력을 담고 있는 넘파이 행렬을 생각해 보겠습니다. 훈련할 때는 이 행렬 값의 일부가 랜덤하게 0이 됩니다.

layer_output *=  np.ramdom.randint(0, high=2, size=layer_output.shape)..훈련할 때 유닛의 출력중

                                                                                         50%를 버립니다.

테스트 할 때는 드롭아웃 비율로 출력을 낮추어 주어야 합니다. 여기에서는 0.5배만큼 스케일을 조정했습니다(앞에서 절반의 유닛을 드롭아웃했으므로).

layer_output *= 0.5 ....테스트 단계

훈련 단계에 이 두 연산을 포함시켜 테스트 단계에는 출력을 그대로 두도록 구현할 수 있습니다. 실제로 종종 이런 방식으로 구현합니다(그림 4-8 참고).

layer_output *= np.random.randint(0, high=2, size=layer_output.shape) ..훈련단계

layer_output /= 0.5 .........여기에서 스케일을 낮추는 대신 높입니다.

이 기업이 이상하고 무 계획으로 보일 수 있습니다. 왜 드롭아웃이 과대 적합을 줄이는 데 도움이 될까요? 힌튼은 은행에서 사용하는 부정 방지 매커니즘에서 착안했다고 합니다. 그의 말을 빌리면 "은행에 갔을 때 행원들이 계속 바뀌길래 왜 그런지를 물었습니다. 자신들도 이유는 모르지만 자주 업무가 바뀐다고 했습니다. 나는 은행에서 부정 행위를 하려면 직원들 사이의 유대가 필요하기 때문이라 판단했습니다. 각 샘플에 대해 뉴런의 일부를 무작위하게 제거하면 뉴런의 부정한 협업을 방지하고 결국 과대 적합을 감소시킨다는 것을 깨달았습니다." 핵심 아이디어는 층의 출력 값에 노이즈를 추가하여 중요하지 않은 우연한 패턴(힌튼이 이야기한 부정한 협업)을 깨뜨리는 것입니다. 노이즈가 없다면 네트워크가 이 패턴을 기억하기 시작할 것입니다.

케라스에서는 층의 출려 바로 뒤에 Dropout 층을 추가하여 네트워크에 드롭아웃을 적용할 수 있습니다.

model.add(layers.Dropout(0.5))

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

    model = models.Sequential()

    model.add(layers.Dense(16, activation='relu', input_shape(1000, )))

    model.add(layers.Dropout(0.5))

    model.add(layers.Dense(16, activastion='relu'))

    model.add(layers.Dropout(0.5))

    model.add(layers.Dense(1, activation='sigmoid'))

정리하면 신경망에서 과대적합을 방지하기 위해 가장 널리 사용하는 방법은 다음과 같습니다.

1) 훈련 데이터를 더 모읍니다.

2) 네트워크의 용량을 감소시킵니다.

3) 가중치 규제를 추가합니다.

4) 드롭아웃을 추가합니다.


4.4.2 가중치 규제 추가

 오캄의 면도날(Occam's razor) 이론을 알고 있을지 모르겠습니다. 어떤 것에 대한 두 가지의 설명이 있다면 더 작은 가정이 필요한 간단한 설명이 옳을 것이라는 이론입니다. 이 개념은 신경망으로 학습되는 모델에도 적용됩니다. 어떤 훈련 데이터와 네트워크 구조가 주어졌을 때 데이터를 설명할 수 있는 가중치 값의 집합은 여러 개(여러 개의 모델)입니다. 간단한 모델의 복잡한 모델보다 덜 과대적합될 가능성이 높습니다.

여기에서 간단한 모델은 파라미터 값 분포의 엔트로피가 작은 모델입니다(또는 앞 절에서 본 것처럼 작은 수의 파라미터를 가진 모델입니다). 그러므로 과대적합을 완화하기 위한 일반적인 방법은 네트워크의 복잡도에 제한을 두어 가중치가 작은 값을 가지도록 강제하는 것입니다. 가중체 값의 분포가 더 균일하게 됩니다. 이를 가중치 규제(weight regularization)라고 하며, 네트워크의 손실함수에 큰 가중치에 연관된 비용을 추가합니다. 두 가지 형태의 비용이 있습니다.

1) L1규제: 가중치의 절댓값에 비례하는 비용이 추가됩니다(가중치의 L1 노름(norm)).

2) L2규제: 가중치의 제곱에 비례하는 비용이 추가 됩니다(가중치의 L2 노름). L2규제는 신경망에서 가중치 감쇠(weight decay)라고도 부릅니다. 이름이 다르지만 혼동하지 마세요 가중치 감쇠는 수학적으로 L2규제와 동일합니다.

케라스에서 가중치 규제 책체를 층의 키워드 매개변수로 전달하여 가중치 규제를 추가할 수 있습니다. 영화 리뷰 분류 네트워크에 L2가중치 규제를 추가해 보죠.


    from keras import regularizers


    model = models.Sequential()

    model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),

                                    activation=;relu', input_shape=(10000,)))

    model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),

                                    activation='relu'))

    model.add(layers.Dense(1, activation='sigmoid'))

l2(0.001)는 가중치 행렬의 모든 원소를 제곱하여 0.01을 곱하여 네트워크의 전체 손실에 더해진다는 의미입니다. 이 패널티(penalry) 항은 훈련할 때만 추가됩니다. 이 네트워크의 손실은 테스트보다 훈련할 때 더 높을 것입니다.

그림 4-7은 L2규제 패널티의 효과를 보여 줍니다. 여기서 볼수 있듯이 두 모델의 동일한 파라키너 수를 가지고 있더라도 L2규제를 사용한 모델(점)이 기본 모델(덧셈 기호)보다 훨씬 더 과대적합에 잘 견디고 있습니다.

케라스에서는 L2규제 대신에 다음 가중치 규제 중 하나를 사용할 수 있습니다.

     from keras import regularizers

    regularizers.l1(0.001) ..... L1 규제

    regularizers.l1_l2(l1=0.001, l2=0.001) ......  L1과 L2 규제 병행

4.4.1 네트워크 크기 축소

 과대적합을 맏는 가장 단순한 방법은 모델의 크기, 즉 모델에 있는 학습 파라미터의 수를 줄이는 것입니다. 파라미터의 수는 층의 수와 각 층의 유ㅜ닛 수에 의해 결정됩니다. 딥러닝에서 몰델에 잇는 학습 파라미터의 수를 종종 모델의 용량(capacity)이라고 말합니다. 당연하게 파라미터가 많은 모델이 기억 용량이 더 많습니다. 훈련 샘플과 ㅌ나깃 사이를 딕셔너리 같은 일대일 매핑으로 완벽하게 학습할 수도 있습니다. 이런 매핑은 일반화 능력이 없습니다. 옐르 들어50만개의 이진 파라미터가 있는 모델은 MNIST 훈련 세트의 숫자 이미지 클래스를 모두 쉽게 학습할 수 있습니다. 5만 개의 숫자 이미지 하나마다 10개의 이진 파라미터만 있으면 됩니다. 하지반 이런 모델은 새로운 숫자 샘플을 분류하는 용도는 쓸모가 없습니다. 항상 유념해야 할 것은 딥러닝 모델은 훈련 데이터에 잘 맞추려는 경향이 있다는 점입니다. 하지만 진짜 문제는 최적화가 아니고 일반화입니다.

다른 한편으로 네트워크가 기억 용량에 제한이 있다면 이런 매핑을 쉽게 학습하지 못할 것입니다. 따라서 손실을 최소화하기 위해 타깃에 대한 예측 성능을 가진 압축된 표현을 학습해야 ㅎ바니다.

정확히 이런 표현이 우리 관심 대상입니다. 동시에 기억해야 할 것은 과소적합되지 않도록 충분한 파라미너틀 가진 모델을 사용해야 한다는 점입니다. 모델의 기억용량이 부족해서는 안됩니다. 너무 많은 용량과 충부하지 않은 용량 사이의 정충점을 찾아야 합니다. 안타깝지만 알맞은 층의 수나 각 층의 유닛 수를 결정할 수 있는 마법 같은 공식은 없습니다. 데이터 알맞는 모델 크기를 찾으려면 각기 다른 구조를 (당연히 데티스 세트가 아니고 검증 세트에서)평가해 보아야 합니다. 적절한 모델 크기를 찾는 일반적인 작업 흐름은 비교적 적은 수의층과 파라미터로 시작합니다. 그 다음 검증 손실이 감소되기 사작할 때까지 층이나 유닛의 수를 늘리는 것입니다.

영화 리뷰 분류 모델에 적용해 보죠, 원래 네트워크는 다음과 같습니다.

    from keras import models

    from keras import layers


    model = models.Sequenctial()

    model.add(layers.Dense(16, activation='relu', input_Shape=(10000,)))

    model.add(layers.Dense(16, activation='relu'))

    model.add(layers.Dense(1, activation-'sigmoid'))

더 작은 네트워크로 바꾸어 보죠.

    model = models.Sequential()

    model.add(layers.Dense(6, activation='relu', input_shape=(10000,)))

    model.add(layers.Dense(6, activation='relu'))

    model.add(layers.Dense(1, activation='sigmoid'))

그림 4-4는 원본 네트워크와 축소된 네트워크의 검증 손실을 비교한 것입니다. 점으로 표현된 것이 작은 네트워크고, 덧셈기호가 원래 네트워크입니다(검증 손실이 작은것이 좋은 모델입니다). 여기서 볼 수 있듯이 작은 네트워크가 기본 네트워크보다 더 나중에 과대적합되기 시작했습니다(네번째에 에포크가 아니라 여섯 번째 에포크에서). 과대 적합이 시작되었을 때 성능이 더 천천이감소되었습니다.

이번에는 문제에 필요한 것보다 훨씬 더 많은 용량을 가진 테트워크를 비교해 보겠습니다.

    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'))

그림 4-5는 더 큰 네트워크가 기본 네트워크에 비;해 얼마나 차이 나는지 보여 줍니다. 그림에서 점은 용량이 큰 네트워크의 검증 손실이고, 덧셈 기호는 원본 네트워크의 검증 손실입니다.

용량이 큰 네트워크는 첫 번째 에포크 이후 거의 바로 과대적합이 시작되어 갈수록 더 심해집니다. 검증 손실도 매우 불안정합니다.

한편 그림 4-6은 두 네트워크의 훈련 손실을 보여 줍니다. 여기서 볼 수 있듯이 용량이 큰 네트워크는 훈련 손실이 매우 빠르게 0에 가까워집니다. 용량이 많은 네트워크일수록 더 빠르게 훈련 데이터를 모델링할 수 있습니다(결국 훈련 손실이 낮아집니다). 하지만 더욱 과대적합에 민감해집니다(결국 훈련과 검증 손실 사이에 큰 차이가 발생합니다).


2022년 7월 29일 금요일

4.4 과대적합과 과서적합

 이전 장에 있던 세가지 예제인 영화 리뷰 예측, 토픽 분류, 주택 가격 회귀 모두 홀드아웃 데이터에서 모델의 성능이 몇 번의 에포크 후에 최고치에 다다랐다가 감소되기 시작했습니다. 즉 모델이 금방 훈련 데이터에 과대적합(overfitting)되기 시작합니다. 과대적합은 모든 머신 러닝 문제에서 발생합니다. 머신 러닝을 마스터하려면 과대적합을 다루는 방법ㅂ을 꼬 배워야 합니다.

머신러닝의 근본적인 이슈는 최적화 일반화 사이의 줄다리기입니다. 최적화(optimization)는 가능한 훈련 데이터에서 최고의 성능을 얻으려고 모델을 조정하는 과정입니다(머시 러닝의 학습). 반면에 일반화(generalization)는 훈련된 모델이 이전에 본 적 없는 데이터에서 얼마나 잘 수행되는지 의미합니다. 물론 모델을 만드는 목적은 좋은 일반화 성능을 얻는 것입니다. 하지만 일반화 성능을 제어할 방법이 없습니다. 단지 훈련 데이터를 기반으로 모델을 조정할 수만 있습니다.

훈련 초기에 최적화와 일반화는 상호 연관되어 있습니다. 훈련 데이터의 손실이 낮아질수록 테스트 데이터의 손실도 낮아집니다. 이런 상황이 발생할 때 모델이 과소적합(underfitting)되었다고 말합니다. 모델의 성능이 계속 발전될 여지가 있습니다. 즉 네트워크가 훈련 데이터에 있는 관련 특성을 모두 학습하지 모했습니다. 하지만 훈련 데이터에 여러 번 반복학습하고 나면 어느 시점부터 일반화 성능이 더 이상 높아지지 않습니다. 검증 세트의 성능이 멈추고 감소되기 시작합니다. 즉 모델이 과대적합되기 시작합니다. 이는 훈련 데이터에 특화된 패턴을 학습하기 시작했다는 의미입니다. 이패턴은 새로운 데이터와 관련성이 적어 잘못된 판단을 하게 만듭니다.

모델이 관련성이 없고 좋지 못한 패턴을 훈련 데이터에서 학습하지 못하도록 하려면 가장 좋은 방법은 더 많은 훈려 데이터를 모으는 것입니다. 더 많은 데이터에서 훈련된 모델은 자연히 일반화 성능이 더욱 뛰어납니다. 데이터를 더 모으는 것이 불가능할때 차선책은 모델의 수용할 수 있는 정보의 양을 조절하거나 저장할 수 있는 정보에 제약을 가하는 것입니다. 네트워크가 적은 수의 패턴만 기억할 수 있다면 최적화 과정에서 가장 중요한 패턴에 집중하게 될 것입니다. 이런 패턴은 더 나은 일반화 성능을 제공할 수 있습니다.

이런 식으로 과대적합을 피하는 처리 과정을 규제(regularization)라고 합니다. 가장 널리 사용되는 규제 기법을 알아보고 3.4절에서 본 영화 리뷰 분류 모델에 실제로 적용하여 선능을 향상시켜보겠습니다.

4.3.2 특성 공학

 특성 공학은 데이터와 머신 러닝 알고리즘(여기에서는 신경망)에 관한 지식을 사용하는 단계입니다. 모델에 데이터를 주입하기 전에(학습이 아닌) 하드코딩된 변환을 적용하여 알고리즘이 더 잘 수행되도록 만들어 줍니다. 많은 경우에 머신러닝 모델이 임의의 데이터로부터 완벽한 학습을 한다고 기대하기 어렵습니다. 모델이 수월하게 작업할 수 있는 어떤 방식으로 데이터가 표현될 필요가 있습니다.

이해하기 쉬운 예를 하나 살펴보죠. 시계 이미지를 입력으로 받고 하루의 시간을 출력하는 모델을 개발한다고 가정합시다. 이미지의 원본 픽셀을 입력으로 사용한다면 어려운 머신 러닝 문제가 될 것입니다. 이를 해결하려면 합성곱 신경망이 필요할 것이고 이 네트워크를 훈련하기 위해 꽤 많은 컴퓨팅 장원도 필요합니다. 고 수준에서 이 문제를 이해하고 있다면(우리는 시계에서 시간을 읽는 방법을 알고 있습니다) 머신러닝 알고리즘을 위해 훨씬 더 좋은 입력 특성을 만들 수 있습니다. 예를 들어 시계바늘의 검은색 픽셀을 따라 각 바늘 끝의 (x, y) 좌표를 출력하는 간단한 파이썬 스크립트를 만듭니다. 그 다음 머신 러닝 알고리즘이 이 좌표와 적절한 시간을 연결하도록 쉽게 학습될 수 있습니다.

이보다 저 좋은 특성을 만들 수 있습니다. 좌표를 바꾸어 (x, y)포인트를 이미지 중심에 대한 극좌표로 나타낼 수 있습니다. 이제 각 시계 바늘의 각도가 입력됩니다. 이렇게 특성을 준비하면 문제가 너무 쉬워져서 머신 러닝이 전혀 필요하지 않습니다. 간단한 반올림 연산과 딕셔너리 참고만으로 하로ㅜ의 시간을 추정하기 충분합니다.

이것이 특성 공학의 핵심입니다. 특성을 더 간단한 방식으로 표현하여 문제를 쉽게 만듭니다. 일반적으로 해당 문제를 아주 잘 이해하고 있어야 합니다.

딥러닝 이전에는 특성 공학이 아주 중요했습니다. 전통적인 얕은 학습 방법의 알고리즘들은 스스로 유용한 특성을 학습할 만큼 충분히 넓은 가설 공간을 가지고 있지 않습니다. 알고리즘에 데이터를 표현하는 방식에 성공 여부가 달려 있습니다. 옐르 들어 합성곱 신경망이 MNIST 숫자이미지 분류 문제를 해결하기 전까지 전형적인 해결책은 하드코딩된 특성을 사용하는 것이었습니다. 숫자 이미지에 있는 동심원의 수, 이미지에 있는 숫자와 높이, 팩셀 값의 히스토그램(histogram)등 입니다.

다행이 최근 딥러닝은 대부분 특성 공학이 필요하지 않습니다. 신경망이 자동으로 원본 데이터에서 유용한 특성을 추출할 수 있기 때문입니다. 그렇다면 심층 신경망을 상요할 때는 특성 공학에 대해 신경쓰지 않아도 될까요? 두 가지 이유로 그렇지 않습니다.

1) 좋은 특성은 적은 장원을 상요하여 문제를 더 멋지게 풀어낼 수 있습니다. 옐르 들어 시계 늘을 읽는 문제에 합성곱 신경망을 사용하는 것은 어울리지 않습니다.

2) 좋은 특성은 더 적은 데이터로 문제를 풀 수 있습니다. 딥러닝 모델이 스스로 특성을 학습하는 능력은 가용한 훈련 데이터가 많을 때 발휘됩니다. 샘플의 개수가 적다면 특성에 있는 정보가 매우 중요해집니다.