페이지

2022년 7월 30일 토요일

5.1.2 최대 풀링 연산

 앞선 컨브넷 예제에서 특성 맵의 크기가 MaxPooling2D층마다 절반으로 둘어들었습니다. 얘ㅖㄹ르 들어 첫 번째 MaxPooling2D 층 이전에 특성 뱁의 크기는 26 * 26이었ㄴ느데 최대 풀링 연산으로 13 * 13으로 줄어들었습니다. 스트라이드 합성곱과 매우 비슷하게 강제적으로 특성 맵을 다운샘프링하는 것이 최대 풀링의 역할입니다.

최대 풀링은 입력 특성 맵에서 원도우에 맞는 패치를 추출하고 각 채널별로 최댓값을 출력합니다.

합성곱과 개념적으로 비슷하지만 추출한 패치에 학습된 선형 변환(합성곱 채널)을 적용하는 대신 하드코딩된 최댓값 추출 연산을 사용합니다. 합성곱과 가장 큰 차이점은 최대 풀링은 보통 2 * 2원도우와 스트라이드 2 를 사용하여 특성 맵을 절반 크기로 다운샘플링한다는 것입니다. 이에 반해 합성곱은 전형적으로 3 * 3 원도우와 스트라이드 1을 사용합니다.

왜 이런 식으로 특성 맵을 다운샘플링할까요? 왜 최대 풀링 층을 빼고 큰 특성 맵을 계속 유지하지 않을 까요? 이런 방식을 한번 테스트해 보죠, 합성곱으로만 이루어진 모델은 다음과 같습니다.

model_no_max_pool = models.Sequential()

model_no_max_pool.add(layers.Conv2D(32, (3, 3), activation='relu',

                            input_shape=(28, 28, 1)))

model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))

model_no_max_pool.add(layers.Conv2D(64, (3, 3), activation='relu'))

모델 구조는 다음과 같습니다.

>>> model_no_max_pool.summary()

Layer(type)                ouput Shape            Param #

=======================================================

conv2d_4 (Conv2D)        (None, 26, 26, 32)        320

conv2d_5 (Conv2D)        (None, 24, 24, 64)        18496

conv2d_6 (Conv2D)        (None, 22, 22, 64)        36928

========================================================

Total params: 55,744

Trainable params: 55,744

Non-trainable params:0

이 설정에서 무엇이 문제일까요? 두가지가 있습니다.

1) 특성의 공간적 계층 구조를 학습하는 데 도움이 되지 않습니다. 세 번째 층이 3 * 3원도우는 초기 입력의 7 * 7원도우 영역에 대한 정보만 담고 있습니다. 컨브넷에 의해 학습된 고수준 패넡은 초기 입력에 관한 정보가 아주 적어 숫자 분류를 학습하기에 충분하지 ㅇㄶ을 것입니다(7 * 7픽셀 크기의 창으로 숫자를 보고 분류해 보세요!). 마지막 합성곱 층의 특성이 전체 입력에 대한 정보를 가지고 있어야 합니다.

2) 최종 특성 맵은 22 * 22 * 64 = 30,976개의 원소를 가집니다. 아주 많습니다. 이 컨브넷을 펼친 후 512 크기의Dense츠과 연결한다면 약 15.8배만 개의 가중치 파라미터가 생깁니다. 작은 모델치고는 너무 많은 가중치고, 심각한 과대적합이 발생할 것입니다.


간단히 말해서 단운샘플링을 사용한느 이유는 처리할 특성 맵의 가중치 개술르 줄이기 위해서입니다. 또 연속적인 합성곱 층이(원본 입력에서 커버되는 영역 측면에서)점점 커진 원도우를 통해 바라보도록 만들어 필터의 공간적인 계층 구조를 구성합니다.

최대 폴링이 다운샘플링을 할 수 있는 유일한 방법은 아닙니다. 이미 알고 있듯이 앞선 합성곱 층에서 스트라이드를 사용할 수 있습니다. 최댓값을 취하는 최대 폴링 대신에 입력 패치의 채널별 평균값을 계산하여 변환하는 평균 풀링(average pooling)을 사용할 수도 있습니다. 하지만 최대 풀링이 다른 방법들보다 더 잘 작도하는 편입니다. 그 이유는 특성 맵의 각 타일에서 어떤 패턴이나 개면이 존재 여부를 인코딩하는 경향이 있기 때문입니다(그래서 특성의 지도(맵)입니다). 따라서 특성의 평균값보다 여러 특성 중 최댓값을 사용하는 것이 더 유용합니다. 가장 납득할 만한 서브 샘플링(subsampling)전략은 먼저(스트라이드가 없는 삽성곱으로)조밀한 특성 맵을 만들고 그 다음 작은 배치에 대해서 최대로 활성화된 특성을 고르는 것입니다. 이런 방법이 입력에 대해(스트라이드 합성곱으로) 듬성듬성 원도우를 슬라이딩하거나 입력 패치를 평균해서 특성 정보를 놓치거나 희석시키는 것보다 낫습니다.

