[CS231n] 14. Visualizing and Understanding (EECS 498-007 / 598-005)

SoyE·2023년 2월 18일
1


이번 강의는 컨볼루션 신경망 내부에서 일어나는 일을 시각화하고 이해하기 위한 기술에 대해 이야기 할 것입니다.

두 가지의 주제로 요약하면

  1. 우리가 훈련시킨 데이터에 대해 학습한 것이 무엇인지 이해하는 기술
  2. neural net을 Visualizing 하고 Understanding하는데 사용되는 많은 테크닉들이 deep dream, style transfer에 사용될수 있다는 것

신경망 내부를 들여다 보고 감각을 얻을 수 있다면 어떻게 될까요?

서로 다른 layer의 서로 다른 feature 각각이 찾고 있는 것이 무엇인지 또는 왜 동작하고 왜 동작하지 않는지에 대해 더 많은 직관을 얻을 수 있습니다.

서로 다른 아키텍처를 가진 모델의 첫 번째 레이어의 필터를 시각화 해보면 상당히 비슷합니다.

주로 edge 정보를 나타내고, 이는 포유류의 시각 시스템에서 가장자리를 찾는 세포가 이러한 필터와 다소 유사합니다.

다음 higher layer의 필터를 시각화해보면

위 그림처럼 두번째 세번째 layer만 보았을 때에도 channel과 dimension이 커지며 직관적으로 이해하기 힘들어집니다.

그렇기에 layer에서 무슨 일이 일어나고 있는지 알기 위한 다른 기술이 필요합니다.

신경망이 무엇을 하는지 이해하려고 하는 한 가지 방법은 중간 layer를 건너뛰고 마지막 fully-connected layer에서 일어나는 일을 이해하는 것입니다.

dataset을 학습시킨 AlexNet에서 1000개의 class score를 도출하기 직전 FC7-layer를 다양한 테크닉을 통해 시각화화여 살펴봄으로써 network가 무엇을 "represent" 하려하는지 이해해봅시다.

왼쪽 그림은 pixel space에서 nearest neighbors를 적용하면 픽셀 값은 유사하지만 동일한 class가 아닌 이미지를 포함하는 경우가 있습니다.

오른쪽 그림은 feature space에서 nearest neighbors를 적용한 결과입니다.

두 번째 행 코끼리 사진을 보면 머리가 다른 방향을 향하고 있으면 코끼리 이미지의 픽셀 값은 많이 다를 수 있지만 잘 분류된 것을 볼 수 있습니다.

이는 model에서 많은 low-level pixel 값을 무시하고 코끼리와 같은 정보를 인코딩 한다고 볼 수 있습니다.

이러한 feature space에서 적용해볼수있는 또 다른 방법으로는 몇몇의 차원 축소 알고리즘을 사용하는 것입니다.

이 이미지는 FC7-layer의 feature vector를 차원 축소 알고리즘을 사용하여 4096차원을 2차원으로 줄여 이차원 공간상에 나타낸 것입니다.

이 결과가 10개의 cluster로 나뉘는 모습을 통해 학습을 통한 model의 feature space가 일종의 identity of the class를 encoding 했다고 볼 수 있습니다.

위 그림은 ImageNet을 학습시킨 model의 feature space를 차원 축소해서 나타낸 결과입니다.
각 비슷한 클래스들끼리 cluster를 형성한 것을 볼 수 있습니다.

위 그림은 conv5 layer의 activation map을 각 gray scale로 시각화 한 것입니다.
초록색 박스로 나타낸 activation map을 보면 input image의 얼굴에 대해서 높은 activation 값을 갖는것으로 보여집니다.

이는 우리에게 서로 다른 필터가 응답할 수 있는 것이 무엇인지에 대한 직관을 줄 수 있습니다.

위 그림처럼 fix된 layer에서 fix된 channel의 가장 큰 activation을 갖는 부분을 모아 시각화 해보니 각 카테고리별로 해당 layer의 각각의 channel이 image에서 중요하게 생각하는 부분이 비슷하다는 것을 알 수 있습니다.

