[EECS 498-007 / 598-005] 강의정리 - 14강(CS231n 12강) Visualizing and Understanding

ONground·2022년 4월 22일
1
post-thumbnail
post-custom-banner

Visualizing and Understanding

  1. Neural Network가 training data를 어떻게 학습하고 무엇을 배우는가
  2. Visualizing and Understanding의 기술들을 재미있는 application에 적용

  1. What's going on inside Convolutional Networks?
    1.1) First Layer: Visualize Filters
    1.2) Higher Layers: Visualize Filters
    1.3) Last Layer
    1.4) Visualizing Activations
    1.5) Maximally Activating Patches
    1.6) Which Pixels Matter? Saliency via Occlusion
    1.7) Which Pixels Matter? Saliency via Backprop
    1.8) Intermediate Features via (guided) backprop
  2. Gradient Ascent
    2.1) 방법
    2.2) 더 좋은 visualization
    2.3) Adversarial Examples
  3. Feature Inversion
  4. DeepDream
  5. Texture Synthesis
    5.1) Nearest Neighbor
    5.2) Gram Matrix: Texture Synthesis with Neural Networks
  6. Neural Style Transfer
    6.1) 설명
    6.2) Neural Style Transfer 조정
    6.3) Fast Style Transfer
    6.4) One network, Many Styles

Summary


1. What's going on inside Convolutional Networks?

네트워크 내부에서는 과연 어떤 것을 학습할까?

1.1) First Layer: Visualize Filters

Conv Net의 매우 첫번재 layer에서는 다른 color들과 여러 종류의 edges를 찾는다.

1.2) Higher Layers: Visualize Filters

2번째, 3번째 conv layer을 visualize하면 더이상 blobs나 edges를 잘 보기 힘들다. 그래서 어떤 것을 보고 있는지 정확히 알기 힘들다.

1.3) Last Layer

실질적으로 conv layers가 어떤 일을 하는지 보려면 중간 layers를 건너뛰고 last fc layer을 살펴봐야한다.1000개의 class scores를 계산하기 전 4096차원의 feature vector을 시각화해보려고 한다.

a. Nearest Neighbors

4096 dim feature vector에 Nearest Neighbors를 적용하였다.

왼쪽 그림은 학습 전에 픽셀 공간에서 Nearest Neighbors를 적용한 것으로 비슷한 이미지들을 묶을 수 있다. 하지만 개의 이미지를 넣었음에도 그저 흰색 덩어리가 있는 다른 이미지들을 가져오기도 한다.

오른쪽 그림은 학습 후에 픽셀 공간이 아니라 CNN에서 나온 4096-dim feature vectors에서 NN을 계산한다. 이를 보면 픽셀 공간에서의 NN과 다르게 픽셀 값의 차이가 커도 feature이 비슷하면 비슷한 이미지로 계산한다. 코끼리를 보면 머리의 방향이 달라 픽셀 값의 차이가 매우 다름에도 같은 코끼리로 학습하여 비슷한 feature을 갖는다.

즉 네트워크가 학습을 통해 이미지의 semantic content features을 잘 포착한 것이다.


NN이 어떻게 계산되는가?

  • 이미지를 네트워크에 통과시킨다.
  • 각 이미지들에 해당하는 4096-dim feature vectors를 전부 다 저장해 놓는다.
  • 저장된 vectors를 가지고 NN을 계산한다.

b. Dimensionality Reduction

4096-dim을 2-dim으로 축소하여 보기 쉽게 visualize한다. t-SNE을 통해 차원축소를 한 예시이다.

https://cs.stanford.edu/people/karpathy/cnnembed/
이곳에서 feature space를 확인해볼 수 있다. 서로 다른 sementic categories에 대응하는 이미지들을 확인할 수 있고, 각 class들이 cluster을 이루고 있다.

1.4) Visualizing Activations

중간 layers의 가중치들은 시각화하더라도 어떤의미를 갖는지 확인하기 어렵다. 따라서 중간 layers의 가중치가 아니라 Activation map을 시각화 해보면 일부 해석할 수 있는 것들을 볼 수 있다.AlexNet의 예시를 보면 conv5의 feature map은 128x13x13의 tensor이며 이는 128개의 13x13 2-dim grid로 볼 수 있다. 이를 그레이스케일 이미지로 시각화해보면 conv layer가 입력에서 어떤 features를 찾고 있는지를 짐작해볼 수 있다.

초록색 박스의 feature map을 보면 사람의 얼굴에 활성화되는 것 같아 보인다. 즉 분명 어떤 layer에서는 사람의 얼굴을 찾고 있다는 것이다.

