본문 바로가기

Review/Reading

Glow: Generative Flow with Invertible 1X1 convolutions 논문 리뷰

논문은 이곳에 링크를 걸어두겠다.

​동아리에서 논문세미나(WaveGlow)를 했던 내용으로 발표영상도 있으니 참고하면 좋겠다.

 

 

순서로는,

 

  • 생성모델의 종류를 알아본다.
  • flow기반 방법을 이해하기 위한 수학적 근간을 알아본다.
  • flow기반 방법의 수식을 이해해본다.
  • Normalizing flow가 복잡한 분포를 생성해내는 것을 알아본다.
  • Glow가 어떻게 normalizing flow를 구현했는지 model구조를 알아본다.

Generative model의 3가지 유형

1. Generative adversarial networks(GAN)

GAN은 생성자(generator)와 구분자(discriminator)로 구성되어있다. 구분자는 생성자가 생성해낸 fake sample들로부터 진짜 데이터를 구별하는 일을 한다. 그리고 생성자는 구분자가 더 못맞추도록 서로 경쟁하면서 발전된 generator를 만든다. 두 모델은 minimax game을 하는 것처럼 trainning 된다.

2. Variational autoencoder(VAE)

VAE는 데이터를 잘 나타낼 수 있는 feature로 데이터를 encoding한다. 변분추론(Variational inference)의 목적은 계산이 어려운 사후확률 분포를 계산이 쉬운 분포로 근사하는 것이다. 몇가지 수식정리를 거치면 ELBO를 도출할 수 있고, 이를 maximize하는 방식으로 network를 optimize한다.

3. Flow-based generative models

flow기반의 모델은 invertible transformation의 sequence에 의해 만들어진다. 두가지 생성모델 모두 명시적으로 실제 데이터의 확률분포 p(x)를 학습하지 않는데, 그것이 어렵기 때문이다. 앞선 두가지 방법과 다르게 이 모델은 명시적으로 데이터의 확률분포 p(x)를 학습한다.  Flow기반의 generative model같은 경우에는 이런 어려운 문제를 normalizing flow라는 것으로 정복하려고 한다. loss는 간단한게 log-likelihood다.

 

그림을 보면 GAN과 VAE는 각각 구분자와 인코더부분이 사다리꼴 모양이다. 이는 원본 데이터를 압축하는 것을 의미하고, 압축 및 확장하는 과정에서 데이터 손실이 발생할 수 있다 (lossy). Flow-based 생성모델은 그림에서도 볼 수 있듯이 역함수변환이 분포생성에 관여하는 것으로, 역함수 변환을 통해 데이터 손실을 줄일 수 있다.

Flow-based generative model을 이해하기 위한 수학적 background

수학적 배경에 대한 자료는 이곳에서 가져왔다.

1. 변수변환 (Change of variable formula)

 

이게 뭔 소리냐 라고 생각할 수 있다. 침착하고 예시를 들어보자.

어떤 반 학생들의 키의 평균이 175cm, 표준편차 5cm라고 하고, normal distribution을 따른다고 하자.

 

 

여기서 단위만 mm로 바꾼다면 아래와 같이 표현할 수 있을 것이다.

 

 

단위만 바꿨지 같은 말인데 likelihood가 10배가 차이나는 것을 알 수 있다. 왜 이런 차이가 나는 것일까?

 

 

Continuous distribution의 likelihood는 해당 값이 일어날 확률을 말해주지 않는다!! pdf영역의 크기가 해당 구간이 일어날 확률을 말해준다. 아까 봤던 변수변환 식에 이 예시를 대입해보면,

 

 

변환된 변수와 원래 변수사이의 likelihood변화를 확인할 수 있다.

2. 자코비안 행렬(jacobian matrix)과 Determinant(행렬식)

 

 

자코비안행렬의 행렬식을 변수변환된 확률의 likelihood에 scaling을 해줘서 원래의 likelihood를 쉽게 구할 수 있게된다.

 

 

형광펜 칠한 부분을 구하기 위해서 쓰는 것이다. 자코비안 행렬은 아래와 같이 표현할 수 있다.

 

 

총 정리를 해보면,

 

Flow-based model에서 가장 중요한 2가지는?

