딥러닝은 black box 모델이다. black box 모델이 어떻게 작용하는지 알고 싶기에 다양한 시각화 기법을 사용하여 내부가 어떻게 작용하는지 확인해본다.
먼저 ConvNet 안에 있는 내부 이미지가 어떻게 움직이는지 알고 싶다.
> 첫 번째 Layer는 이미지와 필터의 가중치를 내적 한 결과이다.
> 필터 값을 가장 활성화 시키는 입력(이미지)은 필터의 가중치 값과 동일한 경우, 입력(이미지)와 가중치를 내적 한 결과를 통해서 필터가 무엇을 찾고 있는지 확인 할 수 있다.
> 이미지와 필터를 내적 후, 시각화하는 기법은 Conv Layers의 중간에 적용하면 해석하기 어렵다. 처음 input 이미지와 직접적으로 연결되어 있지 않기 때문이다.
> 마지막 Conv-layer를 확인하는 것도 필터가 어떤 특징을 추줄 하는지 알아내는데 좋은 방법이다.
> 네트워크가 학습을 통해서 이미지의 semantic content한 특징들을 잘 포착한 것을 시각화를 통해 알 수 있다. (ex – 두 번째 줄, 코끼리의 위치가 달라도 잘 예측한 모습을 보이고 있다.)
> Image-Net Data를 이용해서 t-SNE 알고리즘을 시행하여 시각화하였다(4096-dim -> 2-dim). >비슷한 이미지들끼리 군집화 되어있다.
> 중간 Layer의 Activation map을 시각화 해보면 일부를 해석할 수 있다. (CNN모델이 얼굴을 찾고 있는 것을 알 수 있음)
> 각 뉴런은 전체의 이미지를 나타내는 것이 아니다. 사진 안에 있는 하나의 이미지를 나타냄
> 행은 어떤 특징들을 포함하는 뉴런들을 의미하고, 뉴런을 가장 잘 활성화 하는 이미지(patch)를 순서대로 정렬, 이를 통해서 해당 뉴런이 무엇을 찾고 있는지 짐작해 볼 수 있다.
cf) 뉴런 : activation map의 하나의 scaler
> layer가 깊어질수록 receptive field 영역이 넓어지므로 더 큰 구조들을 찾고 있음을 알 수 있다.
> 이미지에서 어떤 픽셀이 classification에 영향을 주는지 찾기 위한 방법
> 이미지의 일부분을 가린 뒤 네트워크에 통과시켜 class 예측 확률이 어떻게 변하는지 heat map으로 기록, (일부분을 가릴 때 일반적으로 데이터의 평균값으로 바꾸어준다.)
> 가린 이미지의 network score가 크게 변하면 그 부분은 classfication에 매우 중요하다는 의미이다.
> go-cart 사진의 경우, go-cart를 가렸을 때 확률 값이 급격하게 감소한다. (go-cart가 중요하다는 것을 의미)
cf) 진한 색: 확률 값이 낮다, 연한 색: 확률 값이 높다.
> 이미지 픽셀에 대해서, 예측한 클래스 스코어의 그레디언트를 계산하는 방법,
> 어떤 픽셀이 영향력이 있는지 알려준다.(픽셀을 조금 바꿨을 때 클레스 스코어가 변하는 것을 관찰)
> 네트워크의 중간 뉴런을 고른 뒤에 입력 이미지의 어떤 부분이 선택한 뉴런에 영향을 주는지를 찾는다.
> saliency와 유사하게, 입력 이미지의 각 픽셀에 대한 네트워크 중간 뉴런의 그레디언트를 계산한다.
> back prop과정에서 Relu를 통과시키면, gradient 부호가 양수인 경우만을 backprop하여 관심 뉴런의 gradient을 좀 더 선명하게 시각화 할 수 있다.
> 가중치를 고정을 한 뒤, Gradient ascent를 통해서 중간 뉴런 혹은 클랙스 스코어를 최대화 시키는 입력 이미지의 픽셀을 값을 바꾸어준다.
> regularization term을 추가하여서 생성된 이미지가 Overfitting 되는 것을 방지 한다. (특정 뉴런 값을 Maximize하면서, 이미지가 자연스럽게 보이게 만들어준다.)
- 최적화 과정에 이미지에 주기적으로 가우시안 블러를 적용한다.
- 주기적으로 값이 작은 픽셀들은 모두 0으로 만들어준다.
- gradient가 작은 값들도 모두 0으로 만든다.
> 훨씬 더 보기 좋은 이미지를 생성할 수 있다.
> 어떤 이미지 내의 특정 클래스를 강화하는 방향으로 이미지의 최적화 (Optimiatioin to Image) 를 수행함으로써 해당 이미지의 클래스를 왜곡시키는 것.
아무 이미지(코끼리 사진) 하나를 고른다.
이 이미지(코끼리 사진)를 코알라라고 분류하도록 이미지를 조금씩 조정한다.
네트워크는 이미지를 코알라라고 분류해 버린다.
> DeepDream을 통해 모델이 이미지의 어떤 특징들을 찾고 있는지를 짐작할 수 있다.
Forward : 입력 이미지를 CNN의 선택한 중간 레이어까지 Forward 시킨다.
선택한 중간 레이어의 Gradinent를 Activation map값과 같게 설정
Backward : back prob을 하여 weight가 아닌 이미지의 gradinet을 구한다.
이미지를 업데이트 한다.
> 이미지를 네트워크에 통과시킨 뒤, 특징(activation map)을 저장 한다.
> 이 특징(activation map)을 가지고 이미지를 재구성한다.
> 기존의 이미지의 feature vector와 새롭게 생성한 이미지의 feature vector의 거리를 최소화하여 이미지를 잘 생성하도록 만들어준다 (+ 특징 파악)
> layer가 깊어질수록 정보가 많이 사라진다. 깊어질수록 정확한 픽셀 값이 사라지고, 색이나 텍스처 같은 미세한 변화에도 robust한 의미론적 정보들만을 유지한다.
> 입력 텍스처 패치가 있을 때, 동일한 텍스터의 더 큰 패치를 생성한다.
> Nearest Neighbor 방법은 Scan line을 따라서 한 픽셀씩 이미지를 생성한다.
> 현재 생성해야 할 픽셀 주변의 이미 생성된 픽셀들을 계산한 후, 입력 텍스처 패치에서 한 픽셀을 복사하는 방식이다.
> Neural network를 활용하여 텍스처 합성 문제를 해결하려 했다. (Gram Matrix)
입력 텍스처(자갈 사진)을 CNN을 통과시켜 특정레이어에서 특징 맵(C x H x W)을 가져온다. H x W 그리드는 공간 정보이며 C는 해당 지점의 이미지 특징이다.
feature map에서 서로 다른 두 개의 특징 벡터를 뽑아낸다.
두 벡터의 외적을 계산해서 C x C 행렬을 만든다.(서로 다른 두 지점에 있는 특징들간 co-occurrence를 담고 있음)
가령 C x C 행렬의 (i, j) 번째 요소의 값이 크다는 것은 두 입력 벡터의 i번째, j번째 요소가 모두 크다는 의미이다. 서로 다른 공간에서 동시에 활성화 되는 특징들을 포착할 수 있음
- H x W 그리드의 전부에서 수행해주고, 결과에 대한 평균을 계산해보면 C x C Gram matrix를 얻을 수 있다.
> Gram Matrix는 공간 정보를 전부 날려버리고 대신에 특징들 간의 co-occurrence 만을 포착하고 있다.
> co-variance Matrix를 사용하는 것도 좋지만 계산 비용이 크기에 gram matrix를 사용한다.
> 입력 이미지의 특징맵 전체를 재구성하기 보다는 gram matrix를 재구성하도록 한다.
pretrain model를 가져 온다.(VGG)
이미지를 VGG에 통과시키고 feature map을 생성후 gram matrix를 계산한다.
생성해야 할 이미지를 랜덤으로 초기화시킨다.
원본 이미지와 생성된 이미지(처음 초기화 된 이미지)의 gram matrix간의 차이를 L2 norm을 이용해 Loss를 계산하다.
Backprob을 통해 생성된 이미지의 픽셀의 gradient를 계산한다.
gradient ascent를 통해 이미지를 업데이트 한다.
> 레이어가 깊어질 주록 패턴을 잘 구현해 내는 것을 볼 수 있다.
> Style Tranfer는 texture synthesis와 feature inversion을 조합한 방식이다
> Content Image는 이미지의 형태, Style Image는 이미지의 텍스처을 나타낸다.
> feature reconstruction loss, gram matrix loss 최소화하면 style image스러운 화풍의 content image가 생성된다.
> 네트워크에 Content이미지와 style이미지를 네트워크에 통과시키고 feature map과 gram matrix을 계산한다.
> Output이미지는 랜덤 노이즈로 초기화한다.
> forward/backward를 반복한 후 gradient ascent를 이용해서 이미지를 업데이트한다.
> style/content loss간의 가중치에 따라 생성되는 이미지의 형태가 달라질 수 있다.
> 그러나 Style Transfer은 Content Image와 style Image를 함께 넣어 학습을 진행하는 방식이다보니, Content Image가 바뀔 때마다 다시 학습을 시켜야 하므로 많은 연산을 필요하다.
> 이러한 문제를 해결하기 위해서 Fast Style Transfer가 등장하였다.
> Style image를 고정시켜놓고(1장을 학습시키고 network를 그대로 이용) Content Image만을 입력으로 하여 단일 네트워크를 학습(가중치 업데이트)시킨다.
> 학습 시에는 content/style loss를 동시에 학습시킨다.
<참고자료>
[1] https://hoya012.github.io/blog/Fast-Style-Transfer-Tutorial/