대부분의 filter 값들이 검은색인 이유는 ReLU를 거쳤기 때문이다.

1.5) Maximally Activating Patches

어떤 이미지가 들어와야 각 뉴런들의 활성이 최대화되는지를 시각화해보는 방법이다.conv5를 통과한 후 나온 128x13x13의 activation map중에서 17번째 channel을 보기로 하였다. 많은 이미지를 CNN에 통과시키고 선택한 channel을 max activate시킨 이미지 패치를 visualize한 결과는 오른쪽 그림과 같다.

각 행에 있는 패치들은 하나의 뉴런에서 나온 것이다. 이 패치들은 해당 뉴런의 활성을 최대화시킨 패치들이다. 이들 특징을 통해 해당 뉴런이 무엇을 찾고 있는지 짐작할 수 있다.


용어의 정리

여기에서 한 뉴런은 conv5 activation map의 하나의 scalar값이다. conv5는 conv layer이므로 한 channel안의 모든 뉴런들은 모두 같은 가중치를 공유한다. 각 channel 당 하나의 conv filter이 있고, 이에 상응하는 많은 뉴런들(activation map)이 있다.


위 그림에서 아래의 그림은 같은 네트워크의 더 깊은 layer에서 뉴런들을 최대로 활성화시키는 패치들이다. 더 깊은 layer에서 왔으므로 receptive field가 훨씬 더 넓다. 즉, 입력으로부터 훨씬 더 큰 패치들을 기준으로 찾는다.

1.6) Which Pixels Matter? Saliency via Occlusion

이 실험에서 알고자 하는 것은 입력의 어떤 부분이 분류를 결정짓는 근거가 되는지에 관한 실험이다.

위 예시에서는 코끼리를 입력으로 받고 이미지의 일부를 가린다. 그리고 가린 부분을 데이터셋의 평균 값으로 채워버린다. 이를 네트워크에 통과시키고 네트워크가 이 이미지를 예측한 확률을 기록한다. 그리고 이 occluded patch를 전체 이미지에 대해 sliding하여 반복한다.

만약 이미지의 일부를 가렸는데 네트워크 스코어의 변화가 크게 발생한다면 가려진 그 부분이 분류를 결정짓는데 아주 중요한 부분이라는 것이다.

예시를 자세히 보자. 가장 아래 예시를 보면 빨간색 지역은 확률값이 낮음을 의미한다. 앞쪽의 카트부분을 가렸을 때 확률이 매우 감소함을 볼 수 있다. 즉, 네트워크가 이 부분을 많이 고려한다는 사실이다.

1.7) Which Pixels Matter? Saliency via Backprop

Simonyan, Vedaldi, and Zisserman, “Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps”, ICLR Workshop 2014.

개를 입력으로 넣었을 때 네트워크는 이를 개라고 예측할 것이다. 이 때 우리는 네트워크가 픽셀들을 보고서 이미지를 개라고 분류했는지를 알고싶다.

이 방법은 입력 이미지의 각 픽셀들에 대해서 예측한 클래스 스코어의 gradient를 계산하는 방법이다. 어떤 픽실에 영향력있는지를 알 수 있다. 어떤 픽셀이 개를 분류하는데 있어서 중요한지 알 수 있다. 그림 아래의 Saliency map을 보면 개의 윤곽이 보인다.다른 이미지들의 saliency map을 보면 위와 같다.

Saliency Maps: Segmentation without Supervision

위의 saliency map을 가지고 segmentation 레이블 없이 semantic segmentation을 수행할 수 있다.이들은 Grabcut Segmentation Algorithm을 사용한다. Grabcut은 interactive segmentation algorithm이라고 한다.. 이는 자세히 설명하지 않았다.

Saliency mapgrabcut을 잘 조합하여 이미지 내에서 객체럴 segmentation할 수 있다. 그러나 supervision이 있을때에 비해 매우 안 좋은 성능을 낸다고 한다.

1.8) Intermediate Features via (guided) backprop

이번에는 어떤 이미지가 있을 때 클래스 스코어가 아니라 네트워크의 중간 뉴런을 하나 고른다. 그리고 입력 이미지의 어떤 부분이 내가 선택한 중간 뉴런의 값에 영향을 주는지 찾는 것이다.