이제 커브넷의 특성 맵과 합성곱 그리고 최대 풀링에 대한 기본 개념을 이해했을 것입니다. MNIST숫자 이미지 분류처럼 간단한 문제를 풀기 위해 작은 컨브넷을 만드는 법을 배웠습니다. 그럼 좀 더 유용하고 현실적인 애플리케이션을 만들어 보죠.

5장부터 등장하는 예제는 CPU만 사용할 경우 컴퓨터 사양에 따라 실행 시간이 다소 오래 걸릴수 있습니다. 부로 C 를 참고하여 아마조 GPU 인스턴스를 사용하거나 구글의 코랩 (Colab, https://colab.research.google.com/)을 사용할 수 있습니다. 코랩은 구글이 만든 교육과 연구를 위한 주피터 노트북 환경으로 구글 클라우드의 컴퓨팅 자원을 무료로 사용할 수 있습니다.

5.1.1 합성곱 연산

 완전 연결 층과 합성곱 층 사이의 근본적인 차이는 다음과 같습니다. Dense층은 입력 특성 공간에 있는 전역 패턴(예를 들어 MNIST숫자 이미지에는 모든 픽셀에 걸친 패턴)을 학습하지만 합성곱 층은 지역 패턴을 학습합니다(그림 5-1 참고). 이미지일 경우 작은 2D 원도우(window)로 입력에서 태펀을 찾습니다. 앞의 예에서 이 원도우는 모두 3 * 3크기였습니다.

이 핵심 특징은 컨브넷에 두가지 흥미로운 성질을 제공합니다.

1) 학습된 패턴은 평행 이동 불변성(translation invariant)을 가집니다. 컨브넷이 이미지의 오른쪽 아래 모서리에서 어떤 패턴을 학습했다면 다른 곳(예를 들어 왼쪽 위 모서리)에서도 이 패턴을 인식할 수 있습니다. 완전 연결 네트워크는 새로운 위치에 나타난 것은 새로운 패턴으로 학습해야 합니다. 이런 성질은 컨브넷이 이미지를 효율적으로 처리하게 만들어 줍니다(근본저ㅏㄱ으로 우리가 보는 세상은 평행 이동으로 인해 다르게 인식되지 않습니다). 적은 수의 훈련 샘플을 사용해서 일반화 능력을 가진 표현을 학습할 수 있습니다.

2) 컨브넷은 패넡의 공간적 계층 구조를 학습할 수 있습니다. 첫 번째 합성곱층이 에지 같은 작은 지역 패턴을 학습합니다. 두 번째 합성 곱층은 첫 번째 층의 특성으로 수겅되 더 큰 패턴을 학습하는 식입니다. 이런 방식을 사용하여 컨브넷은 매우 복잡하고 추상적인 시가적 개념을 효과적으로 학습할 수 있습니다.(근본적으로 우리가 보는 세상은공간적 계ㅒ츨 구조를 가집니다).


합성곱 연산은 특성 맵(featreu map)이라고 부르는 3D 텐서에 적용됩니다. 이 텐서는 2개의 공간축(높이와 너비)과 깊이 축(채널 축이라고도 합니다)으로 구성됩니다. RGB 이미지는 3개의 컬러채널(빨간색, 녹색, 파란색)을 가지므로 깊이 축의 차원이 3이 됩니다. MNIST 숫자처럼 흑백이미지는 깊의 축 차원이 1(회색 톤) 입니다. 합성곱 연산은 입력 특성 맵에서 작은 패치(patch)들을 추출하고 이런 모든 패치에 같은 변환을 적용하여 출력 특성 맵(output feature map)을 만듭니다.

출력 특성 맵도 높이와 너비를 가진 3D 텐서입니다. 출련 텐서의 깊이는 층의 매개변수로 결정되기 때문에 상황에 따라 다릅니다. 이렇게 되면 깊이 축의 채널은 더 이상 RGB 입력처럼 특정 컬러를 의미하지 않습니다. 그 대신 일종의 필터(filter)를 의미합니다. 필터는 입력 데ㅐ이터의 어떤 특성을 인코딩합니다. 예를 들어 고수준으로 보면 하나의 필터가 '입력에 얼굴이 있는지'를 인코딩할 수 있습니다.

