본문 바로가기
딥러닝관련

CAM 및 Grad-CAM 정리

by 머리올리자 2021. 1. 29.

CAM(Class Activation Map) - Learning Deep Features for Discriminative Localization

 

  • Global Average Pooling layer가 imagelevel labels에 대해서 trained 되었음에도 불구하고 Convolutional Neural Network(CNN)의 localization ability를 가질 수 있도록 하는 방법

출처 : Learning Deep Features for Discriminative Localization

 

  • 특정 범주에 대한 class activation map은 해당 범주를 식별하기 위해 CNN에서 사용하는 discriminative image region을 나타냅니다. (즉. CAM은 아래와 같이 특정 클래스가 어디 위치에 있는지 보여주는 이미지)

출처 : Learning Deep Features for Discriminative Localization

  • 마지막 output 레이어(즉, classification의 경우 softmax) 이전 레이어에서, convolutional feature map에 대해서 global average pooling을 적용하고 그 output features들을 fully-connected 레이어처럼 사용합니다.
  • 이런 simple connectivity structure로 convolution feature map에 output 레이어의 weight를 다시 투영(projecting back)하여 이미지 영역의 중요성을 식별할 수 있습니다. -> 이를 class activation mapping
  • Figure 2와 같이 global average pooling은 output으로 마지막 convolutional 레이어의 각 unit(channel)의 feature map의 spatial average를 내뱉습니다.
  • 이 average 값들의 weighted sum은 최종 출력을 생성해내는데 사용됩니다.
  • 비슷하게, class activation map을 얻기 위해 마지막 convolutional 레이어의 feature map의 weighted sum를 계산합니다.

Global Average Pooling (GAP)을 fully connected layer를 대체하여 최종 output을 얻으려는 목적으로 쓰인다면,

 

마지막 convolutional layer의 channel 수를 class의 개수와 같게 설정해줍니다.

 

(batch, width, height, channel(class)) -> (batch, 1, 1, channel(class))

 

GAP는 각 채널을 기준으로 평균을 구하고, 이 각각의 값들이 class에 대응하는 값들로 되어, 가장 큰 값을 가지는 class로 예측을 합니다.

 


Class Activation Map

$f_k(x,y)$가 spatial location $(x, y)$에서 마지막 convolutional 레이어에서 $k$번째 activation를 나타냅니다.

 

$k$의 global average pooling 의 결과 $F^k$를 $\sum_{x,y} f_k(x,y) $ 로 나타낼 수 있습니다.

 

클래스 $c$에 대해서 softmax에 입력으로 주어지는 값, $S_c$ = $\sum_{k} w_k^c F_k $가 됩니다.

 

$w_k^c$가 $k$ 번째 채널과 class $c$에 대응하는 weight 입니다.

 

$w_k^c$s는 class $c$에 대해서 $F^k$의 importance를 가리킵니다.

 

최종적으로 class $c$에 대한 softmax의 output은, $P_c$로 $y = {exp(S_c) \over \sum_{c}exp(S_c)}$

 

여기서 bias term은 무시합니다. classification performance에 거의 또는 전혀 영향을 주지 않기 때문에 softmax의 input  bias을 0으로 명시적으로 설정

 

$F^k$ = $\sum_{x,y} f_k(x,y) $ 를 class score $S_c$로 plugging 하기 위해 아래와 같이 수식을 정의합니다.

여기서 class $c$에 대한 class activation map을 $M_c$와 같이 정의합니다.

이렇게 정의한 $M_c$를 통해 아래의 $S_c$를 얻어낼 수 있습니다.

$M_c(x,y)$는 $(x, y)$에 위치한 값이 c라는 class로 분류되는데 미치는 importance를 나타냅니다.

 

위 수식을 그림으로 표현한 것이 아래입니다.

출처 : Learning Deep Features for Discriminative Localization

간단히 정리하면....

 

수식을 보면 c라는 클래스를 분류하려고 할 때, feature map에다가 해당하는 class weight 값을 곱해줘서 값을 더 두드러지게 표현한다는 것을 볼 수 있습니다.

 

더 쉽게 말하면 위의 첫 번째 파란색 feature map을 global average pooling하면 파란색 원이 나오는데,

 

기존에 파란색 원에 weight를 곱해서 최종 연산을 진행했다고 하면, 파란색 원 말고, 파란색 feature map에 곱해줘보자 이 의미로 보시면 됩니다.

 

 

따라서 위에서 정의한 class activation map $M_c(x,y)$를 GAP의 input에서 좌표 $(x,y)$가 class $c$에 얼마나 영향을 주는지와 관련된 수치로 볼 수 있습니다.

 

그리고 class activation map의 결과는 $M_c(x,y)$로 이루어진 행렬을 원래 크기에 맞게 upscaling한 결과로 나타내어 집니다.

 

 


Grad-CAM

 

기존 CAM의 단점은 Global Average Pooling 레이어가 필요하다는 것입니다.

 

GAP가 없는 레이어는 마지막 convolutional layer 뒤에 GAP를 붙여서 fine-tuning 해야 한다는 문제와, 이로 인한 약간의 성능 감소를 동반한 문제가 있습니다. 또한 같은 이유로 마지막 layer에 대해서만 CAM 결과를 얻을 수 있습니다.

 

Grad-CAM은 Global Average Pooling 레이어에 의존하지 않는 아이디어 입니다.

 

이에 따라 자연스럽게 CAM의 문제가 해결 됩니다.

 

Convolutional Layer를 가진 어떤 모델이든 Grad-CAM을 적용할 수 있습니다.

 

Grad-CAM을 얻기 위해서는 관찰하려는 convolutional layer의 gradient와 그 layer를 통과한 output 정보가 필요합니다.

 

$y^c$를 softmax 거치기 전 output의 $c$번째 값, $A^k_{ij}$를 관찰하려는 layer를 통과한 output 좌표 $(i, j)$에 대응하는 값으로 정의

 

이 정보를 이용하여 neuron importance weights $\alpha_k^c$를 정의 가능하다.

 

 

최종적으로  $\alpha_k^c$ 와 $A^k_{ij}$를 이용하여 Grad-CAM을 정의할 수 있습니다.

마지막에 ReLU를 적용하는 이유는 관심있는 class에 대한 긍정적인 영향을 가진 features에만 관심을 두기 위해서 입니다.

 

만약 ReLu를 제거하면 localization에서 성능이 좋지 않다고 합니다.

 

 

 

 

참고

cnnlocalization.csail.mit.edu/Zhou_Learning_Deep_Features_CVPR_2016_paper.pdf

kangbk0120.github.io/articles/2018-02/cam

www.secmem.org/blog/2020/01/17/gradcam/

jsideas.net/grad_cam/