이 경우에는 이미지의 각 픽셀에 대한 클래스스코어의 gradient를 계산하는 것이 아니라 입력 이미지의 각 픽셀에 대한 네트워크 중간뉴런의 gradient를 계산한다. 이를 통해 어떤 픽셀이 해당 뉴런에 영향을 주는지 알 수 있다.오른쪽의 guided backprop(ReLU의 gradient부호가 양수면 그대로 통과, 음수이면 backprop하지 않음)을 통해 더 좋은 이미지를 얻을 수 있다고 한다.guided backprop을 통해서 어떤 픽셀들이 뉴런들에 영향을 미치고 있는지 확인할 수 있다. 이 방법은 중간 layer가 무엇을 찾고 있는지 이해하기 위한 영상을 합성하는데 아주 유용하다.

그런데.. 이들 방법들은 모두 고정된 입력 이미지의 어떤 부분이 어떻게 영향을 미치는지밖에 말해주지 않는다. 입력 이미지에 의존하지 않는 방법은 없을까?


2. Gradient Ascent

해당 뉴런을 활성화시킬 수 있는 일반적인입력 이미지가 있을까?

우리는 loss의 최소화를 위해 gradient descent를 사용한다. 그러나 gradient ascent에서는 네트워크 가중치를 전부 고정시키고 gradient ascent를 통해 중간 뉴런 혹은 클래스 스코어를 최대화시키는 이미지의 픽셀들을 만들어낸다. 즉 가중치를 최적화하는 것이 아니라 뉴런 또는 클래스 스코어가 최대화될 수 있도록 입력 이미지의 픽셀값을 바꿔주는 방법이다.이때 regularization term이 필요한데 생성된 이미지가 특정 네트워크의 특성에 과적합되는 것을 방지하기 위함이다. 이를 통해,

  1. 이미지가 특정 뉴런의 값을 최대화시키는 방향으로 생성되길 원한다.
  2. 이미지가 자연스러워보여야 한다.(regularization term의 역할)
  • II^* : 선택한 뉴런이 최대로 활성화되게 하는 이미지
  • f(I)f(I) : 선택한 뉴런의 value(값)
  • R(I)R(I) : regularization term

2.1) 방법

gradient ascent를 위해 초기 이미지가 필요한데 이는 zeros, uniform, noise등으로 초기화한다.

그리고 이를 네트워크에 통과시키고 우리가 선택한 뉴런의 스코어를 계산한다. 그리고 이미지의 각 픽셀에 대한 해당 뉴런 스코어의 gradient를 계산하여 back prop을 한다.스코어를 최대화시키기 위해 이미지 픽셀 자체를 업데이트한다.L2 norm의 regularize를 진행한 예시이다. 각 클래스의 특징을 나타내는 모양이 있음을 확인할 수 있다.위의 두 사진은 더 좋은 regularizer을 적용한 결과이다. 똑같이 L2 norm을 정용했지만 이미지에 주기적으로 Gaussian blur을 적용하고 값이 작은 픽셀들을 0으로 만들었다. gradient가 작은 값들도 0으로 만든다.

위와 같이 최종 스코어를 최대화시키는 것이 아니라 중간 뉴련을 최대화시키는 이미지를 생성해보면 아래와 같다.

2.2) 더 좋은 visualization

입력 이미지의 픽셀을 곧장 최적화하기보다 FC6을 최적화하는 것을 기본 아이디어로 하여 발전시켰다고 한다. 이미지 생성 문제에서 prior을 추가하면 아래와 같이 매우 현실적인 이미지를 만들 수 있다.

2.3) Adversarial Examples

네트워크를 속이기 위한 이미지를 만들어낸다.

  1. 임의의 이미지를 고른다.
  2. 어떤 클래스로 속일지 클래스를 고른다.
  3. gradient ascent를 통해 선택한 다른 클래스의 스코어를 최대화시키도록 고른 이미지를 변형시킨다.
  4. 네트워크가 속을때까지 반복한다.

거의 변함없는 두 이미지이지만 코끼리를 코알라로, 범선을 아이팟으로 잘못 분류하고 있는 것을 볼 수 있다. 이들은 그저 아주 조금의 픽셀이 변형되었을 뿐이다.


3. Feature Inversion

네트워크의 다양한 layer에서 이미지의 어떤 요소들을 포착하고 있는지를 짐작할 수 있게 해준다.

  • 어떤 이미지를 네트워크에 통과시킨다.
  • 네트워크를 통과시킨 activation map(features)를 저장해둔다.
  • activation map만을 가지고 이미지를 재구성한다.

이를 통해서 이미지의 어떤 정보가 feature vector에서 포착되는지 짐작할 수 있다. 이 방법 또한 regularization을 추가한 gradient ascent를 이용한다. 스코어를 최대화시키는 것 대신, feature vector간의 거리를 최소화시키는 방법을 이용한다.