아래는 좀 더 깊은 layer에서 시각화한 것으로 한 neuron의 receptive field가 크기 때문에 좀 더 넓은 영역을 나타내고 있습니다.

또 다른 방법은 이미지의 어떤 pixel이 중요한지 알아보는 것입니다.
다시말해 이미지의 어떤 부분이 network가 분류를 위한 결정의 근거가 되는지 알아보는 것입니다.

특정 부분을 masking하면 score가 급격히 떨어지는 (붉은색) 부분을 heat map을 통해 살펴 볼 수 있고 이러한 부분들이 중요한 부분임을 나타낸다.

하지만 이것은 마스크를 이동하며 하나씩 다 계산해야 하기 때문에 계산 비용이 많이 듭니다.

그래서 역전파를 통해 계산할 수 있는 방법이 있습니다.

image의 class score값을 backprop시켜 어떤 pixel에서 activation이 있는지 살펴보는 것입니다.

여러 이미지에 적용한 결과입니다.

해당 예시는 단순히 이러한 테크닉이 있다라는 것만 소개하기 위함입니다.
실제 다른 이미지에서 진행해보면 위와 같은 의미있는 결과를 보이지 않는다고 합니다.

위 아이디어가 실제로 잘 작동한다고 가정하면 unsupervised로 이미지의 객체를 분리할 수 있다고 생각할 수 있습니다.

네트워크의 이 중간 부분의 기능이 무엇인지 알기 위해
중간의 feature 값을 backprop시켜 image의 어떤 부분이 class score가 아닌 선택한 neuron에 영향을 주는지를 살펴보는 것입니다.

이때 backpro과정에서 일반적인 backprop을 수행하는 것이 아니라 조금 다른 과정을 거치게 됩니다.

위 그림처럼 forward pass과정에서 ReLU를 거치면 음수 값 들이 zero가 되기 때문에 backprop에서도 negative upstream gradient를 죽여 zero로 만듭니다.
(upstream gradient에 forward pass와 같은 masking을 하겠다는 것)

이러한 과정을 통해 깔끔한 visualize가 된다고 합니다.

오른쪽 사진은 왼쪽 패치의 어떤 픽셀이 실제 뉴런 값에 영향을 미치는지를 보여줍니다.

더 깊은 layer에 대해서도 마찬가지입니다.

이러한 방법은 input image의 patch의 제한된 부분이 (or pixel이) 특정 neuron에 얼마나 영향을 미치는가를 나타낼 뿐입니다.

그렇다면 전체 image에서 어떤 image가 해당 neuron을 최대로 활성화 시키는지를 알수있는 방법은 무엇일까요?

그 방법은 특정 neuron이 최대 값을 갖게하는 새로운 image를 생성하는 것입니다.

위 수식에서

  • I*는 생성되는 이미지이고
  • f(I)는 우리가 선택한 neuron의 value이고
  • R(I)는 일종의 정규화로 이미지를 좀 더 자연스럽게 만들어줍니다.

이러한 Gradient Ascent는 가중치를 훈련하는 것이 아니라 선택한 neuron이 최대 값을 갖게 하는 이미지를 학습하는 것입니다.

Gradient Ascent의 절차에 대해 보면

  1. 이미지를 zero값으로 (또는 random noise) 초기화하고
  2. 이미지를 forward 시킨다.
  3. 이미지의 픽셀에 대한 neuron의 gradient를 얻기 위해 backprop하고
  4. neuron의 activation값을 최대화 시키게끔 픽셀을 update한다.
(neuron 대신 score 선택 가능)

L2 norm만을 사용해서 정규화를 진행하면 결과가 natural 해보이지 않습니다.

그래서 정규화를 변형하여 이용해 보면 다음과 같습니다.

  1. l2 norm 에다가 주기적으로 Gaussian blur를 적용합니다.
  2. 작은 값을 갖는 pixel을 0으로 cliping합니다.
  3. 작은 값을 갖는 gradient에도 마찬가지입니다.

전 그림처럼 socre에 대해 gradient ascent를 하는 것이 아닌
특정 layer의 neuron에 대해 최대 값을 갖기 위한 gradient ascent를 해주면 위 그림과 같습니다.

