본문 바로가기

딥러닝 & 머신러닝/딥러닝 지식

GAP (Global Average Pooling) : 전역 평균 풀링

위 그림처럼 Fully-Connected Layer(전결합층) 직전의 컨볼루션 레이어에서 채널 수, 즉 feature map의 수가 6개라고 합시다.

 

기존 FC Layer를 사용한 분류에서는 Flatten Layer를 이용해서 입력받은 값을 굉장히 긴 하나의 벡터로 만든 다음, 그 벡터를 FC Layer에 넣는 방식으로 하나하나 매핑해서 클래스를 분류했습니다. 이 과정에서 공간적 정보도 많이 잃어버리는데다가, 굉장히 많은 파라미터, 즉 가중치가 많이 필요하고, VGGNet의 경우 이 부분이 전체 계산량의 85%를 차지했습니다. 컨볼루션 레이어를 아무리 쌓아도 FC Layer 하나를 못 따라갈 정도입니다.

 

GAP(Global Average Pooling)는 이 문제를 효과적으로 해결합니다.

 

우선 분류할 클래스 수만큼 feature map을 마지막에 생성합니다. 위 그림에선 feature map이 6개니까 분류할 클래스 수가 6개라고 가정합시다. 그럼 그 feature map 안에 있는 특징값들의 평균을 구해서 각각의 출력 노드에 바로 입력하는 방식입니다. 위 그림에서는 각 feature map의 평균이 7, 4, 8, 6, 3, 5가 나왔습니다.

 

즉, 단순히 i번째 feature map의 평균값을 구해서 i번째 출력 노드에 입력하는 것입니다.

 

이 방식은 85%의 가중치를 없애므로 계산량과 모델의 무게가 줄어들고, 파라미터가 줄어드니까 덩달아 오버피팅 방지 효과도 따라옵니다. 그리고 이 방법이 정보량 손실이 많이 될 것 같고, 실제로도 그렇습니다. 이미지의 모든 값을 평균내버리는 건데, 정보를 잃지 않을 수 없습니다. 그러나 그럼에도 불구하고 성능이 좋다고 합니다.

 

 

 

분류 관점에서, 기존의 FC Layer는 1차원 벡터로 쭉 늘어뜨림으로써 공간적 정보를 잃는 반면, GAP를 쓰면 사상(embedding)된 특징 공간에서 이미지의 특정 영역이 response 되고, 이를 class activation map으로 시각화 함으로써 확인할 수 있기 때문입니다.

 

더 자세히 말하면, GAP 연산은 채널 별로 평균을 낼 뿐이고, 평균을 통해 얻은 클래스 개수만큼의 1차원 벡터와 클래스 라벨로 loss를 계산해 업데이트 했을 때, GAP 연산의 결과가 아닌 GAP 연산을 거치기 전의 컨볼루션 필터(커널)들을 학습시킵니다. 이때 역전파를 통해 loss를 업데이트하면서 해당 컨볼루션 필터들은 이미지의 특징을 더 잘 잡도록 훈련될 것이며, 그 부분이 response가 됩니다. 이 response 덕에 GAP 연산을 적용하면 FC Layer에 비해 location 정보를 상대적으로 덜 잃는 것으로 볼 수 있습니다.

 

또한, FC Layer에 입력되는 노드 수 같은 걸 계산할 필요도 없어집니다. 어차피 각 채널의 평균값만 계산하는데 그것마저도 파이토치나 케라스 같은 프레임워크를 사용하면 자동으로 되니까요. 그리고 각 채널의 평균값을 계산하므로 해당 이미지의 global context 정보를 얻을 수 있다는 장점도 큽니다.

 

그래서 최근 나오는 모델들은 거의 전부 다 GAP 방식을 사용한다고 합니다. 모델의 경량화 효과에 오버피팅 방지 효과까지 따라오니, 안 쓸 이유가 없어 보입니다.

 

요약하면 GAP의 장점은 다음과 같습니다.

 

1. Location 정보를 FC Layer보다 적게 잃는다.

2. 파라미터를 차지하지 않아 계산 속도가 빠르다.

3. 마찬가지로 파라미터가 많아지지 않기 때문에 오버피팅을 방지한다.

4. feature map 안의 값들의 평균을 사용하기 때문에 global context 정보를 가진다.

(Global average pooling operation which aggregates the spatial information into channels)