꺼내먹는지식 준
CNN Visualization 본문
CNN 기반 neural net: 학습 가능한 conv 와 non linear activation function 의 stack으로 이루어진 연산기
어떤 원리로 CNN 이 잘 동작하는걸까?

학습은 어떻게 이루어지고, 어떤 현상이 일어나는걸까?
학습이 잘 안되고, 성능이 잘 안나올때는 왜 안나오는지 알아보려면 어떻게 해야할까?
입력이 주어지면 출력이 나오는 blackbox 기계가 있다고 하자.
기계에 문제가 있으면 보통 원인을 파악하기 위해서 내부를 들여다 봐야 한다.
시각화 해서 내부를 들여다보자!
어떨때 잘되고 안되고, 어떻게 개선할지를 보는 방법!

2013 ZFNet
낮은 단계에서는 동그란 블록, 혹은 선을 찾는 필터들이 위치하는 것을 확인
높은 계층으로 갈 수록 의미 있는 high level 을 학습한다는 것을 찾았다.
이를 통해 눈으로 보면서 CNN을 tunning하여서 ImageNet 에서 1등
눈 확인이 잔기술이 아니다! 라는 것을 확인

AlexNet 첫번째 layer conv filter 는 11 X 11 3channel이기에 색상을 띄울 수 있다.
각종 영상 처리 필터와 같이 color, 각도, block detector 같은 기본적 operation이 학습된 것을 확인 가능
필터를 입혀서 얻은 activation map visualization 결과
필터 처리 결과가 한 채널로 나와서 흑백으로 나왔다. 각 필터의 특성마다 각도가 변하거나, 잔 detail이 잡히거나, 혹은 color 가 반영되거나 등의 결과를 볼 수 있다.
CNN 의 첫 layer가 어떤 것을 보고 있고 어떤 행동을 하고 있는지 이해할 수 있었다.
왜 두번째, 혹은 더 높은 계층의 layer 는 해석하지 않을까?
뒤 쪽 레이어의 filter 는 차원 수가 너무 높아서 간단하게 이미지로 visualization 할 수가 없다.
사람이 직관적으로 알아보기 힘들다. (3차원이 색인데 그 이상이다.)
즉, 더 높은 눈으로 봐봤자 못알아보고, 앞쪽 필터와 합성 되어서 더 추상적인 역할을 할 뿐이다.
전체적인 neural net을 해석하기 위해서는 이보다 더 복잡한 방법이 필요하다.

왼쪽으로 갈 수록 모델 이해, 오른쪽으로 갈 수록 데이터 결과를 분석

DB에 여러 데이터를 저장, query 데이터가 들어오면 query 영상과 유사한 이웃 영상을 DB내에서 검색을 한다.
그것과 유사한 영상 몇개를 거리에 따라 정렬한다.
이를 통해 여러 해석 여지를 준다.
의미론적으로 비슷한 컨셉들이 clustering 되어있는 것을 알 수 있다.
top 6 유사한 이미지를 출력한건데, 이를 통해 컨셉을 제대로 이해했구나를 확인할 수 있다.
두번째로는 query 가 들어왔을 때 simple 하게 pixel별 검색을 통해 영상검색도 가능하다.
이 경우 비슷한 영상을 찾을 수 없는 경우도 있다. (위치가 다른 곳에 있고, 다른 포즈의 강아지는 픽셀 비교를 통해 찾을 수 없다. )
nearest neighbor 검색을 했을 때 포즈와 위치가 다른 강아지를 찾았다.
즉, 학습된 feature 가 물체의 위치 변화에 굉장히 강인하게, 컨셉을 잘 학습했다는 것을 알 수 있다.
nearest neighbors 구체적 예시

오른쪽 그림과 같은 embedding feature vector가 있다고 할 때, 각각의 벡터에 해당하는 영상이 있다고 하자.
실제 구현에서는 미리 학습된 neural net 을 준비하고 제일 뒤 쪽에서 fc layer 에서 특징을 추출할 수 있도록 준비를 한다. 그리고 query 영상을 넣어주면 특징을 추출하고 추출한 특징은 특징위치 어딘가에 위치한다.

DB에서 뽑은 영상들은 feature space 어딘가에 다 위치한다. (당연히 feature는 영상과 연결이 되어있다.)
빨간 색 영상들은 mapping이 되어있지 않다. 뒤에 차차 설명이 된다.

