Review of Image Style Transfer using CNN(2015)

최근 딥러닝 알고리즘이 다양한 산업 분야에 활용되고 있는데 특히 Convolutional neural network(CNN)를 기반으로 한 알고리즘은 컴퓨터 비전(vision) 분야의 큰 발전이 있었다. 실제로 요즘은 이미지 처리가 아닌 문제에서도 대부분의 알고리즘에서 CNN을 사용한다. 2015년 CNN을 활용해서 이미지의 스타일을 변화시키는 알고리즘이 공개되어서 큰 반응을 불러왔다. 2018년 현재 이 알고리즘의 문제점 등을 개선하여 개발된 많은 알고리즘들이 공개되었으며 사진 이미지 뿐만 아니라 영상에도 적용하는 듯 다양한 활용들이 나왔다(참고). 주어진 이미지의 윤곽과 같은 객체 정보를 유지한 채 다른 이미지의 스타일을 주는 알고리즘이다. 아래 이미지는 2018 평창 올림픽 마스코트인 수호랑 이미지에 실제 호랑이 이미지의 스타일을 합성한 것이다.

본 포스트에서는 이 논문의 알고리즘에서 사용한 수학적인 방법을 소개할 것이다.

특징

  • 1000개의 라벨을 갖는 이미지 데이터셋의 분류 모델 중 하나인 VGG19 모델을 기반으로 VGG19에서 기학습된(pre-trained) convolution filter(weight)를 사용하였다(Imagenet challenge). 총 19개의 레이어(layer)를 갖고 있는 모델이다.
  • VGG19 모델 뒷 부분에 있는 3개의 fully connected 레이어는 사용하지 않았다. 즉, 16개의 convolution 연산만 한다.
  • 논문 저자의 말을 빌리면 좀 더 매력(?)적인 이미지를 생성하기 위해서 convolution 연산의 max pooling을 average pooling으로 대체하였다(원문: For image synthesis we found that replacing the maximum pooling operation by average pooling yields slightly more appealing results, which is why the images shown were gen- erated with average pooling).
  • 모든 레이어의 activation function은 ReLU(Rectified Linear Unit)를 사용하였다. $f(z):=\max(z,0)$.
  • 모델의 cost는 최종 단계에서 한번만 계산하는 것이 아니라 각각의 레이어에서 나온 feature map들의 cost를 합산한다($F^l$, $P^l$, $A^l$).

참고: VGG19(1000개 종류의 이미지 데이터셋 분류)

  • input: $(224\times 224)$ RGB 이미지

input $\longrightarrow$ conv3-64 $\longrightarrow$ maxpool(conv3-64) $\longrightarrow$ conv3-128 $\longrightarrow$ maxpool(conv3-128) $\longrightarrow$ conv3-256 $\longrightarrow$ conv3-256 $\longrightarrow$ conv3-256 $\longrightarrow$ maxpool(conv3-256) $\longrightarrow$ conv3-512 $\longrightarrow$ conv3-512 $\longrightarrow$ conv3-512 $\longrightarrow$ maxpool(conv3-512) $\longrightarrow$ conv3-512 $\longrightarrow$ conv3-512 $\longrightarrow$ conv3-512 $\longrightarrow$ maxpool(conv3-512) $\longrightarrow$ FC-4096 $\longrightarrow$ FC-4096 $\longrightarrow$ softmax(FC-1000)


Neural style transfer 알고리즘 구성