위 사진들은 여러 논문에서 GAN을 기반으로 하여 좀 더 realistic한 이미지를 생성해내는 것을 볼 수 있습니다.

Adversarial image를 생성하는 방법을 보면

  1. 임의의 사진으로부터 시작
  2. 임의의 카테고리 선택
  3. 선택한 카테고리의 점수를 최대화 하도록 이미지 수정(gradient ascent를 통해)
  4. 네트워크가 속을 때까지 진행

이러한 기법을 통해 위 그림과같이 코끼리를 코알라로 자신있게 분류 하게끔 네트워크를 속일 수 있는데 이때 pixel을 아주 약간 변형했기 때문에 차이가 거의 없습니다.

또한 gradient ascent를 통해 Feature Inversion을 할 수 있습니다.

Feature Inversion은 주어진 Image의 feature vector와 새로운 image의 feature vector간의 차이를 줄이는 것입니다.
이때 두 feature vector는 동일한 layer의 feature끼리 연산합니다.

그리고 이 정규화는 공간상의 매끄러움을 권장하기 위해 사용된다고 합니다.

위 사진을 보면어떤 종류의 정보가 신경망의 layer에서 보존되고 버려지는지 알 수 있고
더 깊은 레이어로 갈수록 색상 및 텍스처 정보가 손실되는 것을 확인할 수 있습니다.

DeepDream은 이미지의 특정 feature를 주어진 activation값과 같게 만들어 주는 것입니다.

  1. forward: 선택한 layer에서 활성화 값을 계산합니다.
  2. 선택한 layer의 기울기를 활성화와 동일하게 설정합니다. (이 활성화 값은 우리가 선택할 수        있음 ex) 낮은 층의 활성화 값 or 높은 층의 활성화 값)
  3. backward: 이미지의 gradient 계산
  4. 이미지 update

잘 이해가 안 될수도 있어서 예시를 통해 설명하겠습니다.

하늘 이미지를 실제로 DeepDream network에 집어넣으면
하늘 이미지에서 한 layer를 선택해서 다른 이미지의 낮은 layer에서 활성화 값을 가져와 하늘 이미지의 선택한 layer의 활성화 값을 다른 이미지의 낮은 layer의 활성화 값과 비슷하게 만들어줍니다.

낮은 layer의 활성화 값을 사용했기 때문에 위와 같이 edge성분 같은 feature가 극대화 된 것을 볼 수 있습니다.

좀 더 높은 layer에서 활성화 값을 가져와 진행하면 좀 더 추상화된 feature가 표현된 것을 볼 수 있습니다.

위 사진도 마찬가지입니다.

이러한 deepdream을 많이 돌리면 원본 image에서 많이 벗어나 위와 같은 요상한 그림이 나타나게 됩니다.

다양한 유형의 장소 이미지에 대해 deepdream을 실행한 결과입니다.

Texture Synthesis는 규칙적인 texure를 가진 작은 input image로 동일한 texture구조를 갖는 큰 output image를 만드는 것입니다.

texture synthesis를 하기 위해 Nearest Neighbor algorithms을 활용합니다.
이미 생성된 픽셀로 이웃을 형성하고 입력에서 가장 가까운 이웃을 복사합니다.

위 사진도 texture가 단순하다면 neural net없이 Nearest Neighbor algorithms을 활용하여 texture synthesis을 진행한 결과입니다.

Gram Matrix는 neural net에서 텍스쳐 정보, 즉 스타일의 정보를 담고 있는 행렬입니다.
위 사진으로는 이해하기 어려워서 Gram Matrix를 구하는 다른 자료를 가져왔습니다.

Gram Matrix는 한 layer에서 feature map간의 내적을 통해 구합니다.
예를 들어 G1,2의 값은 feature1과 feature2를 내적한 값입니다.
내적을 하는 과정에서 feature map들이 flatten되기 때문에 공간 구조는 사라지고 texture정보 즉 style정보만 남게 된다고 해석할 수 있습니다.

