Pooling Layer의 개념과 용례
Tensorflow와 PyTorch에서는 여러 종류의 Pooling Layer 함수를 지원하지만,
이미지 분류 모델에 있어 그 중 가장 많이 활용되는 것은 MaxPooling2D 쪽이다.
그렇다면 Pooling Layer들은 어떤 역할을 하는가?
풀링은 차례로 처리되는 데이터의 크기를 줄인다. 이 과정으로 모델의 전체 매개별수의 수를 크게 줄일 수 있다.
풀링에는 MaxPooling과 AveragePooling이 존재하는데,
- MaxPooling은 해당 영역에서 최댓값을 찾는 방법이고, (위 그림이 MaxPooling의 예시이다.)
- AveragePooling은 해당 영역의 평균값을 계산하는 방법이다.
그렇다면 이러한 과정(Pooling)을 왜 거쳐야 하는가?
더 높은 정확도를 위해서는 필터가 많아야 하는데, 필터가 늘어날 수록 Feature Map이 늘어난다.이는 딥러닝 모델의 Dimension이 늘어난다는 것이고, High Dimension 모델은 그만큼 파라메터의 수 또한 늘어난다.이는 Over fitting의 문제점 뿐만이 아니라, 모델의 사이즈와 레이턴시에도 큰 영향을 끼친다.
따라서 차원을 감소시킬 필요성이 있는데,이것을 하는 방법이 Pooling Layer를 활용하는 것이다.
또한, 자주 사용되는 Pooling Layer의 종류로는 MaxPooling Layer와 GlobalAveragePooling Layer가 존재하는데,
MaxPooling Layer는 TF2.X와 PyTorch에서 각각 아래의 용례로 사용된다.
# Tensorflow 2.X
tf.keras.layers.MaxPool2D(
pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs
)
# PyTorch
torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1,
return_indices=False, ceil_mode=False)
MaxPool2d는 PyTorch Official Doc에 의하면 아래와 같은 수학식을 가진다.
이때, MaxPool2d가 하는 역할은 아래 그림으로 확실히 확인이 가능하다.
MaxPooling Layer는 Feature Map들이 쌓여있는 스택을 인풋으로 받으며, Kernel Size(Filter Size / Window Size)와 stride를 인자로 받는다.
위 예시 같은 경우, kernel size가 2x2이며, stride가 2이기 때문에,
(stride는 인풋 데이터에 커널(필터)을 적용할 때 이동할 간격을 조절하는 것이다.)
왼쪽의 16x16의 윈도우는 2x2의 4구역으로 이루어지게 된다.
만약 kernel size는 2x2이지만, stride가 1이었다면, 왼쪽의 16x16 윈도우는 2x2의 9구역으로 나뉘게 되는 것이다.
이때 MaxPooling은 각각의 구역에서 가장 큰 수인 [5, 9, 8, 9]를 뽑아내고,만약 AveragePooling이라면 각각의 구역의 평균값(정수)인 [3, 4, 4, 4]를 뽑아낼 것이다.
이로써 특징 탐색 영역(Feature Map)은 1/4로 축소되고, 위 층에서의 특징 추출 및 추론에 대한 부담은 크게 줄어든다.더불어 분류 작업에 유리한 불변성질(Invariance)을 얻을 수 있는 장점도 있다.MaxPooling은 위치에 상관없이 눈, 코, 입 등의 특징(Feature)을 인식할 수 있도록 해준다. (그렇기에 이미지 분류에서는 MaxPooling이 자주 사용된다.)
물론 단점 또한 존재한다.탐색 속도를 높이고자 고안한 Max Pooling은 CNN의 치명적인 취약점으로도 작용한다.Max Pooling을 거치면 이미지 구성 요소의 공간 관계에 대한 정보를 잃는다.그렇기 때문에 누군가 일부러 그려놓은 눈이 엉덩이에 붙어있고, 코가 손에 달려있고, 눈이 정수리에 달려있는 그림도 사람으로 인식하는 등, 상대적인 위치, 방향과 상관없이 특징 추출이 된다.또한 방향(Orientation)이나 비율이 달라지면 서로 다른 객체로 인식하는 단점이 있다.
두 번째로는, Global Average Pooling Layer가 있다.Global Average Pooling Layer는 TF2.X와 PyTorch에서 각각 아래의 용례로 사용된다.
# Tensorflow 2.X
tf.keras.layers.GlobalAveragePooling2D(
data_format=None, **kwargs
)
# PyTorch
# In PyTorch, use AdaptiveAvgPool2d
torch.nn.AdaptiveAvgPool2d(output_size)
AdaptiveAvgPool2d을 Tensorflow의 GlobalAveragePooling2D처럼 활용하기 위해서는 output_size 인자로 1을 넣으면 된다.
# Example
torch.nn.AdaptiveAvgPool2d(1)
Global Average Pooling은 위 그림처럼 작동하며,
이때는 Kernel Size(Filter Size/Window Size)나 stride를 지정해주지 않는다. Tensorflow에서도
x = GlobalAveragePooling2D()(x) 같이 사용하며, PyTorch에서도 output 인자에 1만 넣어주면 된다.
이때 Global Average Pooling Layer는 각 Feature Map 상의 노드값들의 평균을 뽑아낸다.이런 방식으로 Global Average Pooling Layer는 레이어 집합을 인풋으로 하여 벡터를 아웃풋으로 낸다.위에서 보듯, 3가지 엔트리를 갖고 있는 벡터가 아웃풋이 된다.
다음 포스팅에서 또 이어서 계속!