MNIST 예제에서는 첫 번째 합성곱 층이 (28, 28, 1)크기의 특성 맵을 입력으로 받아 (26, 26, 32)크기의 특성 맵을 출력합니다. 즉 입력에 대해 32개의 필터를 적용합니다. 32개의 출력 채널 각각은 26 * 26 크기의 배열 값을 가집니다. 이 값은 입력에 대한 필터의 응답 맵(response map)입니다. 입력의 각 위치에서 필터 패턴에 대한 응답을 나타냅이다. 특성 맵이란 말이 의미하는 것은 다음과 같습니다. 깊이 축에 있는 각 차원은 하나의 특서(또는 필터)이고, 2D텐서 output[:, :, n]은 입력에 대한 이 필터 응답을 나타내는 2D 공간상의 맵입니다.

합성곱은 색십적인 2개의 파라미터로 정의됩니다.

1) 입력으로부터 뽑아낼 패치의 크기: 전형적으로 3 * 3 또는 5 * 5 크기를 사용합니다. 이 예에서는 일반적으로 많이 사용하는 3 * 3 크기를 사용했습니다.

2) 특성 맵의 출력 깊이: 합성곱으로 계샇할 필터의 수입니다. 이 예에서는 깊이 32로 시작해서 깊이 64로 끝났습니다.


케라스 Conv2D층에서 이 파리미터는 Conv2D(output_depth, (window_height, window_width))처럼  첫 번째와 두 번째 매개변수로 전달됩니다.

3D 입력 특성 맵 위를 3 * 3 또는 5 * 5 크기의 원도우가 슬라이딩(sliding)하면서 모든 위치에서 3D 특성 패치((window_height, window_width, input_depth) 크기)를 추출하는 방식으로 합성곱이 작동합니다. 이런 3D패치는 (output_depth,)크기의 1D 벡터로 변환됩니다(합성곱 커널(convolution kernel)이라고 불리는 하나의 학습된 가중치 행렬과 텐서 곱셈을 통하여 변환됩니다). 변환된 모든 벡터는 (height, width, output_depth)크그의 3D특성 맵으로 재구성됩니다. 출력 특성 맵의 공간상 위치는 입력 특성 맵의 같은 위치에 대응됩니다(예를 들어 출력의 오른쪽 아래 모서리는 입력의 오른쪽 아래 부근에 해당하는 정보를 담고 있습니다). 3 * 3 원도우를 사용하면 3D패치 input[i-1: i+2, j-1:j+2, :]로부터 벡터 output[i, j,  :]가 만들어집니다. 


출력 높이와 너비느 입력의 높이, 너비와 다를 수 있습니다. 여기에는 두가지 이유가 있습니다.
1) 경계문제, 입력 특성 맵에 패딩을 추가하여 대응할 수 있습니다.
2) 잠시 후에 설명할 스트라이드(stride)의 사용 여부에 따라 다릅니다.

- 경계 문제와 패딩 이해하기
5 * 5 크기의 특성 맵을 생각해 보겠습니다(총 25개의 타일이 있다고 생각합니다). 3 * 3크기인 원도우의 중앙을 맞출 수 있는 타일은 3 * 3격자를 형성하믄 9개뿐입니다(그림 5-5참고). 따라서 출력 특성 맵은 3 * 3 크기가 됩니다. 크기가 조금 줄어들었습니다. 여기에선느 높이와 너비차원을 따라 정확히 2개의 타일이 줄어들었습니다. 앞선 예에서도 이런 경계 문제를 볼수 있습니다. 첫 번째 합성곱 층에서 28 * 28 크기의 입력이 26 * 26 크기가 되었습니다.
입력과 동일한 높이와 너비를 가진 출력 특성 맵을 얻고 싶다면 패딩(padding)을 사용할 수 있습니다. 패딩은 입력 특성 맵의 가장자리에 적절한 개수의 행과 열을 추가합니다. 그래서 모든 입력 타일에 합성곱 원도우의 중앙을 위치시킬 수 있습니다. 3 * 3원도우라면 아래에 하나의 행을 추가하고 오른쪽, 왼졲에 하나의 열을 추가합니다. 5 * 5원도우라면 2개의 행과 열을 추가합니다.
Conv2D 층에서 패딩은 padding 매개변수로 설정할 수 있습니다. 2개의 값이 가능합니다. "valid"는 패딩을 사용하지 않는다는 뜻입이다(원도우를 놓을 수 있는 위치만 사용합니다). "same"은 "입력과 동일한 높이와 너비를 가진 출력을 만들기 위해 피딩한다." 라는 뜻입니다. padding 매개변수의 기본값은 "valid" 입니다.