1)Normalizing Flow (NF): NF가 무엇인지 알아야하고, GLOW에서는 이를 affine coupling layer로 구현

2)Loss함수: NLL(Negative Log Likelihood)

두가지를 순서대로 아래에서 바로 설명하겠다.

Normalizing Flows

좋은 density estimation을 하는 것은 매우 어렵다. 예를들면, 우리가 딥러닝모델에서 back prop을 수행하기 때문에  embedded 확률분포(p(z|x),사후확률)가 미분을 쉽고 효율적으로 계산할 수 있을 정도로 간단해야한다. 그래서 generative model의 latent variable(z)을 가우시안분포로 모델링하는 것이다. (실제 분포는gaussian보다 복잡할지라도..)

여기서 이제 Normalizing Flow(NF)model이 나오게 되는데 이는 더 좋고 더 강력한 distribution으로 근사하는 모델이다. NF는 invertible transform function의 sequence를 적용해서 간단한 distribution을 복잡한 distribution으로 transform한다. 이런 transform의 chain을 통과해서 flow하면서, 이 모델은 반복적으로 변수(variable)를 '변수변환이론' 에 의해 대체하게 된다. 그리고 결국에 final target variable x의 확률분포를 얻게된다.

flow함수들을 어떻게 구현하느냐는 모델마다 다를 것이다.

 

 

unit gaussian/uniform분포를 가정하고 flow를 10번 거치니 복잡한 분포도 표현할 수 있음을 예시로 확인가능

 

Flow-based generative model에서 Loss와 그 의미

Flow-based generative model의 loss는 NLL(Negative log likelihood)이다.

 

 

data space상에서의 likelihood를 최대화 하는 것이 목적이 된다. 그렇기 때문에 loss로 변환하면 negative를 취해야하고, NLL loss를 쓰게 되는 것이다. 모든 데이터에 대해 연산해야하기 때문에 mean값을 취한다.

원래 px(x)를 추정하려면, 여러 분포들을 총동원해서 복잡하게 estimation해야한다. 하지만 어떤 변환을 통해 간단한 pz(z)를 아래 그림과 같이 정할 수있다.

 

이렇게 pz(z)를 간단하게 정하고,

 

 

위의 식을 만족시키는 z=f(x)에서의 복잡한 f(x)를 찾는 문제로 변환할 수 있다.

총 정리를 해보면,

구하고자 하는 것: f(x)

제약조건: 자코비안 행렬의 determinant

 

 

Determinant of jacobian term이 없으면 어떻게 될까?

 

 

pz(f(x))를 최대화 할 때, determinant가 0으로 가기 때문에 역변환이 어렵다. 그렇기 때문에 det term을 제약조건으로 걸어줘야한다. 사실 아래의 식 같은 경우는 normalizing flow를 여러번 거친다는 사실을 무시하고 data space에서의 likelihood를 정의했다.

 

 

이제 Normalizing flow를 추가해서 data space에서의 likelihood를 수정하자.

 

(위의 수식이해를 위해 추가)

Normalizing Flow 구현 시 만족해야 하는 조건

condition1) It is easily invertible. (역변환해서 generate해야함)

condition2) Its Jacobian determinant is easy to compute. (자코비안 computational cost가 높음)

Glow: Generative Flow with Invertible 1x1 Convolutions

 

 

Glow는 flow를 한번 거치는 것이 그림의 a) 블럭을 통과하는 것으로 모델링 되어있다. a) 블럭을 b)의 multi-scale architecture에 적용했다는 것이 이 논문의 골자다. contribution은 invertible 1X1 conv를 써서 shuffle을 했다는 것.

1) flow block 내부

블럭은 3가지의 substep으로 구성되어있다. 각각 하나씩 살펴보자.

 

Substep 1. actnorm

(batch norm 대체)

이는 activation함수의 normalization을 뜻한다. 이 step에서는 각 채널에 scale과 bias parameter를 이용해서 affine transform을 한다.

 

 

이는 batch normalization과 유사하지만 mini-batch size1에서 동작한다. scale,bias parameter는 학습하는 파라미터이지만 initialize된다.  그래서 데이터의 첫 mini-batch는 actnorm이후 zero mean unit variance가 된다. 초기화 후, scale 과 bias는 데이터와 무관하게 trainable parameter로 취급된다.