기존에 계산한 feature vector Φ0\Phi_0와,
새롭게 생성한 이미지로 계산한 feature vector Φ(x)\Phi(\mathbf x)
간의 거리를 측정한다.


과제에서도 나오겠지만, 사람들이 자주 사용하는 regularizertotal variation RVβ(x)\mathcal R_{V^\beta}(\mathbf x)이 있다.

RVβ(x)=i,j((xi,j+1xij)2+(xi+1,jxij)2)β2\displaystyle\mathcal R_{V^\beta}(\mathbf x)=\sum_{i,j}\left((x_{i,j+1}-x_{ij})^2+(x_{i+1,j}-x_{ij})^2\right)^{\beta \over 2}

상하좌우 인접 픽셀 간의 차이에 대한 패널티를 부여한다. 이를 통해 생성된 이미지가 자연스럽게 되도록 한다.


Feature Inversion을 통한 시각화 예시를 보자.왼쪽 이미지는 원본 이미지이다.

  • 이미지를 VGG-16에 통과시킨다.
  • feature map을 기록하고 이 feature map과 부합하도록 하는 새로운 이미지를 합성한다.

다양한 layer에서 나온 activation map(feature map)을 가지고 합성한 이미지들을 보고 어떤 정보들을 저장하고 있는지 짐작해볼 수 있다.

relu2_2를 거쳐 나온 feature vectors를 가지고 이미지를 재구성해보면 원본과 거의 동일하다. 이를 통해 relu2_2에서는 이미지 정보를 많이 날리지 않는다는 것을 알 수 있다.

그러나 깊은 layer에서 살펴보면 네트워크가 깊어질수록 픽셀 값이 정확히 얼마인지와 같은 low-level 정보들은 사라지고 대신 색이나 텍스쳐와 같은 미세한 변화에 더 강력한 의미론적 정보들을 유지하는 것처럼 보인다.


4. DeepDream

DeepDream의 목적은 재미있는 이미지를 만드는 것이다. 또한, 모델이 이미지의 어떤 특징을 찾고 있는지를 짐작할 수도 있다.DeepDream에서는 입력 이미지를 CNN의 중간 layer를 어느정도 통과시킨다.

  1. 이미지를 CNN의 특정 layer까지 통과시켜 feature을 계산한다.\
  2. 해당 layer의 gradient를 activation값으로 설정한다. (?이 부분 직관적으로 안 와닿음)
  3. 설정된 gradient를 backprop하여 이미지를 업데이트한다.

이를 반복하여 네트워크에 의해 검출된 이미지의 features를 증폭시킨다. 해당 layer에 어떤 특징들이 있든지 그 특징들을 gradient로 설정하면 이는 네트워크가 이미지에서 이미 뽑아낸 특징들을 더욱 증폭시키는 역할을 한다.

특정 feature의 activation이 훨씬 커지도록 이미지를 변형한다.

그리고 이는 해당 layer에서 나온 특징들의 L2norm을 최대화시키는 것으로 볼 수 있다.위 이미지는 초기 layer의 feature을 증폭시킨 것으로 edges등이 나타난다.higher layer의 features이다.위 그림은 multi-scale 프로세싱을 수행하여 오래 돌린 결과이다. 작은 이미지로 DeepDream을 수행하고 점점 이미지 크기를 늘린다.다른 데이터셋으로 학습시키면 위와 같은 결과도 얻을 수 있다.


5. Texture Synthesis

텍스쳐 합성은 어떤 작은 텍스쳐 패치가 있을 때, 이를 갖고 같은 텍스쳐를 갖는 더 큰 이미지를 생성하는 task이다.

5.1) Nearest Neighbor

이 방법은 신경망 대신에 scan line을 따라 한 픽셀씩 이미지를 생성하는 방법이다.

  • 현재 생성해야 할 픽셀 주변의 이미 생성된 픽셀들을 살펴본다.
  • 입력 패치에서 가장 가까운 픽셀을 계산하여 입력 패치로부터 한 픽셀을 복사해 넣는다.

그러나 이러한 복붙방식의 고전방식은 아래와 같이 복잡한 텍스쳐에서 잘 동작하지 않는다.

5.2) Gram Matrix: Texture Synthesis with Neural Networks

텍스쳐 합성에 신경망을 도입한 방법이다.이미지를 네트워크에 통과시키고 특정 layer에서 feature map을 가져온다.

위 그림에서처럼 HxW의 한 점에 있는 C차원 feature vector은 해당 지점에 존재하는 이미지의 특징을 담고있다고 할 수 있다.