- 합성곱 스트라이드 이해하기
출력 크기에 영향을 미치는 다른 요소는 스트라이드 입니다. 지금까지 합성곱에 대한 설명은 합성곱 원도우의 중앙 타일이 연속적으로 자나간다고 가정한 것입니다. 두 번째 연속적인 원도우 사이의 거리가 스트라이드라고 불리는 삽성곱의 파라미터입니다. 스트라이드의 기본값은 1입니다. 스트라이드가 1보가 큰 스트라이드 합성곱도 가능합니다. 그림 5-7에서 5 * 5 크기의 입력(패딩 없음)에 스트라이드 2를 사용한 3 * 3크기의 원도우로 합성곱하여 추출한 패치를 볼수 있습니다.
스트라이드 2를 사용했다는 것은 특성 맵의 너비와 높이가 2의 배수로 다운샘플링되었다는 뜻입니다(경계문제가 있다면 더 줄어듭니다). 스트라이드 합성곱은 실정에서 드물게 사용됩니다. 하지만 어떤 모델에서는 유용하게 사용될 수 있으므로 잘 알아 둘 필요가 있습니다.
특성 뱁을 다운샘플링하기 위해서 스트라이드 대신에 첫 번째 컨브넷 예제에 상요된 최대 풀링(max pooling)연산을 사용하는 경우가 많습니다. 최대 풀링에 대해 좀 더 자세히 알아보겠습니다.


5.1 합성곱 신경망 소개

 컨브넷 정의와 컨브넷이 컴퓨터 비전 관련 작업에 잘 맞는 이유에 대해 이론적 배경을 알아봅시다. 하지만 먼저 간단한 컨브넷 예제를 둘러보죠. 2장에서 환전 연결 네트워크(densely connected network)로 풀었던(이 방식의 테스트 정확도는 97.8%였습니다) MNIST숫자 이미지 분류에 컨브넷을 사용해 보겠습니다. 기본적이 컨브넷이라도 2장에서 다룬 완전 연결된 모델의 성능을 훨씬 앞지를 것입니다.

다음 코드는 기본거인 커브넷의 모습입니다. Conv2D와 MaxPooling2D층을 쌓아 올렸습니다. 잠시 후에 이들이 무성인지 배웁니다.


    from keras import layers

    from keras import models

    

    model = moldes.Sequential()

    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))

    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Conv2D(643, (3, 3), activation='relu'))

    model.add(layers.MaxPooling2D((2, 2)))

    model.add(layers.Conv2D(64, (3, 3), activation='relue'))


컨브넷이 (image_height, image_width, image_channels) 크기의 입력 텐설르 사용한다는 점이 중요합니다(배치 차원은 포함하지 않습니다). 이 예제에서는 MNIST 이미지 포맷인 (28, 28, 1) 크기의 입력을 처리하도록 컨브넷을 설정해야 합니다. 이 때문에 첫 번째 층의 매개 변수로 input_shape=(28, 28, 1)을 전달했습니다.

지금까지의 컨브넷 구조를 출력해 보죠

>>> model.summary()

--------------------------------------------------------------------------------------------

Layer(type)                    Ouput Shape                Params #

========================================================

conv2d_1(Conv2D)        (None, 26, 26, 32)            320

---------------------------------------------------------------------------------------------

maxpooling2D_1(MaxPooling2D)        (None, 13, 13, 32)        0

----------------------------------------------------------------------------------------------

conv2d_2(Conv2D)        (None, 11, 11, 64)            18496

-----------------------------------------------------------------------------------------------

maxpooling2d_2 (MaxPooling2D)        (None, 5, 5, 64)        0

------------------------------------------------------------------------------------------------

conv2d_3 (Conv2D)        (None, 3, 3, 64)                36928

==========================================================

Total params: 55,744

Trainable params: 55,744

Non-trainable params: 0

Conv2D와 MaxPooling2D 층의 출력은 (height, width, channels) 크기의 3D텐서입니다. 높이와 너비 차원은 네트워크가 깊어질수록 작아지는 경향이 있습니다. 채널의 수는 Conv2D층에 전달된 첫 번째 매개변수에 의해 조절됩니다(32개 또는 64개).