논문 Figure 1. Image representations in a Convolutional Neural Network (CNN). A given input image is represented as a set of filtered images at each processing stage in the CNN. While the number of different filters increases along the processing hierarchy, the size of the filtered images is reduced by some downsampling mechanism (e.g. max-pooling) leading to a decrease in the total number of units per layer of the network. Content Reconstructions. We can visualise the information at different processing stages in the CNN by reconstructing the input image from only knowing the network’s responses in a particular layer. We reconstruct the input image from from layers ‘conv1 2’ (a), ‘conv2 2’ (b), ‘conv3 2’ (c), ‘conv4 2’ (d) and ‘conv5 2’ (e) of the original VGG-Network. We find that reconstruction from lower layers is almost perfect (a–c). In higher layers of the network, detailed pixel information is lost while the high-level content of the image is preserved (d,e). Style Reconstructions. On top of the original CNN activations we use a feature space that captures the texture information of an input image. The style representation computes correlations between the different features in different layers of the CNN. We reconstruct the style of the input image from a style representation built on different subsets of CNN layers ( ‘conv1 1’ (a), ‘conv1 1’ and ‘conv2 1’ (b), ‘conv1 1’, ‘conv2 1’ and ‘conv3 1’ (c), ‘conv1 1’, ‘conv2 1’, ‘conv3 1’ and ‘conv4 1’ (d), ‘conv1 1’, ‘conv2 1’, ‘conv3 1’, ‘conv4 1’ and ‘conv5 1’ (e). This creates images that match the style of a given image on an increasing scale while discarding information of the global arrangement of the scene.

Input image

  • 이미지(content image) $\mathbf{p}$: 변형하고 싶은 이미지
  • 스타일 이미지(style image) $\mathbf{a}$: 추출하고 싶은 스타일을 갖고 있는 이미지

Output image

  • 생성된 이미지(generated image): $\mathbf{x}$

여기서 input 이미지 $\mathbf{p}$와 $\mathbf{a}$의 크기는 같을 필요 없다. 하지만 생성된 이미지 $\mathbf{x}$는 $\mathbf{p}$와 동일한 크기로 생성된다. 이미지 $\mathbf{x}$를 생성하는 알고리즘으로 윤곽은 $\mathbf{p}$ 이미지에서 추출하고 스타일 또는 texture는 $\mathbf{a}$에서 추출한다. 수학적으로 효과적으로 설명하기 위해 논문에는 없는 문자나 기호를 추가하였다.

$\mathbf{x}$의 초기값은 random noise이다. 각 레이어에서 진행되는 연산과 cost를 계산하는 방법을 살펴보자.

  • 첫 번째 convolution 연산 $C^1$ : conv3-64는 $(3\times 3)\times3$ shape의 64개 filter를 stride=1, padding=1 이고 $2\times2$ average pooling을 한다(원래 VGG19는 max pooling).
  • conv3-64의 filter의 개수는 64이므로 $C^1(\mathbf{p})=\mathbf{p}^1$과 $C^1(\mathbf{x})=\mathbf{x}^1$의 shape은 $(m_w, m_h,64)$이고 $C^1(\mathbf{a})=\mathbf{a}^1$의 shape은 $(\widetilde{m}_w, \widetilde{m}_h,64)$ 이다. $m_w, m_h, \widetilde{m}_w, \widetilde{m}_h$ 값은 input 이미지 $\mathbf{p}$와 $\mathbf{a}$의 크기에 의존한다. Cost를 계산할 때는 $\mathbf{p}^1$, $\mathbf{x}^1$, $\mathbf{a}^1$을 다음과 같이 shape 변경 한다.
\[P^1 = \mathbf{p}^1.\text{reshape}(64, -1)\] \[F^1 = \mathbf{x}^1.\text{reshape}(64, -1)\] \[S^1 = \mathbf{a}^1.\text{reshape}(64, -1)\]

즉, 3차원 rank 데이터를 filter의 개수를 기준 2차원 rank로 변형한 데이터이다. 다음 그림을 보면 첫 번째 convolution 레이어를 거친 결과와 cost 계산을 위해서 변환한 형태를 확인할 수 있다.

여기서 $N_1$은 첫 번째 layer에서 filter의 개수인 64이고 $M_1$은 $\mathbf{p}^1$과 $\mathbf{x}^1$ 이미지의 가로$\times$세로 = $m_w \times m_h$를 의미하고 $\widetilde{M}_1$은 $\mathbf{a}^1$의 $\widetilde{m}_w \times \widetilde{m}_h$를 의미한다.

예를 들어서, input 이미지인 $\mathbf{p}$의 shape이 VGG19의 input 사이즈와 같은 $(224,224,3)$ 이라고 가정해보자. 여기서 3은 R,G,B 3개의 채널을 의미한다. $(224,224,3)$ 사이즈 $\mathbf{p}$에 $(3\times 3) \times 3$인 filter 64를 stride=1, padding=1 (padding=same)이고 $2\times 2$ average pooling을 한 것이 첫 번째 연산 $C^1$(conv3-64 convolution) 이므로 $\mathbf{p}^1$의 shape은 $(112,112,64)$ 이다. 결론적으로 cost 계산을 위해 펼친(flatten) $P^1$의 shape은 $(64,112\times 112)$ 이다.

\[N_1 = 64,\quad M_1=112\times 112\]

이다.

위 연산을 $l$번 째 레이어로 일반화 하면 다음과 같다.

$l$ 번 째 레이어

\[N_l := \text{ convolution filter 개수}\] \[M_l := \text{ feature map 이미지의 width} \times \text{height}\]

$(N_l, M_l)$ 차원의 행렬 $F^l$의 $N_l$개 행을 $F^l_k\in R^{M_l}$ 이라고 하고 $F_{ij}^l$을 $F^l$의 $i,j$ 번 째 성분이라고 하자. 즉, $F^l\in R^{N_l \times M_l}$을 다음과 같이 분할 했다.

\[F^l = \left(\begin{array}{cc} F_1^l\\ \vdots \\F_{N_l}^l \\ \end{array}\right), \quad F_k^l \in R^{M_l}\] \[F_{ij}^l:=\text{ the component of feature map of the }i^\text{th} \text{filter at position }j\]

목적함수(objective function)

Neural style transfer 알고리즘의 cost 는 다음과 같이 정의한다.

\[\text{cost}:= \alpha \cdot L_\text{content} (\mathbf{p}, \mathbf{x}) + \beta \cdot L_\text{style}(\mathbf{a}, \mathbf{x})\]

여기서 $\alpha$와 $\beta$는 content 와 style loss의 weight이다(즉, $\beta=0$인 경우에 생성 이미지 $\mathbf{x}$는 $\mathbf{p}$와 매우 유사하게 나온다).

논문 Figure 2. Style transfer algorithm. First content and style features are extracted and stored. The style image $\mathbf{a}$ is passed through the network and its style representation $A^l$ on all layers included are computed and stored (left). The content image $\mathbf{p}$ is passed through the network and the content representation $P^l$ in one layer is stored (right). Then a random white noise image $\mathbf{x}$ is passed through the network and its style features $G^l$ and content features $F^l$ are computed. On each layer included in the style representation, the element-wise mean squared difference between $G^l$ and $A^l$ is computed to give the style loss $L_\text{style}$ (left). Also the mean squared difference between $F^l$ and $P^l$ is computed to give the content loss $L_\text{content}$ (right). The total loss $L_\text{total}$ is then a linear combination between the content and the style loss. Its derivative with respect to the pixel values can be computed using error back-propagation (middle). This gradient is used to iteratively update the image $\mathbf{x}$ until it simultaneously matches the style features of the style image $\mathbf{a}$ and the content features of the content image $\mathbf{p}$ (middle, bottom).

Content loss

$\mathbf{p}$와 $\mathbf{x}$를 비교하는 content loss는 각 레이어에서의 feature map들의 MSE(mean squared error)를 합산하는 형태로 다음과 같이 정의한다.

\[L_\text{content} (\mathbf{p}, \mathbf{x}):= \sum_l L_\text{content}(\mathbf{p},\mathbf{x},l)\] \[\sum_l L_\text{content}(\mathbf{p},\mathbf{x},l):= \frac{1}{2}\sum_{i,j} \left (F^l_{ij} - P^l_{ij} \right )^2\]

모든 레이어의 activation이 ReLU이므로 변수 $F^l_{ij}$에 대한 편미분은 다음과 같다.

\[\frac{\partial L_\text{content}(\mathbf{p},\mathbf{x},l)}{\partial F^l_{ij}} = \begin{cases} (F^l -P^l)_{ij} \quad &\text{ if } F_{ij}>0\\ 0 &\text{otherwise} \end{cases}\]

다음과 같이 convolution 연산 없이 $\mathbf{p}$와 $\mathbf{x}$의 차이를 loss로 정의하게 되면

\[\sum_{i,j} (\mathbf{p}_{ij} - \mathbf{x}_{ij} )^2\]

이미지의 객체나 윤곽을 찾는 것이 아니라 단순히 전체 이미지의 유사도만 높이는 결과가 나오기 때문에 위와 같이 정의하지 않고 feature map(convolution)의 오차로 loss를 정의한 것으로 보인다.

Style loss

스타일 이미지 $\mathbf{a}$에서 어떻게 texture를 추출해서 $\mathbf{x}$를 생성하는지 살펴보자. Content loss와는 달리 $\mathbf{a}$와 $\mathbf{x}$의 shape이 다르기 때문에 동일한 방법으로 정의할 수 없다. Style loss를 정의하기 전에 Gram matrxi에 대해 알아보자.

Gram matrix

d 차원 열벡터 $\mathbf{v}_1$, $\mathbf{v}_2$, …, $\mathbf{v}_N$ $\in R^d$의 Gram matrix $G$는 다음과 같이 정의한다.

\[G_{ij}:= \langle \mathbf{v}_i, \mathbf{v}_j \rangle=\sum_k v_{ik}\cdot v_{jk}.\]

즉, $V$를 다음과 같이 정의 했을 때

\[V = \left(\begin{array}{cc} \mathbf{v}_1\\ \vdots \\\mathbf{v}_N \\ \end{array}\right)\in R^{N\times d}\]

$G= V V^T\in R^{N\times N}$ 이다.

Style loss는 feature map $F^l$과 $S^l$의 Gram matrix 오차제곱합으로 다음과 같이 정의한다.

\[L_\text{style} (\mathbf{a}, \mathbf{x}):= \sum_l L_\text{style}(\mathbf{a},\mathbf{x},l)\]

여기서,

\[L_\text{style}(\mathbf{a},\mathbf{x},l):= \frac{1}{4 N_l^2} \left ( G_{ij}^l - A^l_{ij} \right)^2\]

이고

\[G^l := \frac{1}{M_l}\cdot F^l (F^l)^T,\quad A^l:= \frac{1}{\widetilde{M}_l} \cdot S^l (S^l)^T\]

이다. 생성된 이미지와 스타일 이미지 feature map들의 Gram matrix는 크기가 동일하기 때문에 MSE가 유효하다. Gram matrix의 성분은 각각의 filter에 의해 convolution 연산을 한 feature map들의 inner product (또는 correlation)이다. 즉, filter를 거친 activate된 값들의 차이를 줄이면서 style을 추출하여 이전(transfer)한다.

본 논문에서는 $L_\text{style}(\mathbf{a},\mathbf{x},l):= \frac{1}{4 N_l^2 M_l^2} \left ( G_{ij}^l - A^l_{ij} \right)^2$ 으로 정의했는데 $F^l$과 $S^l$의 차원이 다르기 때문에 $M_l^2$으로 나누는 것은 틀린 것으로 보인다(논문에서는 $S^l$ notation 없음).

Reference