다음과 같이 query image 의 특징을 추출해서 feature space에서 위치해주면 해당 위치와 가까운 영상들을 찾은 후 어떤 것인지 분석할 수 있다. (feature로 오리지날 데이터를 가져와서 보여줄 수 있다.)
검색 된 예제로 분석하는 방법은 전체적인 그림을 파악하기 어렵다.
embedding feature를 해석하는 두번째 방법을 보자.
backbone network 에서 특징을 추출하면 고차원 특징 벡터가 나오는데, 이게 너무 고차원이라 해석하기도, 상상하기도 어렵다.
우리의 익숙한 세상은 3차원이다보니 고차원 space 분포들을 저차원으로 차원축소하여 눈으로 보기 쉬운 분포를 확인해보자.
대표적 방법중 하나
t-SNE (t-distributed stochastic neighbor embedding)

MNIST의 고차원을 2 dimension으로 나타낸것
전반적으로 비슷한 클래스끼리 잘 분포되는 것을 알 수 있다.
이것으로 모델이 적당히 학습되어서 클래스끼리 구분을 잘 할 수 있다는 것을 알 수 있다.
좀 더 나아가서 3이라는 숫자가 8이라는 숫자와 5의 분포가 가깝다는 것을 알 수 있다.
이 과정을 통해 아 모델이 3,5,8의 경계를 햇갈려 하고 있구나를 알 수 있다.

layer 의 activation 을 분석함으로써 모델의 특성 파악하는 방법
alexnet 의 conv5 layer 의 138번째 channel의 activation 적당한 값으로 thresholding을 하고 overlay를 하니까

다음과 같은 사진을 볼 수 있었다. 138은 얼굴을 찾고, 53은 계단을 찾는다는 걸 보면서, 아 이 채널은 어떤 역할이 있구나 와 같은 해석을 할 수 있었다.
Convolution neural network는 중간중간 hidden unit들이 각각 간단한 얼굴 detection 손 detection 계단 detection 등을 다층으로 쌓아서 조합으로 물체를 인식하는 구나..! 와 같은 해석을 할 수 있다.
Layer activation - patch 뜯어서 사용하기
각 layer 의 채널에서 하는일을 판단하기 위해서, 그 채널 즉 히든 노드에서 가장 높은 값을 갖는 위치의 근방의 patch를 데이터별로 뜯는다.

(세로축은 서로 다른 hidden 노드 )그 결과, 아 이 히든노드는 강아지 눈, 혹은 이 히든 노드는 뭐 굴곡진거 등 이런걸 찾는 detector구나 하고 알 수 있다.
맨 하단은 글자 + 노란색을 찾아낸다.
이 방법은 중간 계층을 분석하는데 적합하다. (국부적이고 큰 그림이 아니기 때문에)
해당 방법 구현 과정
1) 분석하고자 하는 레이어를 하나 고르고 (여러 CNN layer 중 하나
ex. conv 5 의 256 채널 중 14 채널을 골랐다고 가정해보자.
2) 예제 데이터를 backbone 네트워크에 넣어서 각 레이어의 activation을 다 뽑는다.
그리고 그 뽑고 싶어했던 채널의 activation을 저장한다.

3) 그리고 저장한 해당 채널의 activation 값 중에서 가장 큰 값을 갖는 위치를 파악하고, 입력 도메인의 maximum값을 도출한 receptive field 를 계산한 다음에 receptive field 해당 하는 patch 를 때온다. 그 후 각 히든 노드 별로 나열을 하면, 히든 노드가 어디를 주의깊게 보나 알 수 있다.
Class visualization
예제 데이터를 사용하지 않고 분류 학습이 된 모델을 보자.
분류시 네트워크는 어떤 모습을 상상하고 있을까?

새 같은 경우에는 나무 등이 같이 나타나고 개는 사람의 모습까지 보인다.
이를 통해 보통 새는 나무들과 같이 관측된다고 생각을 할 수도 있고, 한편으로는 사람혹은 나무와 같이 나타나는 것이 학습 데이터가 bais 되었구나라고 판단을 할 수도 있다.
그렇다면 이 영상은 어떻게 추출할까?
간단한 계산으로는 불가능하고, 최적화를 통해 합성 영상을 찾아나가는 과정을 거친다.
모델을 학습할 때 back propagation 알고리즘을 통해서 gradient descent 로 목적 함수인 loss들을 최소화하는 과정을 거쳤었다.
마찬가지로 합성영상을 만들기 위해서는 loss를 만들어야 하고, 최적화를 통해 영상을 합성한다.
여기서 말하는 loss는 어떻게 디자인을 할까?