다음 단계에서 마지막 층의 ((3, 3, 64) 크기인) 출력 텐서를 완전 연결 네트워크에 주입합니다. 이 네트워크는 이미 익숙하게 보았던 Dense 층을 쌓은 분류기입니다. 이 분류기는 1D벡터를 처리하는데, 이전 층의 출력이 3D 텐서입니다. 그래서 먼저 3D출력을 1D텐서로 펼쳐야 합니다. 그다음 몇 개의 Dense층을 추가합니다.

    

    model.add(layersd.Flatten())

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

    model.add(layers.Dense(10, activation='softmax'))

10개의 클래스를 분류하기 위해 마지막 층의 출력 크기를 10으로 하고 소프트맥스 활성화함수를 사용합니다. 이제 전체 네트워크는 다음과 같습니다.

>>> model.summary()

Layer(type)                               Output Shape                Param #

==========================================================

conv2d_1 (Conv2D)                (None, 26, 26, 32)                320

maxpooling2d_1 (MaxPooling2D)        (None, 13, 13, 32)            0

conv2d_2 (Conv2D)                (None, 11, 11, 64)                18496

maxpooling2d_2 (MaxPooling2D)        (None, 5, 5, 64)                0

conv2d_3 (Conv2D)                (None, 3, 3, 64)                    36928

flatten_1 (Flatten)                    (None, 576)                            0

dense_1 (Dense)                    (None, 64)                            36928

dense_2 (Dense)                    (None, 10)                            650

===========================================================

Total params:93,322

Trainable params: 93,322

Non-trainable params: 0

여기에서 볼 수 있듯이 (3, 3, 64) 출력이 (576,)크기의 벡터로 펼쳐진 후 Dense 층으로 주입되었습니다.

이제 MNIST숫자 이미지에 이 컨브넷을 훈련합니다. 2장의 MNIST예제 코드를 많이 재상요하겠습니다.


        from keras.datasets import mnist

        from keras.utils import to_categorical

    

        (train_iamges, train_labels), (test_images, test_labels) = mnist.load_data()

        train_images = train_images.reshape((60000, 28, 28, 1))

        train_images = train_images.astype('float32') / 255


        test_images = test_images.reshape((10000, 28, 28, 1))

        test_images = test_images.astype('float32') / 255


        train_labels = to_catetorical(train_labels)

        test_labels = to_catetorical(test_labels)


        model.compile(optimizer='resprop', 

                        loss='categorical_crossentropy',

                        metrics=['accuracy'])

        model.fit(train_images, train_labels, epochs=5, batch_size=64)


테스트 데이터에서 모델을 평가해 보죠.

>>> test_loss, test_acc = model.evaluate(test_images, test_labels)

>>> test_acc

0.9921

2장의 완전 연결 네트워크는 97.8%의 테스트 정확도를 얻은 반면에 기본적인 컨브넷은 99.2%의 테스트 정확도를 얻었습니다. 에러율이 (상태적으로) 64%나 줄었습니다. 나쁘지 않군요!

완전 연결된 모델보다 왜 간단한 컨브넷이 더 잘 작동할까요? 이에 대해 알아보기 위해 Conv2D 와 MaxPooling2D 층의 어떤 일을 하는지 살펴보겠 습니다.





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

 이 장에서 다룰 핵심 내용

1) 합성곱 신경망(컨브넷)의 이해

2) 과대적합을 줄이기 위해 데이터 증식 기법 사용

3) 특성 추출을 위해 사전 훈련된 컨브넷 사용

4) 사전 훈련된 컨브넷을 미세 조정하는 방법

5) 컨브넷에서 학습된 것과 컨브넷의 분류 결정 방식을 시각화하는 방법


이 장에서는 컨브넷(convnet)이라고도 불리는 합성곱 신경망(convolutional neural network)을 소개합니다. 이 딥러닝 모델은 거의 대부분의 컴퓨터 비전(computer vision) 애플리케이션에 사용됩니다. 거대 IT회사가 아니라면 대부분 작은 데이터셋을 다루므로 여기에서도 작은 훈련 데이터셋을 사용한 이미지 분류 문제에 컨브넷을 적용하는 법을 배우겠습니다.

4.6 요약

 1) 주어진 문제와 훈련할 데이터를 정의 합니다. 이 데이터를 수집하고 필요하면 레이블을 태킹합니다.

