앞선 컨브넷 예제에서 특성 맵의 크기가 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/)을 사용할 수 있습니다. 코랩은 구글이 만든 교육과 연구를 위한 주피터 노트북 환경으로 구글 클라우드의 컴퓨팅 자원을 무료로 사용할 수 있습니다.
댓글 없음:
댓글 쓰기