페이지

2022년 7월 30일 토요일

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

4.3.1 신경망을 위한 데이터 전처리

 데이터 전처리 목적은 주어진 원본 데이터를 신경망에 적용하기 쉽도록 만드는 것입니다. 벡터화(vectorization), 정규화(normalization), 누락된 값 다루기, 특성 추출 등이 포함됩니다.


- 벡터화

신경망에서 모든 입력과 타깃은 부동 소수 데이터로 이루어진 텐서여야 합니다(또는 특정 경우에 정수로 이루어진 테서입니다). 사운드, 이미지, 텍스트 등 처리햐야 할 것이 무엇이든지 먼저 텐서로 벼ㅑㄴ환해야 합니다. 이 단계를 데이터 벡터화(data vectorization)라고 합니다. 예를 들어 이전에 나온 2개의 텍스트 분류 예에서 텍스트를 (단어 시퀀스를 의미하는) 정수 리스트로 변환했습니다. 그다음 원-핫 인코딩을 사용하여 float32타입 데이터로 이루어진 텐서로 바꾸었습니다. 숫자 이미지 분류와 주택 가격 예측의 예에서는 이미 데이터가 벡터 형태로 주어졌으므로 이 단계를 건너 뛰었씁니다.


- 값 정규화

숫자 이미지 분류 예에서 이미지 데이터를 그레이스케일 인코딩 0-255 사이의 정수로 인코딩했습니다. 이 데이터를 네트워크에 주입하기 전에 float32 타입으로 변경하고 255로 나누어서 최종적으로 0-1 사이의 부동 소수 값으로 만들었습니다. 주택 가격을 예측할 때는 특성들의 범위가 제각각이었습니다. 어떤 특성은 작은 부동 소수 값이고 다른 특성은 매우 큰 정수 값을 가졌습니다. 이 데이터를 네트워크에 주입하기 전에 각 특성을 독립적으로 정규화하여 평균이 0이고 표준편차가 1이 되도록 만들었습니다.

일반적으로 비교적 큰 값(예를 들어 네트워크의 가중치 초깃값보다 훨씬 큰 여러 자릿수를 가진 정수)이나 균일하지 않은 데이터(옐르 들어 한 특성의 범위는 0-1이고 다른 특성은 100-200인 데이터)를 신경망에 주입한느 것은 위험합니다. 이렇게 하면 업데이트할 그래디언트가 컼져 네트워크가 수렴하는 것을 방해합니다. 네트워크를 쉽게 학습시키려면 데이터가 다음 특징을 따라야 합니다.

1) 작은 값을 취합니다. 일반적으로 대부분의 값이 0-1 사이여야 합니다.

2) 균일해야 합니다. 즉 모든 특성이 대체로 비슷한 범위를 가져야 합니다.

추가적으로 다음에 나오는 엄격한 정규화 방법은 꼭 필수적이지는 않지만(예를 들어 숫자 이미지 분류 예에서는 사용하지 않습니다) 자주 사용되고 도움이 될수 있습니다.

3) 각 특성별로 평균 0이 되도록 정규화합니다.

4) 각 특성별로 표준 편차가 1이 되도록 정규화합니다.

넘파이 배열에서 방법은 간단합니다.

x -= x.mean(ㅁ탼=0) .................. x가 (샘플, 특성)크기인 2D 행렬이라고 가정합니다.

x /= x.std(axis=0)


- 누락된 값 다루기

이따름 데이터에 값이 누락된 경우가 있습니다. 예를 들어 주택 가격 예측 문제에서 첫 번째 특성(데이터에서 인텍스가 0인컬럼)은 1인당 범쥐율입니다.

이 특성이 모든 샘플에 들어 있지 않으면 어떻게 될까요? 훈련 데이터나 테스트 데이터에 누락된 값이 포함됩니다. 일반적으로 신경망에서 0이 사건에 정의된ㄴ 의미 있는 값이 아니라면 누락된 값을 0으로 입력해도 괜찮습니다. 네트워크가 0이 누락된 데이터를 의미한다는 것을 학습하면 이 값을 무시하기 시작할 것입니다.

테스트 데이터에 누라된 값이 포함될 가능성이 있다고 가정합시다. 하지만 네트워크가 누락된 값이 없는 데이터에서 훈련되었다면 이 네트워크는 누라된 값을 무시하는 법을 알지 못합니다. 이런 경우에는 누락된 값이 있는 훈련 샘플을 고의적으로 만들어야 합니다. 훈련 샘플의 일부를 여러별 복사해서 테스트 데이터에서 빠질 것 같은 즉성을 제거합니다.

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

 모델 평가 외에도 모델 개발로 들어가기 전에 우리가 넘어야 할 중요한 질문이 있습니다. 신경만에 입력 데이터와 타깃 데이터를 주입하기 전에 어떻게 준비해야 할까요? 많은 데이터 전처리와 특성 공학 기법은 특정 도메인에 종속적입니다(예를 들어 텍스트 데이터나 이미지 데이터에 특화되어 있습니다). 이 후 장에서 실전 문제를 보면서 이에 대해 다루겠습니다. 여기서는 모든 종류의 데이터에 공통되는 기본 사항을 살펴보겠습니다.

4.2.2 기억해야 할것

 평가 방식을 선택할 때 다음 사항을 유념해야 합니다.

1) 대표성 있는 데이터: 훈련 세트와 데이터 세트가 주어진 데이터에 대한 대표성이 있어야 합니다. 옐르 들어 숫자 이미지를 분류하는 문제에서 샘플 배열이 클래스 순서대로 나영되어 있다고 가정합시다. 이 배열의 처음 80%를 훈련 세트로 나머지 20%를 테스트 세트로 만들면 훈련 세트에는 0-7 숫자만 담겨 있고 테스트 세트에는 8-9 숫자만 담기게 됩니다. 어처구니없는 실수처럼 보이지만 놀랍게도 자주 일어나는 일입니다. 이런 이유 때문에 훈련 세트와 테스트 세트로 나누기 전에 데이터를 무작위로 섞는 것이 일반적입니다.

2) 시간의 방향: 과거로부터 미래를 예측하려고 한다면(예를 들어 내일의 날씨, 주식 시세등) 데이터를 분할하기 전에 무작위로 섞어서는 절대 안 됩니다. 이렇게 하면 미래의 정보가 누설되기 때문입니다. 이런 문제에서는 훈련 세트에 있는 데이터보다 테스트 세트에 있는 모든 데이터가 미래의 것이어야 합니다.

3) 데이터 중복: 한 데이터셋에 어떤 데이터 포인트가 두 번 등장하면(실제 데이터셋에서 아주 흔한 일입니다.) 데이터를 섞고 훈련 세트와 검증 세트로 나누었을 때 훈련 세트와 검증 세트에 데이터 포인트가 중복될 수 있습니다. 이로 인해 훈련 데이터의 일부로 테스트하는 최악의 경우가 됩니다. 훈련 세트와 검증 세트가 중복되지 않는지 확인하세요.