ML || DL/이론

[Coursera] DLS_C4W4: Neural Style Transfer

junmukbap98 2023. 10. 10. 21:35

1. Neural style transfer (NST) 란?

Content image (C)의 content (e.g., 전반적인 structure)를 살리면서 style image (S)의 style (e.g., 특정 화가의 화풍)을 가지는 이미지를 generate 하는 것

Neural style transfer 예시

 

이러한 NST를 구현하기 위해서는 NN의 shallow and deep layer에서 추출된 feature들의 특징을 먼저 알아야 한다. 

 

  • What are deep ConvNets learning?
    NN의 각 layers들을 visualization 했을 때의 결과는 아래 그림과 같다. 

각 layer의 9개 hidden unit을 최대화하는 9개의 image patches를 시각화 한 것

그림을 보면 shallow layer에서는 low-level feature (e.g., edges)를 detect 하고, layer가 깊어질수록 high-level features (complex features or patterns)를 detect 한다. 


2. Cost function for NST

그 다음, 우리는 Generated image (G)를 생성하기 위한 cost function을 정의해야 한다. 

우리는 generated image, G가 얼마나 잘 생성되었는지 측정해야 한다. 따라서 cost function을 아래와 같이 정의할 수 있다. 

$$ J(G) = \alpha J_{content}(C, G) + \beta J_{style}(S, G) $$

여기서 $\alpha$와 $\beta$는 content와 style 사이의 weight를 결정하는 hyperparameter이다. $\beta$를 크게 하면 S의 style를 좀 더 가져올 수 있다. 

 

G를 생성하기 위해서, 우리는 먼저

-G를 random하게 초기화한다.

- $J(G)$를 최소화하도록 gradient descent를 사용해서 G의 pixel value를 update 한다. 

이제는 각각의 component들을 자세하게 살펴보자. 


3. Content cost function

우리는 이를 위해서 pre-trained ConvNet의 activation을 활용한다. 

  • 먼저 content cost를 계산할 hidden layer $l$을 정한다. (이때, $l$은 너무 얕지도, 깊지도 않은 layer를 선택해서 low and high-level feature 모두 detect 할 수 있도록 한다.)
  • 그다음 pre-trained ConvNet (e.g., VGG)을 활용해서 C를 입력했을 때의 activation $a^{[l](C)}$와 G를 입력했을 때의 activation $a^{[l](G)}$를 비교한다. --> G와 C가 content 측면에서 얼마나 비슷한지 측정
  • 만약 $a^{[l](C)}$와 $a^{[l](G)}$가 유사한 값을 가지면 두 이미지 (C와 G)는 서로 유사한 content를 가지고 있다고 생각할 수 있다.

$$ J_{content}(C, G) = \frac{1}{2} ||a^{[l](C)} - a^{[l](C)}||^2 $$

위와 같이 content cost function을 정의할 수 있다. 이때 앞에 곱해지는 상수는 어차피 hyperparameter $\alpha$가 곱해지기 때문에 크게 중요하지 않다. 


4. Style cost function

"Style"이 얼마나 비슷한지를 측정하기 위해서, 여기서는 여러 개의 hidden layer $l$을 사용한다.

NST에서 "style"은 channels에 대한 activation들 간의 correlation으로 정의한다. 

 

 

  • Channel들의 correlation을 보는 것이 왜 style을 나타내는 것인지에 대한 직관
    • Correlation은 high-level texture 요소들이 이미지에 함께 나타내는지 아닌지를 알려준다. 
    • 따라서 channel 간의 correlation을 활용해서 G와 S의 style을 비교한다

"style"이 의미하는 것에 대한 직관

  • Style matrix (Gram matrix) $G^{[l]}$ for layer $l$
    • 우리는 S와 G의 style을 비교하기 위해서 style matrix를 정의하고, S와 G의 style matrix를 활용해서 cost function을 정의한다.
    • $a^{[l]}_{i, j, k}$ = hidden layer $l$의 activation이고, i, j, k는 각각 H, W, C의 index를 나타낸다.
    • 우리는 S와 G에 대한 style matirx를 아래와 같이 계산한다. 

수학적으로는 이런 style matrix는 correlation이 아니라 "unnormalized cross covariance"라고 표현한다. 하지만 여기서는 이해를 돕기 위해 correlation이라는 용어를 사용한다. 

$$ J^{[l]}_{style}(S, G) = \frac{1}{(2n^{[l]}_{H} n^{[l]}_{W} n^{[l]}_{C})^2} \sum_{k} \sum_{k'} (G^{[l](S)}_{kk'} - G^{[l](G)}_{kk'})^2 $$

로 정의 된다. 

위 식은 하나의 layer $l$에 대한 cost function이고, 우리는 여러 layer에 대해서 style을 비교해줘야 한다. (low-level and high-level의 correlation 모두 고려해야 하기 때문에) 따라서,

$$ J_{style}(S, G) = \sum_{l} \lambda^{[l]} J_{style}^{[l]}(S, G) $$

와 같이 정의된다. 여기서 $\lambda$는 각 layer들에 대한 가중치를 의미한다. 이때 G가 S를 부드럽게 따르도록 하고 싶으면 deeper layer에 큰 가중치를 주면 되고, 그게 아니라면 shallow layer에 더 큰 가중치를 부여하면 된다.