두개의 loss를 합성해서 사용하고, regularization term이 있다.
$I$ 는 입력 영상이다.
$f()$ CNN 모델 f를 거쳐서 특정 class 에 대한 score를 출력, 예를 들면 강아지 클래스에 대한 스코어 고 부분만 고려를 한다.
그 score 를 $I$ 를 변경해서 maximize해라.
여기서는 f CNN 출력 중에 딱 하는(관심가는 클래스)를 score 로 사용을 해서 목적함수로 랜덤한 영상을 넣어주면 클래스 score가 낮게 나온다. 그때 score 높히는 입력 영상 $I$ 를 찾아라가 첫번째 목적 함수
두번째는 Regularization term이다. score를 높히는 임의의 영상을 찾다보면 더 이상 영상이 아닌 애들도 찾게 된다. 영상은 0~ 255
혹은 normalize되면 0 ~ 1 사이 값으로 bound 된 형태로 표현을 하게 되는데, 그말은 최적화 과정을 거쳐서 나온 출력 I 가 너무 큰 값으로 나오면 해석 가능한 형태가 아닐 수 있다. 그러나 CNN 은 그 경우를 해당 클래스로 분류를 잘하면 문제가 된다. 그걸 막고, 우리가 알고 있는 이해할 수 있는 영상을 유도하기 위해서 간단한 loss인 regularization term 을 추가한다.


여기서는 간단하게 찾는 영상의 L2 norm 즉 각 픽셀의 $\sum_{x,y} {(I_{x,y})^2}$
-이므로 제곱의 합이 낮아져서 0 이 될수록 유리하다. 따라서 좀 작아져라 라고 넣어준 것이다.
작아져야 하는 정도를 람다로 컨트롤을 해준다.
이전에는 neural net 을 학습할 때 에러나 손실을 최소화 하는 방향으로 최적화를 했는데 여기서는 최대화를 한다.
graident descent 가 아니라 ascent라는 최적화 방법을 사용한다.
부호만 반대고 똑같다.
argmin(-f + lamda )
부호만 -로 바꿔주면 minimization 문제로 바뀌고, gradient descent 를 사용하면 된다.
https://gaussian37.github.io/dl-concept-regularization/
L1,L2 Regularization
gaussian37's blog
gaussian37.github.io
- Normalization : 데이터에 scale을 조정하는 작업
- Regularization : predict function에 복잡도를 조정하는 작업
위 굉장히 좋은 글, 다만 이해가 어려워서 시간날때 마다 여러번 봐보자. 결론은 overfitting을 막는다.
Regularization은 복잡한 함수보다 더 간단한 피팅 함수에 보상(reward)을 합니다. 예를 들어, RMS 에러가 x 인 단순 로그 함수가 오류가 x / 2 인 15 차 다항식보다 낫다고 말할 수 있습니다. 이러한 모델 단순화의 정도와 에러에 대한 트레이드 오프 조정은 모델 개발자에게 달려 있습니다.
gradient ascent 를 step by step 으로 살펴보자.
임의의 영상으로 분석하고자 하는 CNN 모델에 입력을 넣어준다. 그리고 관심 class score를 추출한다.
이 방법은 중간 단계를 분석한 것이 아니라 최종 적인 결론을 보고 CNN에 대한 해석을 내놓는 방법이다.


그후 backpropagation 을 쭉해서 입력까지 내려가서, 입력이 어떻게 변해야 target score가 높아지는지 찾고, 이에 따라 input image를 업데이트 한다. (gradeint를 더해준다.)
loss를 측정할 때 score값에 -를 붙혀서 내려가는 방향으로 만들어놓고 graident를 계산하면 이전에 neural net 을 학습할 때 사용했던 descent 알고리즘을 그대로 사용하면 된다.
그렇게 한번 입력을 업데이트 해주고, 업데이트 된 영상으로 부터 위 과정을 반복한다.

그 결과 다음과 같은 몽환적인 그림을 얻어낸다. 랜덤 노이즈나, gray scale 이나 .. 그러나 보통 입력으로 부터 적절하게 바뀐 영상이 나오게 된다. (gradient descent는 현재 영상에서부터 조금조금 씩 변화를 줌으로)
즉 초기 입력을 어떻게 설정하냐에 따라 다양한 결과를 얻어볼 수 있다. 이 neural net 을 하나의 class에 대해서 어떤 이미지를 상상하고 있는지는 여러번 이 관점을 거쳐서 다양한 영상을 만들어 놓고 패턴들을 쭉 늘여놓고 눈으로 관찰하며 분석해볼 수 있다.
즉 패턴을 볼 수 있다.
Model descision explanation
모델이 특정 입력을 보았을 때, 특정 입력을 어떤 각도로 바라보고 있는지 해석하는 방법들에 대해서 살펴보자.
Saliency test (영상에서 어떤 부분이 결정을 내리는 데 중요한 역할을 하는지 보는 기법)
Occulusion map


