CNN 내부에서는 어떤 일들이 일어나고 있는가?
First Layer : Visualize Filter
- AlexNet을 예로들면 AlexNet은 3x11x11의 크기의 필터 64개가 존재한다
- 이 필터들은 sliding window로 영상의 일부 영역과 내적을 수행한다. 이렇게 필터의 가중치와 내적한 결과가 첫 번째 Conv Layer의 출력이다
- 첫 번째 Conv Layer는 입력 이미지와 직접 내적을 수행하기 때문에 이 필터를 단순히 시각화시키는 것 만으로도 이 필터가 이미지에서 무엇을 찾고 있는지 알아낼 수 있다
- AlexNet의 11x11x3 필터는 11x11x3 rgb 이미지로 쉽게 시각화할 수 있다
- 필터가 총 64개 이므로 64개의 11x11 이미지를 시각화시킬 수 있다
이미지 삽입 p5
- 위 이미지는 PyTorch Model zoo에서 가져온 AlexNet의 pretrained model의 필터들이다
- 이를 통해서 이 필터들이 무엇을 찾고있는지 알 수 있다
- 우선 가장 많이 찾는 것은 엣지성분이다
- 흰/검으로 길게 늘어선 필터들이 이에 해당한다
- 다양한 각도와 위치에서의 보색(oppising colors)도 있다
- 초록색과 분홍색, 주황색과 파랑색처럼 보이는 이미지들이 이에 해당한다
- 흥미로운 점은 CNN을 어떤 모델/데이터로 학습하건 간에 첫 번째 레이어는 전부 다 이런 식으로 생겼다는 점이다
- 입력 이미지에서 oriented edges 라던지 보색(opposing colors) 같은 것들을 찾는다
Middle Layer
- 앞서 했던 동일한 시각화 기법을 중간 Conv Layers에 적용하면, 우리가 보고 해석하기 더 어렵다
- 두 번째 레이어까지는 수 차례 Conv & ReLU를 거쳐야 한다
- 중간 레이어의 필터들은 직접적으로 이미지의 형태로 시각화시킬 수 없다는 문제점이 있다
- 시각화시키기 위해서는 grayscale images로 나눠서 표현해야 한다
- 중간 레이어의 필터가 무엇을 찾고 있는건지 적당한 Intuition을 얻기란 힘들다
- 이 필터들은 이미지와 직접 연결되어 있지 않기 떄문이다
- 두 번째 레이어의 필터들은 첫 번째 레이어의 출력과 연결되어 있다
- 따라서 우리가 시각화한 내용은 "두 번째 레이어의 결과를 최대화시키는 첫 번째 레이어의 출력 패턴이 무엇인지" 이다
Last Layer : Nearest Neighbors
- CNN의 마지막 레이어는 1000개의 클래스 스코어가 있다
- 이는 학습 데이터의 predicted scores를 의미한다
- 마지막 레이어 직전에는 Fully Connected Layer가 있다
- 가령 AlexNet의 마지막 레이어는 이미지를 표현하는 4096-dim 특징벡터를 입력으로 최종 Class scores를 출력한다
- 마지막 레이어는 Nearest Neighbor를 이용한 방법으로 시각화시킬 수 있다
- 픽셀 공간에서 Nearest neighbors를 계산하는 것이 아니라 CNN에서 나온 4096-dim 특징 벡터 공간에서 계산한다
- 픽셀 공간에서의 Nearest neighbors는 픽셀값이 비슷하다면 전혀 다른 개체임에도 같다고 출력된다
- 하지만 벡터 공간에서 계산하는 방법은 픽셀값이 전혀 달라도 같은 개체인 경우도 잘 구별해낸다
Last Layer : Dimensoinality Reduction
- PCA(Principle Component Analysis)는 4096-dim 과 같은 고차원 특징벡터들을 2-dim 으로 압축시키는 기법이다
- 이 방법을 통해서 특징 공간을 조금 더 직접적으로 시각화시킬 수 있다
- 하지만 t-SNE라는 알고리즘이 PCA보다 더 성능이 좋다
- t-SNE는 t-distributed stochastic neighbor embeddings 이라는 뜻이다
- 많은 사람들이 특징공간을 시각화하기 위해서 사용하는 PCA보다는 조금 더 강력한 방법이다
이미지 삽입 p10
- 위 이미지는 MNIST를 t-SNE dimensionality reduction를 통해 시각화한 모습이다
- MNIST는 0부터 9까지로 이루어진 손글씨 숫자 데이터셋이다
- MNIST의 각 이미지는 Gray scale 28x28 이미지이다
- 여기에서는 t-SNE가 MNST의 28x28-dim 데이터를 입력으로 받는다 (raw pixels)
- 그리고 압축된 2-dim 을 이용해서 MNIST를 시각화한다
- t-SNE로 MNIST를 시각화해보면 위 이미지처럼 자연스럽게 군집화된 모습을 볼 수 있다
- 각 군집이 MNIST의 각 숫자를 의미한다
이미지 삽입 p11
- 이런 식의 시각화 기법을 ImageNet을 분류하려고 학습시킨 네트워크의 마지막 레이어에도 적용해볼 수 있다
- 엄청나게 많은 이미지들을 네트워크에 통과시킨다
- 그리고 각 이미지에 대해서 최종 단의 4096-dim 특징 벡터들을 기록한다
- 그러면 4096-dim 특징 벡터들을 아주 많이 모을 수 있다
- 이 특징벡터들에 t-SNE을 적용하면 4096-dim에서 2-dim으로 압축된다
- 2-dim 특징 공간의 각 grid에 압축된 2-dum 특징들이 시각화시킨다
- 이를 통해 학습된 특징 공간의 기학적인 모습을 어렴풋이 추측해 볼 수 있다
- 결과를 보면 좌하단의 초록초록한 군집을 볼 수 있다
- 또 다른 곳들에는 다양한 종류의 개들이 모여있고, 다양한 동물들끼리 모여있고, 다양한 지역들이 모여있다
- 이를 통해 우리가 학습시킨 특징 공간에는 일종의 불연속적인 의미론적 개념(semantic notion)이 존재하며 t-SNE을 통한 dimensionality reduction version의 특징 공간을 살펴보며 그 공간을 조금이나마 느낄 수 있다
중간 특징들의 시각화
Maximally Activating Patches
- AlexNet을 예시로 보면 AlexNet의 conv5의 특징은 128 x 13 x 13-dim tensor이다
- 이 tensor는 128개의 13x13 2-dim gird로 볼 수 있다
- 따라서 이 13 x 13 ( x 1) 특징 맵을 그레이스케일 이미지로 시각화해 볼 수 있다
- 이를 시각화해보면 conv layer가 입력에서 어떤 특징을 찾고있는지를 짐작해볼 수 있다
뉴런의 활성 시각화
- 어떤 이미지가 들어와야 각 뉴런들의 활성이 최대화되는지를 시각화해보는 방법이다
- AlexNet Con5 Layer를 예시로 보면 AlexNet의 conv5는 128 x 13 x 13 한 덩어리의 activation volume을 갖는다
- 128개의 채널 중에 하나를 뽑는다. 예시에서는 17번째의 채널을 선택했다
- 많은 이미지들을 CNN에 통과시킨다. 그리고 각 이미지의 conv5 features를 기록해 놓는다
- 그러고나서 어떤 이미지가 17번째 특징 맵을 최대로 활성화시키는지를 살펴본다
- 현재 뉴런은 convolutional layer이다. 따라서 receptive field가 작은 편이다
- 각 뉴런이 전체 이미지를 보고있지는 않다. 이미지의 일부만을 보고 있다
- 따라서 특정 레이어의 특징을 최대화시키는 이미지의 일부분(pathes)을 시각화킨다. 그리고 특정 레이어의 활성화 정도를 기준으로 패치들을 정렬시키면 된다
이미지 삽입 p14
- 위 이미지는 해당 레이어의 활성을 최대화시키는 패치들이다
- 각 행에 있는 패치들이 하나의 뉴런에서 나온 것이다
- 각 패치들은 데이터셋에서 나온 패치들을 정렬한 값들이고 이 패치들이 해당 뉴런의 활성을 최대화시키는 패치들이다
- 패치의 특징을 통해서 해당 뉴런이 무엇을 찾고있는지 짐작해 볼 수 있다
- 가령 맨 윗 행을 보면 어떤 동그란 모양을 찾고있다는 것을 알 수 있다
- 이로 미루어, 네트워크 레이어의 어떤 뉴런은 입력 영상에서 어떤 동그란 모양을 찾고 있다는 것을 알 수 있다
- 한 뉴런은 conv5 activation map의 하나의 scaler 값을 의미한다
- conv5 는 convolutional layer 이기 때문에 한 채널안의 모든 뉴런들은 모두 같은 가중치를 공유한다
- 각 채널 당 하나의 conv filter가 있고 이에 상응하는 많은 뉴런들이 있다 (activation map)
- Convolution의 특성 상 patch들을 이미지의 모든 곳에서 추출해 낼 수 있다
Occlusion Experiments
- 이 실험에서 알고자하는 것은 입력의 어떤 부분이 분류를 결정짓는 근거가 되는지에 관한 실험이다
- 우선 입력 이미지를 받는다. 그리고 이미지의 일부를 가린다
- 가린 부분을 데이터셋의 평균 값으로 채워버린다. 그리고 가려진 이미지를 네트워크에 통과시키고 네트워크가 이 이미지를 예측한 확률을 기록한다
- 이 가림 패치(occluded patch)를 전체 이미지에 대해 돌아가면서(slide) 같은 과정을 반복한다
이미지 삽입 p15
- 오른쪽의 히트맵은 이미지를 가린 patch의 위치에 따른 네트워크의 예측 확률의 변화를 의미한다
- 이 실험의 아이디어는, 만약 이미지의 일부를 가렸는데 네트워크의 스코어의 변화가 크게 발생한다면 가려진 바로 그 부분이 분류를 결정짓는데 아주 중요한 부분이었다는 사실을 짐작할 수 있다
- 위 이미지에서 가장 밑의 Go-kart의 예시를 살펴보면 빨간색 지역은 확률 값이 낮고, 노란색 지역은 확률 값이 높음을 의미한다
- 앞쪽의 Go-kard를 가렸을 때 Go-kart에 대한 확률이 아주 많이 감소함을 볼 수 있다
- 이를 통해 네트워크가 분류를 결정할 때 실제로 go-kart를 아주 많이 고려한다는 사실을 알 수 있다
Saliency Maps
- 네트워크가 픽셀들을 보고서 이미지를 특정 개체라고 분류했는지를 알 수 있다
- 이 방법은 입력 이미지의 각 픽셀들에 대해서, 예측한 클래스 스코어의 그레디언트를 계산하는 방법이다.
- 이 방법은 일종의 "1차 근사적 방법"으로 어떤 픽셀이 영향력있는지를 알려준다
- 입력 이미지의 각 픽셀에 대해서, 우리가 그 픽셀을 조금 바꿨을 때 클래스 스코어가 얼마나 바뀔까?
- 이 질문은 어떤 픽셀이 특정 개체를 분류하는데 있어서 어떤 픽셀들이 필요한지알 수 있는 또 다른 방법이 될 수 있다
- 이 방법을 통해 이미지의 Saliency map을 만들어보면 개체의 윤곽이 나타남을 알 수 있다
- 이는 네트워크가 이미지에서 어떤 픽셀들을 찾고 있는지를 짐작할 수 있다
- 이 방법은 다른 이미지들에도 적용해보면 네트워크가 올바른 지역을 보고있다는 것을 알 수 있다
이미지 삽입 p18
- 어떤 한 이미지가 있을 때, 클래스 스코어가 아니라 네트워크의 중간 뉴런을 하나 고른다. 그리고 입력 이미지의 어떤 부분이, 내가 선택한 중간 뉴런의 값에 영향을 주는지를 찾는 것이다
- 이 경우에도 앞서 했던 방법처럼 Saliency Map을 만들어볼 수 있다
- 이 경우에는 이미지의 각 픽셀에 대한 "클래스 스코어"의 그래디언트를 계산하는 것이 아니라 입력 이미지의 각 픽셀에 대한 네트워크 중간 뉴런의 그레디언트를 계산한다
- 이를 통해 어떤 픽셀이 해당 뉴런에 영향을 주는 지 알 수 있다
- 이 경우에도 평범한 back propagation을 이용한다. 하지만 back propagation 과정에서 조금의 트릭을 가미하면 조금 더 깨끗한 이미지를 얻을수 있다. 이를 "guided back propagation" 이라고 한다
- 이 방법(guided backprop)은 backprop 시 ReLU를 통과할 때 조금의 변형을 가해준다
- ReLU의 그레디언트의 부호가 양수 이면 그대로 통과시키고 부호가 음수이면 backprop하지 않는 방법이다
- 이로인해 전체 네트워크가 실제 그레디언트를 이용하는 것이 아니라 "양의 부호인 그레디언트" 만을 고려하게 된다
이미지 삽입 p21
- 실험 결과를 보면, guided backprop이 그냥에 비해 훨씬 더 선명하고 좋은 이미지를 얻을 수 있음을 알 수 있다
- 이 이미지들은 입력 이미지에 어떤 픽셀들이 특정 뉴런에 영향을 미치는지를 알려준다
Gradient Ascent
- 우리는 지금까지 Loss를 최소화시켜 네트워크를 학습시키기 위해 Gradient decent를 사용했다
- 하지만 여기에서는 네트워크의 가중치들을 전부 고정시킨다. 그리고 Gradient ascent를 통해 중간 뉴런 혹은 클래스 스코어를 최대화 시키는 이미지의 픽셀들을 만들어 낸다
- Gradient ascent는 네트워크의 가중치를 최적화하는 방법이 아니다
- 가중치들은 모두 고정되어 있다
- 대신 뉴런, 또는 클래스 스코어가 최대화될 수 있도록 입력 이미지의 픽셀 값을 바꿔주는 방법이다
이미지 삽입 p23
- 이 방법에는 regularization term이 필요하다
- regularization terms의 역할은 가중치들이 학습 데이터로의 과적합을 방지하기 위함이다
- 이 경우에도 유사하다
- 생성된 이미지가 특정 네트워크의 특성에 완전히 과접합 되는 것을 방지하기 위함이다
- regularization term을 추가함으로서, 우리는 생성된 이미지가 두 가지 특성을 따르길 원하는 것이다
- 하나는 이미지가 특정 뉴런의 값을 최대화시키는 방향으로 생성되길 원하는 것이다
- 다른 하나는 이미지가 자연스러워 보여야 한다는 것이다
- 생성된 이미지가 자연 영상에서 일반적으로 볼 수 있는 이미지이길(statistics) 원하는 것이다
- 이런 종류의 regularization term의 목적은 생성된 이미지가 비교적 자연스럽도록 강제하는 역할이다
이미지 삽입 p24
- Gradient Ascent를 위해서는 초기 이미지가 필요하다
- 이 이미지는 zeros, uniform, noise 등으로 초기화시켜준다
- 초기화를 하고나면 이미지를 네트워크에 통과시키고 여분이 관심있는 뉴런의 스코어를 계산한다
- 그리고 이미지의 각 픽셀에 대한 해당 뉴런 스코어의 그레디언트를 계산하여 back prop을 수행한다
- 여기에서는 Gradient Ascent를 이용해서 이미지 픽셀 자체를 업데이트한다
- 해당 스코어를 최대화시킨다
- 이 과정을 계속 반복한다
이미지 삽입 p27
- 단순하게 생성된 이미지에 대한 L2 norm을 계산해서 더해준다
- 사실 L2 norm을 추가하는 것 자체에 큰 의미가 있는 것은 아니다
- Gradient Ascent와 같은 이미지 생성과 관련된 방법들의 초창기 문헌에서 종종 보이는 regularizer 중 하나일 뿐이다
이미지 삽입 p29
- Jason Yesenski, et al의 논문에서 이들은 아주 인상적인 regularizers를 추가했다
- L2 norm constraint은 여전히 있다. 그리고 최적화 과정에 이미지에 주기적으로 가우시안 블러를 적용한다
- 또한 주기적으로 값이 작은 픽셀들은 모두 0으로 만든다
- 낮은 기울기의 픽셀 값 중 일부는 0으로 설정된다
- 그레디언트가 작은 값들도 모두 0으로 만든다
- 이는 일종의 projected Gradient descent 라고 볼 수 있다
- 생성된 이미지를 더 좋은 특성을 가진 이미지 집합으로 주기적으로 매핑시키는 방법이다
이미지 삽입 p31
- 이 과정은 최종 스코어에만 적용하는게 아니라 중간 뉴런에도 적용해볼 수 있다
- 클래스의 스코어를 최대화시키는 것이 아니라 중간의 뉴런을 최대화시키는 이미지를 생성해볼 수도 있다
- 이를 통해서 중간 뉴런이 무엇을 찾고있는지 짐작해볼 수 있다
- 위 이미지에서 예제 이미지가 큰 이미지일수록 receptive fileds 가 더 큰 뉴런들이다
- Receptive field가 클수록 이미지 패치 내에 더 큰 곳을 볼 수 있다
- 이런 뉴런들은 입력 이미지에서 더 큰 구조와 더 복잡한 패턴을 찾는 경향이 있다
이미지 삽입 p33
- 각 클래스마다 클러스터링 알고리즘을 수행한다
- 한 클래스 내 서로 다른 모드들 끼리 다시 한번 클래스가 나뉜다. 그리고 나뉜 모드들과 가까운 곳으로 초기화를 해준다
- 이 방법을 통해서 multimodality를 다룰 수 있다
- 위 이미지를 보면 여덟개의 이미지는 모두 식료품점이다
- 가장 상위의 이미지들은 선반 위에 전시된 물건들을 클로즈업 한 것 같아 보인다
- 그리고 하단의 이미지들은 사람들이 식료품점을
돌아다니고 있는 모슴인 것처럼 보인다
- 하지만 이 둘은 아주 다르게 생겼다
- 많은 클래스들이 이렇게 multimodality를 가지고 있다
- 이미지를 생성할 때 이런 식으로 multimodality를 명시하게 되면 아주 좋은 (다양한) 결과를 얻을 수 있게 된다
Feature Inversion
- 특징(feature)으로부터 원본 입력(input)을 재구성하는 과정을 의미한다
- 먼저 모델을 통해 입력 이미지의 특징을 추출한다. 그런 다음, 이 특징을 최대한 잘 재현하는 이미지를 찾는 최적화 과정을 거친다
- 이 최적화 과정은 보통 gradient descent와 같은 방법으로 수행된다
- Feature inversion은 모델이 어떤 특징을 학습하고, 이 특징이 입력 이미지의 어떤 부분을 대표하는지 이해하는 데 도움이 된다
- 네트워크의 다양한 레이어에서 이미지의 어떤 요소들을 포착하고 있는지를 짐작할 수 있게 해준다
- 어떤 이미지가 있고, 이 이미지를 네트워크에 통과시킨다. 그리고 네트워크를 통과시킨(activation map)을 저장해둔다
- 이 특징(activation map) 만 가지고 이미지를 재구성한다
- 해당 레이어의 특징 벡터로부터 이미지를 재구성해보면, 이미지의 어떤 정보가 특징 벡터에서 포착되는지를 짐작할 수 있다
- 이 방법은 regularizer를 추가한 gradient ascent를 이용한다
- 또한, 스코어를 최대화시키는 것 대신, 특징 벡터간의 거리를 최소화시키는 방법을 이용한다
- 기존에 계산해 놓은 특징 벡터와, 새롭게 생성한 이미지로 계산한 특징벡터 간의 거리를 측정한다
이미지 삽입 p51
- Total variation regularizer은 상하좌우 인접 픽셀 간의 차이에 대한 패널티를 부여한다
- 생성된 이미지가 자연스러운 이미지가 되도록 해준다
이미지 삽입 p52
- 왼쪽 이미지는 원본 이미지이다. 이 이미지를 VGG-16에 통과시킨다
- 특징 맵을 기록하고, 기록된 특징 맵과 부합하도록 하는 새로운 이미지를 합성한다
- 다양한 레이어를 이용해서 합성한 이미지들을 통해서, 얼마나 많은 정보들이 저장되어 있는지를 짐작해 볼 수 있다
- 가령 VGG-16 의 relu2_2를 거쳐서 나온 특징 벡터를 가지고 이미지를 재구성해보면 이미지가 거의 완벽하게 재구성됨을 알 수 있다
- 이를 통해, relu2_2 에서는 이미지 정보를 엄청 많이 날려버리지는 않는다는 사실을 알 수 있다
- relu4_3 과 relu5_1을 가지고 재구성 해보았을 때, 재구성된 이미지를 보면 이미지의 공간적인 구조는 잘 유지하고 있다는 것을 알 수 있다
- 재구성된 이미지만 봐도 코끼리인지, 바나나인지, 사과인지 우리 눈으로도 구별할 수 있다. 하지만 디테일은 많이 죽었다
- 정확히 어떤 픽셀인지, 어떤 색인지, 텍스터가 정확히 어떤지를 알아보기 힘들다
- 이런 낮은 레벨의 디테일들은 네트워크가 깊어질수록 손질됨을 알 수 있다
Neural Texture Synthesis
Gram matrix
이미지 삽입 p57
- 입력 텍스처로 자갈 사진이 있다. 이 사진을 네트워크에 통과시킨 후, 네트워크의 특정 레이어에서 특징 맵을 가져온다
- 이렇게 가져온 특징 맵의 크기는 C x H x W이다
- H x W 그리드는 공간 정보는 가지고 있다
- H x W 의 한 점에 있는 C차원 특징 벡터는 해당 지점에 존재하는 이미지의 특징을 담고 있다고 할 수 있다
- 이 특징 맵을 가지고 입력 이미지의 텍스쳐 descriptor를 계산한다
- 우선 특징 맵에서 서로 다른 두 개의 특징 벡터를 뽑아낸다 (빨간 색, 파란 색)
- 이 두 벡터의 외적(outer product)을 계산해서 C x C 행렬을 만든다
- 이 C x C 행렬은 이미지 내 서로 다른 두 지점에 있는 특징들 간의 co-occurrence를 담고 있다
- 가령 C x C 행렬의 (i, j) 번째 요소의 값이 크다는 것은 두 입력 벡터의 i번째, j번째 요소가 모두 크다는 의미이다
- 이를 통해 서로 다른 공간에서 동시에 활성회되는 특징이 무엇인지 2차 모멘트를 통해 어느정도 포착해 낼 수 있다
- 이 과정을 H x W 그리드에서 전부 수행해주고, 결과에 대한 평균을 계산해보면 C x C Gram matrix를 얻을 수 있다
- 이 결과를 입력 이미지의 텍스처를 기술하는 텍스처 descriptor로 사용한다
- Gram matrix의 흥미로운 점은 공간 정보를 모두 날려버렸다는 것이다
- 이미지의 각 지점에 해당하는 값들을 모두 평균화 시켰기 떄문이다
- 공간 정보를 다 날려버린 대신에 특징들 간의 co-occurrence 만을 포착해 낸다
- 때문에 gram matrix는 텍스처 기술자로 아주 제격이다
- 또한 계산도 아주 효율적이다
- C x H x W 차원의 3차원 텐서가 있다고 해도 행렬을 C x (HW)로 바꾼 다음에 한 번에 계산할 수 있다
- 공분산 행렬을 써도 무방하고, 실제로 동작도 잘 하지만 공분한 행렬을 계산하는 것 자체가 비용이 엄청 크다. 따라서 실제로 사람들은 공분산 행렬 보다는 gram matrix를 선호하는 편이다
Neural Texture Synthesis
이미지 삽입 p63
- pretrained model를 다운로드 받는다
- 보통 VGG 네트워크를 선호하여 많이 사용한다
- 이미지를 VGG에 통과시키고 다양한 레이어에서 gram matrix를 계산한다
- 생성해야 할 이미지를 랜덤으로 초기화시키고, 그 다음 과정 부터는 gradient ascent와 유사하다
- 이미지를 VGG에 통과시킨다. 그리고 여러 레이어에서 gram matrix를 계산한다
- 원본 이미지와 생성된 이미지의 gram matrix 간의 차이를 L2 norm을 이용해 Loss로 계산한다
- Loss를 backprob을 통해 생성된 이미지의 픽셀의 그레디언트를 계산한다
- gradient ascent를 통해 이미지의 픽셀을 조금씩 업데이트한다
- 이 단계을 여러번 반복한다. 다시 앞 단계로 가서 gram matrix를 계산하고, Loss를 계산하고 backprob 한다
- 이 과정을 거치면 결국 입력 텍스처와 유사한 텍스처를 만들어낼 수 있다
이미지 삽입 p64
Style Transfer
- texture synthesis와 feature inversion을 조합한 것이다
- Style transfer에서는 입력이 두 가지이다
- Content Image는 네트워크에게 최종 이미지가 어떻게 "생겼으면 좋겠는지" 를 알려준다
- Style Image는 최종 이미지의 "텍스처가 어땠으면 좋겠는지" 을 알려준다
- 최종 이미지는 content image의 feature reconstruction loss도 최소화하고(1), Style image의 gram matrix loss도 최소화하는 방식으로 최적화하여 생성해 낸다
이미지 삽입 p69
이미지 삽입 p70
- 네트워크에 content/style 이미지를 네트워크에 통과시키고 gram matrix와 feature map을 계산한다
- 최종 출력 이미지는 랜덤 노이즈로 초기화시킨다
- forward/backward를 반복하여 계산하고 gradient ascent를 이용해서 이미지를 업데이트한다
- 파라미터를 조절하여 다양한 결과를 만들어 낼 수 있다
- 동일한 content image라고 할지라도 다양한 style images를 고르게 되면 전혀 다른 이미지들이 생성된다
- 하이퍼파라미터도 자유롭게 조정할 수 있다. style/content loss의 joint loss이기 때문이다
- gram matrix를 계산하기 앞서 style image를 resizing 해서 넣어준다면 Style image로부터 재구성된 특징들의 스케일을 마음대로 조절할 수 있다
- 또한 여러 장의 style images를 가지고 style transfer를 할 수도 있다
단점
- 아주 느리다
- 이미지를 만들어 내려면 backward/forward를 아주 많이 반복해야 한다
- 메모리와 계산량이 엄청나게 필요하다
- 엄청 좋은 GPU를 쓰더라도 이미지 한장을 만드는데 수십 분이 소요된다
- 네트워크 하나당 하나의 Style Transfer 밖에 할 수 없다
해결책
이미지 삽입 p80
- Style tranfer를 위한 또 다른 네트워크를 학습시키는 것이다
- 이 방법은 합성하고자 하는 이미지의 최적화를 전부 수행하는 것이 아니라 Content image만을 입력으로 받아서 결과를 출력할 수 있는 단일 네트워크를 학습시키는 방법이다
- 이 네트워크의 학습 시에는, content/style loss를 동시에 학습시키고 네트워크의 가중치를 업데이트한다
- 학습은 몇 시간이 걸릴 수 있지만, 한번 학습시키고 나면 이미지를 네트워크에 통과시키면 결과가 바로 나올 수 있다
- Segementation Network와 매우 유사하게 생겼다
- Sementic segmentation 에서는 다운 샘플링을 여러 번 진행하고
transposed conv로 업 샘플링한다
- Segmentic segmentation과 다른 점이라고는 출력이 RGB 이미지라는 점이다
- 또한 네트워크 중간에 batch norm이 들어간다
출처 및 참조
https://youtu.be/6wcs6szJWMY?si=onVAnwDQfwEQVK8_