Neural Texture Synthesis를 하는 과정을 설명하면

  1. VGG와 같은 pre-trained CNN model을 사용합니다.
  2. Target texture image를 forwarding시켜 매 layer에서 feature map을 저장합니다.
  3. 기록한 feature map들을 가지고 gram matrix를 계산합니다.
  4. 생성할 image를 random noise로 초기화 시키고
  5. 이 nosie 이미지를 동일한 network에 forwarding시켜 마찬가지로 매 layer에서 Gram
      matrix를 계산합니다.
  6. 같은 layer의 target image와 noise image의 Gram matix간의 L2 distance를 weighted
      sum해주어 loss를 구해줍니다.
  7. 계산된 loss를 backprop시켜 pixel별 gradient를 계산하고 noise image를 update시켜줍니다.

즉 noise image의 Gram matix를 target image의 Gram matix에 맞춤으로써 target이미지의 style을 따라가는 과정이라고 해석할 수 있습니다.

위 그림은 더 높은 layer에서 input texture의 큰 feature(texture)들을 잘 구성하는 것을 볼 수 있습니다.

이제 우리는 texture synthesis와 앞서 본 feature reconstruction을 결합하려고 합니다.

위 그림처럼 content image의 feature와 style image의 Gram matrix를 matching시켜 새로운 이미지를 생성할 수 있습니다.

이를 Style Transfer라고 합니다.

위 그림에서 Content Image는 네트워크에게 output 이미지가 어떻게 생겨야하는지를 말해주고 (ex 집의 모양이나 위치) Style Image는 output 이미지의 텍스쳐가 어때야하는지를 말해줍니다.

이때 style loss와 content loss 두가지 loss를 동시에 낮추면서 이미지를 update합니다.

위 사진은 style transfer의 진행 상황을 보여줍니다.

다양한 style정보로 style transfer를 진행한 결과입니다.

여기에는 trade-off가 존재하는데 content loss에 더 많은 가중치를 둘수록 왼쪽 그림과 같고 style loss에 더 많은 가중치를 두면 content 정보는 거의 사라진채 style 정보가 많이 남은 것을 볼 수 있습니다.

그리고 style image를 어떻게 resize하냐에 따라 위와 같이 조금 다른 특징의 스타일을 전송하는 것을 볼 수 있습니다.

이렇게 여러 개의 style을 mix하여 style transfer를 진행할 수 있습니다.

스탠퍼드 대학 사진에 별이 빛나는 밤의 스타일을 전송한 것이고

이 사진은 style transfer와 deep dream을 동시에 실행한 것입니다.

하지만 문제가 있는데 위와 같은 style transfer 방식은 매우 느리다는 것입니다.
그래서 style transfer를 수행하기 위해 VGG가 아닌 다른 neural network를 제시합니다.

feed forward방식으로 훈련할 땐 다소 시간이 좀 걸릴 수 있지만 훈련된 후에는 이 feed forward network를 분리하고 사용할 수 있으며 single forward에서 이미지를 스타일화 할 수 있다고 합니다.

이 fast style transfer는 스마트폰을 통해 실시간으로 적용될 수 있을 만큼 빠릅니다.

인스턴스 정규화 중 하나는 실제로 style transfer를 위해 개발되었기 때문에

이렇게 고품질 결과를 얻기 위해 인스턴스 정규화를 사용합니다.

여기서 단점이 있는데, fast style transfer algorithm은 각각의 다른 스타일에 대해 하나의 네트워크만 훈련합니다.
그래서 여러 스타일을 적용시키려면 시간이 다소 오래 걸릴 수 있습니다.

그래서 사람들은 conditional instance 정규화를 사용하여 다양한 style을 적용할 수 있을 뿐만 아니라 style을 혼합할 수 있습니다.

이번 내용을 요약하면
신경망 내부에서 일어나는 일을 시각화하고 이해하기 위한 기술에 대해 배웠습니다.
그리고 이 기술이 몇 가지 재밌는 이미지를 생성하는데 어떻게 사용되는 지 확인했습니다.

reference
강의 자료

profile
응애

0개의 댓글