2) 성공을 어떻게 측정할지 선택하세요. 검증 데이터에서 모니터링할 지표는 무엇인가요?

3) 평가 방법을 결정하세요. 홀드아웃 검증이나 K-겹 교차 검증인가요? 검증에 사용해야 할 데이터의 양은 얼마나 되나요?

4) 단순한 랜덤 선택 모델보다 나은 통꼐적 검정려이 있는 첫 번째 모델을 만듭니다.

5) 과대적합된 모델을 만듭니다.

6) 검증 데이터ㅢ 성능에 기초하여 모델에 규제를 적용하고 하이퍼파라미터를 튜닝합니다. 머신러닝 연구의 대부분은 이단계에 집중됩니다. 하지만 큰 그림을 놓치지 마세요.

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

 이 단계가 대부분의 시간을 차지합니다. 반복적으로 모델을 수정하고 훈련하고 검증 데이터에서 평가합니다(이때 테스트 데이터를 사용하지 않습니다). 그리고 다시 수정하고 가능한 좋은 모델을 얻을 때까지 반복합니다. 적용해 볼 것은 다음과 같습니다.

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

2) 층을 추가하거나 제거해서 다른 구졸르 시도해 봅니다.

3)L1이나 L2또는 두 가지 모두 차가합니다.

4) 최적의 설정을 찾기 위해 하이퍼파라미터를 바꾸어 시도해 봅니다(층의 유닛 수나 옵티마이저의 학습률 등).

5) 선택적으로 특성 공학을 시도해 봅니다. 새로운 특성을 추가하거나 유용하지 않을 것 같은 특성을 제거합니다.

다음사항을 유념하세요. 검증 과정에서 얻은 피드백을 사용하여 모델을 튜닝할 때마다 검증 과정에 대한 정보를 모델에 누설하고 있다는 것입니다. 몇 번만 반복하는 것은 큰 문제가 되지 않습니다. 하지만 많이 반복하게 되면 결국 모델이 검증 과정에 과대적합될 것입니다(모델이 검증 데이터에서 전혀 훈련되지 않는데도 말입니다). 이는 검증 과정의 신뢰도를 감소시킵니다.

만족할 만한 모델 설정을 얻었다면 가용한 모든 데이터(훈려 데이터와 검증 데이터)를 사용해서 제품에 투입할 최종 모델을 훈련시킵니다. 그리고 마지막에 딱 한번 테스트 세트에서 평가합니다. 테스트 세트의 성능이 검증 데이터에서 측정한 것보다 많이 나쁘다면, 검증 과정에 전혀 신뢰성이 없거나 모델의 하이퍼파라미터를 튜닝하는 동안 검증 데이터에 과대적합된 것입니다. 이런 경우에는 좀 더 신뢰할 만한 평가 방법으로 바꾸는 것이 좋습니다(반복 K-겹 교차검증)

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

 통계적 검정력을 가진 모델을 얻었다면 이제 모델이 충분히 성능을 내느지 질문해 보야야 합니다. 주어진 문제를 적절히 모델링하기에 충분한 층과 파라미터가 있나요? 예를 들어 2개의 유닛을 가진 하나의 은닉 층으로 구성된 ㅔㄴ트워크가 있다고 가정합시다. 이 네트워크가 MNIST데이터셋에서 통계적 검정력을 가질 수 있지만 문제를 잘 해결하기에는 충분하지 않을 것입니다. 머신 러닝은 최적화와 일반화 사아의 줄다리기라는 점을 기억하세요. 과서적합과 과대적합 사이, 즉 과서용량과 과대용량의 경계에 적절히 위치한 모델이 이상적입니다. 이 경계가 어디에 위치하는 지 찾기 위해서는 먼저 지나쳐 보아야 합니다.

얼마나 큰 모델을 만들어야 하는지 알기 위해서는 과대적합된 모델을 만들어야 합니다. 이는 아주 쉽습니다.

1) 층을 추가합니다.

2) 층의 크기를 키웁니다.

3) 더 많은 에포크 동안 훈련합니다.

관심 대상인 훈련과 검증 지표는 물론 항상 훈련 손실과 검증 손실을 모니터링하세요. 검증 데이터에서 모델 성능이 감소하기 시작했을 때 과대적합에 도달한 것입니다.

다음 단계에서 규제와 모델 튜닝을 시작하여 과소적합도 아니고 과대적합도 아닌 이상적인 모델에 가능한 가깝도록 만듭니다.