우선 feature map에서 서로 다른 두개의 feature vector(red, blue)를 뽑는다. 그리고 이 둘의 외적을 계산하여 CxC행렬을 만든다. 이 CxC행렬은 이미지 내 서로 다른 두 지점에 있는 특징들 간의 co-occurrence를 담고 있다. CxC행렬의 (i,j)번째 요소의 값이 크다면 두 입력 벡터의 i번째, j번째 요소가 모두 크다는 의미이다.

이를 통해 서로 다른 공간에서 동시에 활성화되는 특징이 무엇인지 어느정도 포착할 수 있다.위 과정을 HxW그리드에서 전부 수행하고 결과에 대한 평균을 계산하면 CxC Gram matrix를 얻을 수 있다. 그리고 이 결과를 입력 이미지의 텍스쳐를 설명하는 텍스쳐 기술자(discripter)로 사용한다.


흥미로운 점

Gram matrix는 이미지의 각 지점에 해당하는 값들을 평균화시켰기 때문에 공간 정보를 모두 날린다. 대신 특징들 간의 co-occurrence만을 포착한다.


이렇게 텍스쳐 기술자를 만들었으니 이제 이미지를 생성할 차례이다.gradient ascent와 유사한 과정을 거친다. 입력 이미지의 gram matrix를 재구성하도록 한다.

  1. VGG-19 pretrained model을 다운받는다.
  2. 이미지를 VGG에 통과시키고 다양한 layer에서 gram matrix를 계산한다.
  3. 생성해야 할 이미지를 랜덤 noise로 초기화시킨다.(=생성된 이미지) 이 이후는 gradient ascent와 유사하다.
  4. 이 랜덤 noise로 초기화된 이미지(=생성된 이미지)를 다시 VGG에 통과시키고 여러 layer에서 gram matrix를 계산한다.
  5. 원본 이미지와 생성된 이미지의 gram matrix간의 차이를 L2 norm을 이용해 Loss로 계산한다.
    여러 layer에서 gram matrix 차이를 계산하고 weighted sum을 계산하여 최종 Loss를 구한다.
  6. Loss를 backprop하여 생성된 이미지의 픽셀의 gradient를 계산한다.
  7. gradient ascent를 통해 이미지 픽셀을 조금씩 업데이트한다.
  8. 4번부터 반복한다.

위와 같은 결과를 볼 수 있다.


6. Neural Style Transfer

Neural Style Transfer: Feature + Gram Reconstructiontexture synthesisfeature inversion을 조합하면 흥미로운 결과를 낼 수 있다.

6.1) 설명

Style Transfer은 두가지 입력을 받는다.

  1. Content Image : 네트워크에게 우리의 최종 이미지가 어떻게 "생겼으면 좋겠는지"를 알려준다.
  2. Style Image : 최종 이미지의 "텍스쳐가 어땠으면 좋겠는지"를 알려준다.

최종 이미지는 content image의 feature reconstruction(feature inversion) loss도 최소화하고,
style image의 gram matrix loss도 최소화하는 방식으로 최적화하여 이미지를 생성한다.

  • 네트워크에 content/style 이미지를 통과시키고 feature map과 gram matrix를 계산한다.
  • 최종 출력 이미지는 랜덤 노이즈로 초기화시킨다.
  • forward/backward를 반복하여 계산하고 gradient ascent를 이용하여 이미지를 업데이트한다.

수백번 정도 반복하면 아래와 같은 output image를 얻을 수 있다.

6.2) Neural Style Transfer 조정

Neural Style Transfer은 DeepDream에 비해 더 많이, 정밀한 조정을 할 수 있다.style/content loss간의 가중치를 조절하면 어디에 더 집중해서 이미지를 생성할지 조절할 수 있다.또한, gram matrix를 계산하기 전 style image를 resizing하여 넣어주면 style image로부터 재구성된 feature scale을 조절할 수 있다.여러 style images를 가지고도 생성할 수 있다.

6.3) Fast Style Transfer

style transfer은 VGG에서 많은 forward / backward pass가 일어나 매우 느리다.

따라서 style transfer을 위한 또 다른 네트워크를 학습시킨다.style image는 하나로 고정한다. 그리고 content image만을 받아서 결과를 출력할 수 있는 단일 네트워크를 학습시킨다.

그러나 이는 하나의 네트워크가 하나의 style만 생성할 수 있다.

6.4) One network, Many Styles

하나의 네트워크로 다양한 Style을 생성할 수 있다. 어떤 방법인지는 자세히 설명되지 않았다.


Summary

post-custom-banner

0개의 댓글