확률 값을 출력하는 neural net 모델
코끼리 영상을 입력으로 넣어주는데, A 라는 큰 patch 를 이용해서 occulusion으로 가려준다.
Occlusion patch로 가리고 모델에 넣는다. 그때 올바르게 대답할 확률을 산출
또다른 부분을 가려서 또 모델에 넣어준다.
이런 방법을 통해 어떤 위치를 patch 로 가리냐에 따라 score가 바뀌는 것을 관찰하여 쉽게 해석할 수 있는 맵으로 만든다.
이걸 보면 한눈에 물체 검출에 민감한 영역을 알 수 있다. 별거 아니라 생각했는데 heatmap 뽑아놓고 보니 엄청나다!
Backpropagation
gradient ascent를 이용해서 몽환적인 분석 이미지를 생성했다. 이번에는 랜덤 이미지가 아니라, 특정 이미지를 분류 해보고 최종 결론이 나온 class에 결정적으로 영향을 끼친 부분이 어딘지를 heat map 으로 나타내는 기법이다.

해당 영역들이 최종 score를 결정했다고 나타낼 수 있다.
위 방법 구현 방법은
1) 먼저 입력 영상을 넣어주고, 하나의 클래스 score를 얻는다.

2)그 후 Back propagation 을 입력도메인까지 쭉 한다. l
3) oss를 변경해주는 gradient를 얻고, 얻은 gradient에 절대 값 혹은 제곱을 통해 절대적인 크기를 구해서 해당 이미지 형태로 출력을 한다. 절대값 제곱은 graident 크기 자체가 중요한 정보로, 많이 바뀌어야 score변하므로 부호보다는 그 절대 적인 크기를 중요하게 생각해서 절대값이나 제곱을 취하고 magnitude를 구해서 visualization을 구한다.

위 방법을 반복해서 누적해서 사용해볼 수도 있다.
결국 이 방법은 input단에서 어떤 구간이 민감했는지 보는 것이고, 상단의 model이 어떤 이미지를 상상하는지 본 것인데, 해당 방법들이 굉장히 유사하다.
두 방법의 차이는 입력으로 의미없는 블랙 혹은 랜덤 이미지를 넣었는가와 data에 dependent 하게 넣는가 차이이다.
좀더 advance한 backpopagtion 기반 saliency
Rectified unit


Backward pass: forward 할 때 relu에 의해 0이 된 구간 기억해뒀다가 backward 시 해당 위치 0으로 마스크
deconvnet: 그냥 backward 할 때 음수 값 0으로 마스크 오른쪽 사진은 해당 수식
한발 더 나가서 더 이
상한 방법으로 두 방법을 and gate 취해보기


결과 guided backprop 이 가장 clear 한 결과를 보여준다. 두마스크를 모두 사용한 것이 forward 할 때 음수는 모두 0으로 cancel out 되었고, back ward 할 때도 gradient 를 통해서 더 강화하는 방법으로 activation 들을 고른 것이다. cancel
결론적으로 guided backprop 은 양 방향에서 검출에 도움이 되는 부분만 골라서 뽑은 것이다.
위 방법들은 경험적이지만, 효과적인 방법이 유도되었다고 이해하면 깔끔하다.
class activation map :CAM( 가장 유명하고 많이 사용되는 기법)

어떤 부분을 주로 참고했는지 부드러운 히트맵으로 표현
이 방법을 잘 사용하면 bounding box 까지 그려서 물체 탐지도 가능하다.
CAM 알고리즘은 neural net 의 일부를 좀 개조해야 한다.


마지막 conv feature map을 FC layer 를 바로 통과하지말고 GAP (global average pooling(근데 이거 원래 하지 않나))을 하고 FC layer 를 하나만 통과시켜서 최종적으로 classification 하도록 뒷부분 구조를 만들어야 한다.
그리고 이 구조에 대해서 이미지 classification 학습을 다시해야 한다
.
아까와 같은 heat map 을 얻기 위한 방법
먼저 위 구조로 학습 한 pretrain network로 부터 cam 을 유도한다.
먼저 하나의 class c에 대해서 score를 S 라 해보자.

