- 1. Basic Vision Model
- [12′ NIPS] ImageNet Classification with Deep Convolutional Neural Networks (AlexNet) 핵심 리뷰
- [15′ CVPR] Going deeper with convolutions (GoogleNet, inception) 핵심 리뷰
- [15′ ICLR] VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION (VGGNet)
- [15′ ICML] Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
- [16′ CVPR] Deep Residual Learning for Image Recognition (ResNet)
- 2. Vision Model 응용 버전
- [16′ BMVC] Wide ResNet : Wide Residual Networks
- [17′ CVPR] Xception: Deep Learning with Depthwise Separable Convolutions
- [17′ ICLR] FRACTALNET: ULTRA-DEEP NEURAL NETWORKS WITHOUT RESIDUALS
- [17′ CVPR] Densely Connected Convolutional Networks (DenseNet)
- [17′ CVPR] Deep Pyramidal Residual Networks (PyramidNet)
- [17′ CVPR] Active Convolution: Learning the Shape of Convolution for Image Classification
- [17′ CVPR] Residual Attention Network for Image Classification
- [18′ CVPR] SENet : Squeeze and excitation networks
- [18′ BMVC] BAM: Bottleneck Attention Module
- [18′ ECCV] CBAM : convolutional block attention module
- [19′ CVPR] Selective Kernel Networks (SKNet)
- [19′ ICML] EfficientNet : Rethinking Model Scaling for Convolutional Neural Networks
- [21′ ICLR] Vision Transformer : AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE
- [21′ NIPS] MLP-Mixer: An all-MLP Architecture for Vision
- [논문 리뷰] KAN: Kolmogorov–Arnold Networks
1. 들어가며
이번 글에서는 2018년 ECCV에 발표된 CBAM : convolutional block attention module 논문을 리뷰합니다. 이 논문은 CBAM이라는 별칭으로 불리며, 이번 글에서도 CBAM으로 지칭하겠습니다.
먼저 제목의 의미를 생각해 볼까요?
제목으로부터 우리는 이번 논문은 BAM과 비슷한 철학을 공유하는 다른 방법론이라는 것을 알 수 있습니다. 즉 CNN에 삽입할 수 있는 Attention 모듈이라는 것이죠. 반면 Convolutional Block을 사용하는 차이점이 있다고 생각해 볼 수 있습니다.
이번 글의 순서는 다음과 같습니다. 먼저 CBAM이 풀고자 했던 기존 방법의 문제점을 살펴보겠습니다. 다음으로 해당 문제를 풀기 위한 CBAM의 큰 그림과 CBAM을 구성하는 모듈의 자세한 내용을 살펴봅니다. 이어서 파이썬을 사용하여 CBAM을 직접 구현해봅니다. 이 과정을 통해 CBAM을 정확하게 이해하는지 되짚어 봅니다. 마지막으로 실험 결과를 살펴보며 CBAM의 효과가 무엇인지 확인하고 의의를 정리해보겠습니다.
2. 기존 방법의 문제점
먼저 CBAM이 풀고자 했던 기존 방법의 문제점을 생각해 보겠습니다.
이때의 기존 방법이란 Attention이 적용되지 않은 CNN과 SENet, BAM 등을 포함합니다. SENet은 Channel Attention 기능을 적용하여 입력 Feature Map에 대해 더 중요한 ‘무엇’에 집중할 수 있도록 했습니다.
위 그림은 BAM의 문제 의식을 표현한 그림입니다. BAM은 SENet이 Channel Attention만 사용하고 있는 점을 문제로 지적했죠. 이렇게 되면 ‘무엇’에 집중할 수는 있지만, ‘어디에’는 집중할 수 없다는 점을 파고들어 Channel Attention과 Spatial Attention을 모두 적용하였습니다. CBAM은 이름에서도 알 수 있듯 BAM의 철학을 계승하여 발전시킨 모델이라고 할 수 있습니다. 따라서 본문에서는 계속해서 BAM과의 비교를 통해 논리를 전개합니다. BAM의 자세한 내용은 해당글을 참고 바랍니다.
3. 제안 방법
지금까지 CBAM이 풀고자 했던 문제를 살펴봤습니다. 요약하자면 CBAM은 BAM과 마찬가지로 입력 Feature Map에 대해 Channel Attention과 Spatial Attention을 적용하고자 하는 모듈입니다.
이번 챕터에서는 CBAM은 어떤 방법으로 Channel Attention과 Spatial Attention을 적용했는지 각각 자세히 살펴보겠습니다. 또한 BAM과의 비교해 보며 공통점과 차이점을 생각해 보겠습니다.
3-1. 큰 그림
먼저 CBAM의 큰 그림을 살펴보겠습니다. BAM에서는 입력 Feature Map에 대해 Channel Attention과 Spatial Attention 모듈을 병렬로 배치하여 연결하였죠.
CBAM에서는 위의 그림과 같이 Channel Attention 모듈과 Spatial Attention 모듈을 직렬로 연결합니다. 즉 입력 Feature Map에 대해서 먼저 ‘무엇’에 더 집중할 것인지 Channel Attention을 적용합니다. 이렇게 나온 중간 Feature Map에 다시 ‘어디’에 더 집중할 것인지 Spatial Attention을 적용하죠. 최종적으로 나온 Feature Map은 Channel Attention과 Spatial Attention이 모두 적용되어 ‘무엇’과 ‘어디’를 볼 것인지 강조되어 있는 모습을 볼 수 있습니다. 이를 CBAM 논문에서는 다음과 같은 그림으로 표현하고 있습니다.
Input Feature Map에 대해 Channel Attention을 적용하여 나온 Attention Score를 곱해주는 모습을 볼 수 있습니다. 그리고 이어서 Spatial Attention을 적용하여 나온 Attention Score도 곱하여 최종 Refined Feature Map을 구성하는 모습을 볼 수 있습니다. 이러한 CBAM의 과정은 아래와 같이 수식으로 깔끔하게 표현할 수 있습니다.
- F : Feature Map
- F’ : Channel Attention을 적용한 Feature Map
- F” : Spatial Attention을 적용한 Feature Map
- ⊗ : Element Wise Multiplication
- Mc : Channel Attention Module
- Ms : Spatial Attention Module
3-2. Channel Attention Module
이제 큰 그림을 살펴봤으니 하나씩 자세히 알아보겠습니다.
먼저 첫 번째 기능인 Channel Attention 모듈부터 살펴보겠습니다. CBAM의 Channel Attention 기능을 살펴보기 전에 먼저 BAM의 Channel Attention 연산을 살펴보겠습니다.
위 그림은 BAM의 Channel Attention 연산을 표현한 그림입니다. 먼저 입력 Feature Map에 대해 Channel별로 Average Pooling을 적용하는 모습을 볼 수 있습니다. 이때 Pooling은 정보를 압축해 주는 역할을 하고 있죠. Feature Map을 채널별로 분리한 정보의 사이즈는 (WxHx1)이니 이를 하나의 값으로 압축해 주는 겁니다. 그렇게 나온 압축된 값에 대해 MLP를 사용하여 학습 데이터를 통해 채널별 중요도를 연산하는 모습을 볼 수 있습니다.
그런데 CBAM의 저자들은 이런 의문을 제기합니다. ‘정보를 압축하기 위해 Pooling 연산을 사용하는 것까지는 좋다. 그런데 왜 Average Pooling만 사용하지? Max Pooling도 같이 사용하면 더 좋을 텐데?’
Average Pooling과 Max Pooling은 어떤 의미적 차이가 있는지 생각해 볼까요?
Average Pooling은 평균값이니 여기에 대략적으로 어떤 정보가 들어있는지를 뽑아준다고 생각할 수 있습니다. 따라서 Average Pooling을 사용해서 정보를 압축하겠다는 생각도 일리가 있죠.
반면 Max Pooling은 조금 의미가 다른데요. Max Pooling은 가장 의미 있는 정보 외에는 무시합니다. 따라서 가장 중요한 정보를 희석시키지 않고 추출할 수 있죠.
그 말은 Average Pooling과 Max Pooling 모두 정보 압축 기능으로 사용할 수 있되, 각자의 ‘관점’이 다르다고 표현할 수 있습니다. 다양한 과점의 정보를 사용하면 당연히 모델을 학습시키기에 더 유리하겠죠? 따라서 CBAM은 Average Pooling과 Max Pooling을 병렬로 연결하여 두 정보를 모두 사용하는 방법을 채택합니다.
위 그림은 CBAM의 Channel Attention 연산 방법을 표현한 그림입니다. 가장 먼저, 입력 Feature Map에 대해 Max Pooling과 Average Pooling을 병렬로 연산하는 모습을 볼 수 있습니다. 이 결과로 각각 (1x1xC) 사이즈의 Pooling 결과물이 나옵니다. 이 결과물들은 각각 MLP로 연결되어 중요도를 계산하게 되죠. 이렇게 나온 두 결괏값은 동일한 위치끼리 더해져 (element wise summation) 최종적으로 Sigmoid를 거치게 됩니다. 최종적으로는 (1x1xC) 사이즈의 0~1 값을 갖는 Attention Score가 나오게 되죠. 이러한 CBAM의 Channel Attention 연산을 논문에서는 다음과 같이 표현하고 있습니다.
동일한 논리를 표현한 모습을 볼 수 있습니다.
또한 지금까지의 긴 이야기를 수식으로는 아래와 같이 깔끔하게 정리할 수 있습니다.
- Mc : Channel Attention Module
- 𝜎 : Sigmoid
이때 명심해야 할 건 MLP는 Max Pooling과 Average Pooling 결과물에 공통으로 적용된다는 것입니다. 따라서 두 MLP는 동일한 가중치를 갖고 있습니다.
3-3. Spatial Attention Module
다음은 이어서 CAM의 Spatial Attention Module을 살펴보겠습니다.
Spatial Attention은 Channel Attention과 달리 ‘어디’에 집중할 것인지를 의미합니다. 즉 입력 Feature Map에 대해 Spatial Attention 결과는 (WxHx1) 사이즈로 나와야 합니다. CBAM에서는 Channel Attention에서와 마찬가지로 Max Pooling과 Average Pooling 연산을 사용합니다.
위 그림은 CBAM의 Spatial Attention 연산 방법을 나타낸 그림입니다.
입력 Feature Map에 대해 Max Pooling과 Average Pooling을 병렬로 연산해 주는 모습을 볼 수 있습니다. 이때의 Pooling은 Channel Attention때와 달리 채널축으로 수행해 줍니다. 따라서 (WxHxC) 사이즈의 정보를 (WxHx1) 사이즈로 압축해 주는 역할을 합니다. 이렇게 나온 정보는 각 위치에 무엇이 있는지를 나타내겠죠. Max Pooling으로 나온 정보는 각 위치에서 가장 의미 있는 정보가 무엇인지를 나타낼 겁니다. Average Pooling으로 나온 정보는 각 위치에 있는 평균적인 정보를 나타내겠죠. 우리는 이 두 정보를 모두 활용해야 하니 이 둘을 Concatenation 하여 합쳐줍니다. 이렇게 합쳐진 정보는 입력 Feature Map의 압축된 정보에 해당합니다. 아직 Attention을 적용한 건 아니죠.
이제 Attention을 적용하기 위해 학습 가능한 연산을 붙여 학습 데이터로부터 학습해줘야 합니다. Channel Attention에서는 이를 위한 연산으로 MLP를 사용했죠. 이번에는 Convolution을 사용합니다. Spatial 한 정보를 연산하기에는 MLP보다 Convolution이 적합하기 때문이죠. 이렇게 나온 결괏값은 (WxHx1) 사이즈를 갖습니다. 이제 최종적으로 Sigmoid를 적용해 주면 (WxHx1) 사이즈의 0~1 값을 갖는 Spatial Attention Score Map을 얻을 수 있습니다.
지금까지의 Spatial Attention 연산 방법을 논문에서는 다음과 같이 표현합니다.
마찬가지로 Max Pooling과 Average Pooling을 적용한 뒤 Convolution과 Sigmoid를 적용하는 모습을 볼 수 있습니다. 또한 이러한 Spatial Attention 연산은 다음과 같이 한 줄의 수식으로 깔끔하게 표현 가능합니다.
- f7×7 : 7×7 Convolution
- 𝜎 : Sigmoid
3-5. CBAM과 BAM의 비교
지금까지 CBAM의 구성 요소를 하나씩 자세히 살펴봤습니다. 마지막으로 전체적으로 BAM CBAM의 공통점과 차이점을 하나씩 살펴보겠습니다.
BAM과 CBAM은 CNN의 중간에 삽입할 수 있는 Attention Module이라는 공통점이 있습니다. 또한 이때의 Attention을 Channel Attention과 Spatial Attention으로 구성했다는 점도 동일하죠.
차이점도 존재합니다.
첫 번째로 가장 큰 차이는 Channel Attention과 Spatial Attention의 배치 방법입니다.
위 그림은 BAM과 CBAM의 전체 흐름을 표현한 그림입니다. 각각의 Channel Attention과 Spatial Attention의 배치 방법을 비교해 볼 수 있습니다. 먼저 BAM은 Channel Attention과 Spatial Attention을 병렬로 배치했습니다. 따라서 입력 Feature Map에 대해 Channel Attention과 Spatial Attention을 각각 계산한 뒤 그 결과를 합쳐주는 모습이죠. 반면 CBAM은 Channel Attention과 Spatial Attention을 직렬로 배치했습니다. 따라서 입력 Feature Map에 대해 Channel Attention을 먼저 계산한 뒤, 그 결과물에 대해 다시 Spatial Attention을 계산하고 있습니다.
두 번째 차이점은 Channel Attention의 계산 방법입니다.
위 그림은 BAM과 CBAM의 Channel Attention 계산 방법을 나타낸 그림입니다. 먼저 BAM은 Average Pooling을 사용하여 정보를 압축한 뒤 MLP로 중요도를 계산하는 모습입니다. 반면 CBAM은 Average Pooling 뿐만 아니라 Max Pooling도 사용하고 있죠. 이 둘을 병렬로 연결한 뒤 각각 MLP를 거쳐 중요도를 계산하여 최종적으로 Score를 합쳐주는 모습입니다.
세 번째 차이점은 Spatial Attention의 계산 방법입니다.
위 그림은 BAM과 CBAM의 Spatial Attention 계산 방법을 나타낸 그림입니다. 먼저 BAM은 1×1 Convolution을 사용하여 채널수를 줄여주고 Dilated Convolution을 사용하여 위치별 관계를 계산하는 모습입니다. 반면 CBAM은 Pooling으로 위치별 정보를 압축한 뒤 7×7 Convolution으로 위치별 관계를 계산하고 있죠. 이때도 Channel Attention 계산과 마찬가지로 Average Pooling과 Max Pooling을 병렬로 연결하여 연산하는 모습입니다.
4. 파이썬 구현
이번 챕터에서는 파이썬을 사용하여 CBAM을 직접 구현해봅니다. 이 과정을 통해 위에서 살펴본 내용을 정확히 이해했는지 되짚어보겠습니다.
4-1. Import Module
먼저 필요한 Module들을 Import 해줍니다.
import torch
import torch.nn as nn
import torch.nn.functional as F
4-2. CBAM Class 정의하기
다음으로 CBAM Class를 정의합니다. __init__ 함수에서는 Channel Attention과 Spatial Attention 기능을 각각 정의해주는 모습을 볼 수 있습니다. 이어서 forward 함수에서는 Channel Attention과 Spatial Attention을 직렬로 연결해주는 모습을 볼 수 있습니다.
class CBAM(nn.Module):
def __init__(self, channel, reduction=16):
super(CBAM, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.max_pool = nn.AdaptiveMaxPool2d(1)
# Channel Attention
self.channel_fc = nn.Sequential(
nn.Linear(channel, channel // reduction),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel)
)
# Spatial Attention
self.spatial_conv = nn.Conv2d(2, 1, kernel_size=7, padding=3, bias=False)
def forward(self, x):
b, c, _, _ = x.size()
# Channel Attention
avg_out = self.channel_fc(self.avg_pool(x).view(b, c))
max_out = self.channel_fc(self.max_pool(x).view(b, c))
channel_att = torch.sigmoid(avg_out + max_out).view(b, c, 1, 1)
x = x * channel_att
# Spatial Attention
avg_out = torch.mean(x, dim=1, keepdim=True)
max_out, _ = torch.max(x, dim=1, keepdim=True)
spatial_att = torch.sigmoid(self.spatial_conv(torch.cat([avg_out, max_out], dim=1)))
return x * spatial_att
4-3. CBAM 사용하기
이렇게 정의한 CBAM은 아래와 같이 사용할 수 있습니다.
# Create the CBAM module
cbam_module = CBAM(256)
5. 효과
지금까지 CBAM의 구성 요소를 하나씩 자세히 살펴봤습니다. 이번에는 실험 결과를 통해 CBAM의 효과를 살펴보도록 하겠습니다.
5-1. Image Classification
Image Classification 실험 결과를 살펴보겠습니다.
위 그림은 ImageNet 데이터셋에 대한 다양한 모델의 성능을 측정한 표입니다. ResNet, WideResNet, ResNeXt 등의 기본 모델과 SE, CBAM을 적용했을 때의 성능을 비교하고 있습니다. 실험 결과를 통해 크게 두 가지 포인트를 찾을 수 있습니다.
첫 번째는 CBAM을 추가해 주면 적은 계산양만으로도 많은 성능 개선을 얻을 수 있다는 점입니다.
두 번째로 이러한 성능 개선량이 SE를 적용했을 때 보다 더 크다는 점입니다.
위 그림은 MobileNet과 MobileNet에 SE, CBAM을 적용한 모델의 성능을 비교한 표입니다.
마찬가지로 MobileNet에서도 CBAM의 동일한 효과를 확인할 수 있습니다.
위 그림은 ResNet과 ResNet에 SE를 적용한 모델, 그리고 ResNet에 CBAM을 적용한 모델의 Attention Map을 비교한 그림입니다. ImageNet 데이터셋을 학습한 뒤 각 클래스별 Attention Map을 비교한 것이죠. 이를 통해 각 모델이 해당 클래스 정보를 어디서 얻고 있는지를 알 수 있습니다. 이때의 방법은 grad-CAM을 사용했습니다.
결과를 보면 ResNet 모델도 해당 물체에 제법 잘 Attention 하고 있는 모습이죠. 하지만 SE와 CBAM을 적용한 모델이 훨씬 더 해당 물체에 잘 Attention 하는 모습을 볼 수 있습니다. 그리고 이러한 Attention 능력은 SE보다 CBAM이 더 정교하게 좋은 모습을 볼 수 있습니다.
5-2. Object Detection
다음은 Object Detection 실험 결과를 살펴보겠습니다.
위 그림은 MS COCO 데이터셋에 대한 성능 결과표입니다. ResNet과 ResNet에 CBAM을 추가한 모델의 성능을 비교하고 있습니다. ImageNet에서와 마찬가지로 CBAM을 추가했을 때 성능이 개선되는 모습을 볼 수 있습니다.
위 그림은 VOC2007 데이터셋에 대한 성능 비교 결과표입니다. 마찬가지로 VGGNet과 MobileNet에서 CBAM을 적용했을 때 성능이 개선되는 모습을 볼 수 있죠. 위 두 가지 실험 결과를 통해 CBAM은 Image Classification과 Object Detection 모델의 성능 개선 효과가 있음을 알 수 있습니다.
6. 의의
다음으로 CBAM 논문의 의의를 정리해보겠습니다.
첫 번째 의의는 Channel Attention과 Spatial Attention을 통합한 방법을 제안한 것입니다. CBAM은 Channel Attention과 Spatial Attention을 동시에 고려합니다. Channel Attention은 어떤 채널이 중요한지를, Spatial Attention은 어떤 위치의 픽셀이 중요한지를 판단합니다. 이 두 가지를 통합함으로써, 모델은 더욱 정확하고 효율적인 예측을 할 수 있게 됩니다.
두 번째 의의는 기존 아키텍쳐와 높은 호환성을 가진 방법을 제안했다는 점입니다. CBAM은 기존의 다양한 CNN 아키텍처에 쉽게 적용할 수 있습니다. 이는 개발자가 별도의 복잡한 튜닝 없이도 기존 모델의 성능을 향상시킬 수 있다는 것을 의미합니다. 따라서 CBAM은 기존 네트워크를 더욱 강력하게 만드는 유연한 도구로 작용합니다.
이 두 가지 의의는 CBAM이 단순히 성능을 향상시키는 것을 넘어, 딥러닝 모델을 더욱 효율적이고 정확하게 만드는 중요한 기술적 발전이라고 할 수 있습니다.
7. 결론
지금까지 2018년 ECCV에 발표된 CBAM : convolutional block attention module 논문을 리뷰했습니다.
먼저 CBAM이 해결하고자 하는 문제점을 살펴봤습니다. CBAM 이전에는 SENet과 BAM이 동일한 문제를 해결하고자 했었는데요. CBAM은 BAM과 동일한 철학을 공유하면서 성능을 더 개선한 모델이라고 할 수 있습니다. 이를 BAM과의 비교를 통해 살펴봤습니다. 또한 다양한 실험 결과를 통해 CBAM은 Image Classification과 Object Detection 모델의 성능 개선 효과가 있음을 입증했습니다.