728x90
반응형
인코더
- AE는 각 이미지가 잠재 공간의 한 포인트에 직접 매핑된다.
- VAE는 각 이미지가 잠재 공간에 있는 포인트 주변의 다변수 정규 분포(multivariate normal distribution)에 매핑된다.
정규 분포
- 종 모양의 곡선을 가진 확률 분포
- 1차원일 때는 평균(mean)과 분산(variance) 2개의 변수로 정의된다.
- 표준 편차는 분산의 제곱근이다.
VAE
- VAE는 잠재 공간의 차원 사이에는 어떤 상관관계가 없다고 가정한다.
- 공분산 행렬은 대각 행렬이 된다.
- 인코더는 입력 이미지를 받아 잠재 공간의 다변수 정규 분포를 정의하는 2개의 벡터 mu와 loag_var로 인코딩한다.
VAE의 인코더
# VAE 인코더
encoder_input = Input(shape=self.input_dim, name='encoder_input')
x = encoder_input
for i in range(self.n_layers_encoder):
conv_layer = Conv2D(
filters = self.encoder_conv_filters[i]
, kernel_size = self.encoder_conv_kernel_size[i]
, strides = self.encoder_conv_strides[i]
, padding = 'same'
, name = 'encoder_conv_' + str(i)
)
x = conv_layer(x)
if self.use_batch_norm:
x = BatchNormalization()(x)
x = LeakyReLU()(x)
if self.use_dropout:
x = Dropout(rate = 0.25)(x)
shape_before_flattening = K.int_shape(x)[1:]
x = Flatten()(x)
self.mu = Dense(self.z_dim, name='mu')(x) #1
self.log_var = Dense(self.z_dim, name='log_var')(x)
encoder_mu_log_var = Model(encoder_input, (self.mu, self.log_var)) #2
def sampling(args):
mu, log_var = args
epsilon = K.random_normal(shape=K.shape(mu), mean=0., stddev=1.)
return mu + K.exp(log_var / 2) * epsilon
encoder_output = Lambda(sampling, name='encoder_output')([self.mu, self.log_var]) #3
encoder = Model(encoder_input, encoder_output) #4
- Flatten 층을 바로 2차원 잠재 공간에 연결하지 않고 mu 층과 log_var 층에 연결한다.
- 케라스 모델은 이미지가 입력되면 mu와 log_var의 값을 출력한다.
- Lambda 층이 잠재 공간에서 mu와 log_var로 정의되는 정규분포로부터 포인트 z를 샘플링한다.
- 인코더를 정의하는 케라스 모델을 만든다.
VAE 인코더 구조
vae.encoder.summary()
손실 함수
- VAE는 재구성 손실에 추가적으로 쿨백-라이블러 발산(Kullback-Leibler divergence)(KL 발산)을 사용한다.
- KL 발산 항 추가시 잠재 공간에서 포인트를 선택할 때 사용할 수 잇는 잘 정의된 분포(표준 정규 분포)를 가지게 된다.
- 이 항이 모든 인코딩된 분포를 표준 정규 분포에 가깝게 되도록 강제한다.
- 이로 인해 포인트 군집(cluster)사이에 큰 간격이 생길 가능성이 적다.
손실 함수에 KL 발산 추가하기
## 컴파일
def vae_r_loss(y_true, y_pred):
r_loss = K.mean(K.square(y_true - y_pred), axis = [1,2,3])
return r_loss_factor * r_loss
def vae_kl_loss(y_true, y_pred):
kl_loss = -0.5 * K.sum(1 + self.log_var - K.square(self.mu) - K.exp(self.log_var), axis = 1)
return kl_loss
def vae_loss(y_true, y_pred):
r_loss = vae_r_loss(y_true, y_pred)
kl_loss = vae_kl_loss(y_true, y_pred)
return r_loss + kl_loss
optimizer = Adam(lr=learning_rate)
self.model.compile(optimizer=optimizer, loss = vae_loss, metrics = [vae_r_loss, vae_kl_loss])
http://www.yes24.com/Product/Goods/81538614?OzSrank=1
728x90
반응형
최근댓글