$w_k^c \, F_k$: 마지막 layer 에 해당하는 weight 와 마지막의 gap(global average pooling) feature 즉 각각 공간축의 평균값을 내서 하나의 node로 만든 feature들의 linear combination으로 score가 만들어졌다. 각각의 feature vector 들의 element의 w 가 linear combination 으로 곱해져서 최종적으로 score를 만든다.
여기에서 channel 은 마지막 conv layer 의 channel수다.
gap feature를 잘 살펴보면 모든 pixel에 대해서 conv feature map 을 각 채널마다 평균을 취한 것이다.
모두 리니어한 관계라 순서를 조금 바꿔주고, 마지막 수식 부분을 우리는 cam이라 부른다.
결국 cam은 global average pooling을 적용하기 전이라 공간에 대한 정보가 남아있고, 이 부분을 영상처럼 생각해서 visualization 해주면 다음과 같은 결과가 나타난다.

다른 방법들에 비해서 압도적으로 좋은 성능, 그리고 명확하게 보여준다.
사실 어떤 정보의 물체 위치 공간적 정보를 주지 않았는데도 불구하고, 단순한 영상 인식기 합성으로 위치를 나타내는 신동이 탄생했다!
제 3의 테스크를 깨꿀로 얻었다!
좀 더 정교한 task를 좀 더 rough 한 task 로 간접해결하는걸 weakly supervised learning 이라고 한다.
CAM 적용 가능 제약이 마지막 레이어 구성이 GAP 과 FC layer 로 이루어져야만 한다.
즉, architecture 를 바꿔서 재 학습해야한다.

모델 구조가 바뀌다보니 튜닝 된 그런 파라미터도 좀 안맞을 수도 있고, 성능도 바뀌다보니 좀 떨어질 수 있다.
다행히도 resNet, GooGleNet 은 마지막이 GAP 그리고 FC layer 가 들어가있다.
CAM 사용에 용이한 구조다!
수정하지 않고도 바로 CAM 추출이 가능하다.
모든 architecture 가 이렇게 설계될 수는 없기에, 구조 변경 X 재학습 X, 미리 학습된 네트워크에서 CAM을 뽑는 기법이 바로
Grad CAM
CAM 과 거의 동일한 성능

interpretation하기도 좋고 쉽다.
pretrain된 네트워크를 변경하지 않아도 되기 때문에 꼭 영상 인식 task 에 제한되지 않아도 된다.

backbone 이 CNN 이기만 하면 사용할 수 있다. CAM 하고 비교를 해보면 Grad CAM은 CNN의 마지막 Conv feature map 을 weighted sum으로 합성을 하는 것인데, 결합 weight를 몰라서 그것만 어떻게 구할지 구하는 것이 방법론의 핵심이다.
gradient 를 backpropagation 해서 saliency 맵을 유도했던 방법을 응용해서 weight를 구해보자.
weight 표기 $\alpha$
이전에 saliency map 을 backpropagation으로 구할 때 입력단까지 backprop 을 했지만 이번에는 우리가 관심있는 activation map까지만 back prop을 한다.

현재 task에서 해석하고 싶은 결과인 y를 변화시키는 loss로부터 backprop gradient를 구하게 되고, 공간축으로 GAP 를 적용해서 각 채널의 gradient 성분의 크기를 구한다.
그리고 이 $\alpha$를 activation map 을 결합하기 위한 weight로 사용한다.
선형 결합을 통해 결합을 한다.
다만 relu를 사용해서 양수값만 사용하면 grad cam 을 사용할 수 있다.

뒷단에 classifier 가 붙던, RNN이 붙던 결과를 해석하는데 사용가능한 일반화 된 tool이다.
guided backpropagation의 saliency map + grad cam 결합하는 방법도 있다.
grad cam은 주로 rough 하고 smooth한 특성이 있고,
guided backprop 은 굉장히 sharp 하지만 클래스에 대한 구분성이 떨어져 전반적으로 다 response 가 나온다.
이걸 더 샤프하게 만들어서 이 두개를 곱한다. 이를 통해 sensitive하고 high frequency, 그리고 class 에 민감한 정보 를 합쳐서 뷴류의 택스쳐 맵만 알 수 있는 guided grad cam 으로 유도도 가능하다.
Scouter
최근에는 grad cam 이 더 개선되어서 특정 결과 값 산출 뿐만 아니라, 다른 건 왜 아닌지까지 해석할 수 있는 방법으로 확장이 되었다.
'AI > CV' 카테고리의 다른 글
| FC layer 를 1X1 Convolution 으로 바꾸기 (0) | 2022.03.12 |
|---|---|
| AutoGrad (0) | 2022.03.11 |
| Semantic segmentation (0) | 2022.03.10 |
| semantic segmentation, Detection (0) | 2022.02.08 |
| Convolution network model 소개 (ILSVRC 모델) (0) | 2022.02.08 |