변형 오토인코더를 위한 네트워크를 생성합니다.
코드 13-10 변형 오토인코더 네트워크 생성
class VAE(tf.keras.Model):
def __init__(self, **kwargs):
super(VAE, self).__init__()
self.__dict__.update(kwargs)
self.enc = tf.keras.Sequential(self.enc)
self.dec = tf.keras.Sequential(self.dec)
def encode(self, x):
mu, sigma = tf.split(self.enc(x), num_or_size_splits=2, axis=1)
return ds.MultivariateNormalDiag(loc=mu, scale_diag=sigma) ------ 인코더에서 평균과 표준편차를 정의하고 z의 평균과 분산을 모수로 하는 정규 분포 생성
def reparameterize(self, mean, logvar):
epsilon = tf.random.normal(shape=mean.shape)
return epsilon * tf.exp(logvar * 0.5) + mean ------ ①
def reconstruct(self, x):
mu, _ = tf.split(self.enc(x), num_or_size_splits=2, axis=1)
return self.decode(mu) ------ 입력 데이터를 출력 데이터로 재구성
def decode(self, z):
return self.dec(z) ------ 인코더가 만든 z를 받아 입력 데이터(x)를 복원
def loss_function(self, x):
q_z = self.encode(x)
z = q_z.sample()
x_recon = self.decode(z)
p_z = ds.MultivariateNormalDiag(
loc=[0.] * z.shape[-1], scale_diag=[1.] * z.shape[-1]
)
kl_div = ds.kl_divergence(q_z, p_z)
latent_loss = tf.reduce_mean(tf.maximum(kl_div, 0))
recon_loss = tf.reduce_mean(tf.reduce_sum(tf.math.square(x-x_recon), axis=0))
return recon_loss, latent_loss ------ ②
def gradients(self, x):
with tf.GradientTape() as tape:
loss = self.loss_function(x)
return tape.gradient(loss, self.trainable_variables) ------ ③
@tf.function ------ 파이썬 제어문을 텐서플로에서 자동으로 컴파일
def train(self, train_x):
gradients = self.gradients(train_x)
self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))