(Substep 2보다 3을 먼저 설명하겠다.)

Substep 3. Affine coupling layers (invertible NF function)

(jacobian의 determinant 구하는데 시간이 오래걸려서)

이 layer는 RealNVP(Dinh et al., 2017)에 나온 affine coupling layer과 동일하다.

 

1)처음 d까지의 차원은 그대로 가져간다.

2)d+1~D 차원까지는 scale-and shift를 하는 affine transform을 취한다.

 

여기서 scale, shift parameter들은 처음 d차원의 function들을 이용한다.

이를 아래의 식으로 정리할 수 있다.

 

 

아래 그림을 통해 쉽게 back prop이 가능함을 알 수 있다. (condition1만족)

 

 

이 변환은 jacobian determinant를 쉽게 계산할 수있다.(condition2만족)

 

 

위의 식을 각각 미분해서 쓰면 아래와 같다.

 

 

Lower triangular matrix 형태 -> triangular matrix(각각의 column이 선형독립)

triangular matrix에서는 determinant가 diagonal element의 곱으로 엄청 쉬워짐!

 

 

이처럼 affine coupling layer는 normaling flow를 구현하기에 완벽해보인다.

하지만 하나의 affine coupling layer의 일부 채널은 변하지 않고 유지가 된다. (1~d차원)

그렇기 때문에 각 layer의 순서를 반대로 하여 모든 입력이 변경될 수 있게 설정가능. (문제!!!!!)

Substep 2. Invertible 1X1 convolution

(shuffle 대체)

 

(b) WaveGlow에 사용되는 샘플들

 

앞서 살펴본 affine layer의 단점이 x1:d가 바뀌지 않는 다는 것이다. 이는 변환을 거쳐도 몇몇 요소가 바뀌지 않는 문제가 생긴다. Invertible 1X1 convolution은 이를 해결하기 위한 과정이 되고 이 논문의 main contribution이 되는 부분이다.  1X1 convolution은 input channel과 output channel수가 같으면 permutation연산의 generalization이다. 이 permutation을 learnable하게 만들어 버린 것. 이 말은 결국 1X1 convolution이 output channel을 input channel과 같게만 해주면, x1:d를 어떻게 잡을 것이냐를 shuffle해주면서 channel을 해치지 않게 된다는 것이다.

2) Multi-scale architecture

이 구조는 squeezing operation을 통해 구현할 수 있다. 이미지를 subsquare를 reshape한다. (4X4X1 ->2X2X4) 이 방법은 spatial size를 채널의 수로 효과적으로 trade하는 것이다.

 

 

그래서 전체적인 과정을 보면, x라는 이미지를 입력값으로 넣고 'squeeze를 통해 공간해상도를 줄이고, flow과정을 K번 반복하고 split을 진행하고 이를 L-1번 반복하는 multi-scale 구조를 띈다. 결론적으로 flowK번을 L번 반복하는 것이 된다.

 

학습을 시켰다면 synthesis는 어떻게?

 

training period동안 학습을 통해 f(x) network의 파라미터들이 학습되었을 것이다. z(latent variable)은 간단한 사전분포로 정의되어있기 때문에, 랜덤하게 하나를 샘플링한다. 랜덤샘플링을 network의 역변환인 f-1(z)를 거치게 되면 x를 generate할 수 있다.

 

결과를 보면 고해상도 이미지로 잘 generate한 것을 확인할 수 있다. condition을 줘서 여러가지로 생성해낼 수 있는데, 요즘 n번방사태도 그렇고, 이미지를 생성해내는 기술이 발전하는 것이 조금 무섭기도 하다.

 

Reference

https://ratsgo.github.io/generative%20model/2018/01/29/NF/

https://medium.com/@sunwoopark/slow-paper-glow-generative-flow-with-invertible-1x1-convolutions-837710116939

https://lilianweng.github.io/lil-log/2018/10/13/flow-based-deep-generative-models.html

https://www.slideshare.net/fukuabca/flow-based-generative-models

https://arxiv.org/pdf/1912.01219.pdf