Loading [MathJax]/jax/output/CommonHTML/jax.js
728x90

 

www.tensorflow.org/tutorials/generative/cvae?hl=ko

 

์ปจ๋ณผ๋ฃจ์…”๋„ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”  |  TensorFlow Core

์ด ๋…ธํŠธ๋ถ์€ MNIST ๋ฐ์ดํ„ฐ์„ธํŠธ์—์„œ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”(VAE, Variational Autoencoder)๋ฅผ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค(1 , 2). VAE๋Š” ์˜คํ† ์ธ์ฝ”๋”์˜ ํ™•๋ฅ ๋ก ์  ํ˜•ํƒœ๋กœ, ๋†’์€ ์ฐจ์›์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์ž‘์€ ํ‘œํ˜„

www.tensorflow.org

 Data load

from IPython import display
import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import PIL
import tensorflow as tf
import tensorflow_probability as tfp
import time

(train_images, _),(test_images, _) = tf.keras.datasets.mnist.load_data()

dim(train_images) = (60000, 28, 28)

[0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253,253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0, 0, 0] ..... X 28 
0~255  ์‚ฌ์ด์˜ ์ˆ˜๋กœ ํ”ฝ์…€์˜ ๊ฐ•๋„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. 

train_images counts : 60000
test_images counts : 10000

def preprocess_images(images):
    images = images.reshape((images.shape[0],28,28,1)) / 255.
    return np.where(images > .5, 1.0, 0.0).astype('float32')
    
train_images = preprocess_images(train_images)
test_images = preprocess_images(test_images)

 preprocess_images๋Š” ํ”ฝ์…€์˜ ๊ฐ•๋„ 0~255์˜ ์ˆ˜๋ฅผ 0~1๋กœ ์ „์ฒ˜๋ฆฌ์‹œํ‚ค๊ณ  0.5 ์ดˆ๊ณผ๋Š” 1๋กœ ์ดํ•˜๋Š” 0์œผ๋กœ ๋งŒ๋“ค๊ณ  float32๋กœ ๋ณ€ํ˜•ํ•œ๋‹ค. 

train_dataset = (tf.data.Dataset.from_tensor_slices(train_images).shuffle(train_size).batch(batch_size))
test_datasets = (tf.data.Dataset.from_tensor_slices(test_images).shuffle(test_size).batch(batch_size))

tf.data.Dataset์„ ์ด์šฉํ•ด ๋ฐ์ดํ„ฐ ๋ฐฐ์น˜์™€ ์…”ํ”Œํ•˜๊ธฐ

ConvNet์„ ์ด์šฉํ•œ, VAE CVAE model

class CVAE(tf.keras.Model):
    """Convolutional variational autoencoder"""
    def __init__(self,latent_dim):
        super(CVAE,self).__init__()
        self.latent_dim = latent_dim

CVAE ๋ชจ๋ธ
latent_dim : generator์— ์‚ฌ์šฉํ•  input node์˜ ์ˆ˜

	self.encoder = tf.keras.Sequential(
  	          [
 	               tf.keras.layers.InputLayer(input_shape=(28,28,1)),
	               tf.keras.layers.Conv2D(filters=32,kernel_size=3,strides=(2,2),activation='relu'),
 	               tf.keras.layers.Conv2D(filters=64,kernel_size=3,strides=(2,2),activation='relu'),
	               tf.keras.layers.Flatten(),
 	               tf.keras.layers.Dense(latent_dim+latent_dim),
  	          ]
  	      ),

encoder 
Tensorflow ์˜ˆ์ œ์—์„œ ๊ตฌํ˜„์„ ๋‹จ์ˆœํ™” ํ•˜๊ธฐ ์œ„ํ•ด Sequential์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

InputLayer: image_dim (28,28,1)
Conv2D:
          filters: ๋ช‡ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ• ์ง€, ์ถœ๋ ฅ ๋ชจ์–‘์˜ depth๋ฅผ ์ •ํ•จ
          kernel_size: ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์œˆ๋„์šฐ์˜ ํฌ๊ธฐ
          strides: ์œˆ๋„์šฐ๊ฐ€ ์›€์ง์ผ ๊ฐ„๊ฒฉ
          activation: ์—ฐ์‚ฐ ์ข…๋ฅ˜ 'relu'
depth: 32  ->  64 
Flatten: ๋ฐฐ์—ด flat์œผ๋กœ ___________ 
Dense: ์ถœ๋ ฅ ๋‰ด๋Ÿฐ ์ˆ˜ latent_dim + latent_dim

https://davinci-ai.tistory.com/29

        self.decoder = tf.keras.Sequential(
            [
                tf.keras.layers.InputLayer(input_shape=(latent_dim,)),
                tf.keras.layers.Dense(units=7*7*32,activation=tf.nn.relu),
                tf.keras.layers.Reshape(target_shape=(7,7,32)),
                tf.keras.layers.Conv2DTranspose(filters=64,kernel_size=3,strides=2,padding='same'),
                tf.keras.layers.Conv2DTranspose(filters=32,kernel_size=3,strides=2,padding='same'),
                tf.keras.layers.Conv2DTranspose(filters=1,kernel_size=3,strides=1,padding='same')
            ]
        )

 decoder
InputLayer: latent_dim ํ˜„์žฌ input node์˜ ์ˆ˜
Dense: units ์ถœ๋ ฅ ์ˆ˜ 7*7*32, ์—ฐ์‚ฐ 'relu' ์ถœ๋ ฅ ๋‰ด๋Ÿฐ์ˆ˜ 
Reshape:  7*7*32->(7,7,32)
Conv2DTranspose:
          filters: ๋ช‡ ๊ฐœ์˜ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ํ•„ํ„ฐ๋ฅผ ์‚ฌ์šฉํ• ์ง€, ์ถœ๋ ฅ ๋ชจ์–‘์˜ depth๋ฅผ ์ •ํ•จ
          kernel_size: ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ์œˆ๋„์šฐ์˜ ํฌ๊ธฐ
          strides: ์œˆ๋„์šฐ๊ฐ€ ์›€์ง์ผ ๊ฐ„๊ฒฉ
          padding: 'same' ์ถœ๋ ฅ ํฌ๊ธฐ ๋™์ผ
Conv2DTranspose๋กœ ๋ณต์›
depth: 64 - > 32 -> 1

Conv2DTranspose

        def sample(self,eps=None):
            if eps is None:
                eps = tf.random.normal(shape=(100,self.latent_dim))
            return self.decode(eps,apply_sigmoid=True)

z=ฮผ+ฯƒโŠ™ฯต

sample ํ•จ์ˆ˜๋Š” epsepson๋ฅผ ํ†ตํ•ด ์ธ์ฝ”๋”์˜ ๊ทธ๋ž˜๋””์–ธํŠธ๋ฅผ ์—ญ์ „ํŒŒํ•˜๋ฉด์„œ ๋ฌด์งˆ์„œ๋„๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. 

        def encode(self,x):
            mean, logvar = tf.split(self.encoder(x),num_or_size_splits=2,axis=1)
            return mean, logvar

encode
num_or_size_splits = 2 : integer, then value is split along the dimension axis into num_or_size_splits smaller tensors.
๋” ์ž‘์€ํ…์„œ๋กœ๋‚˜๋ˆˆ๋‹ค.

mean = ฮผ
logva = ฯƒ

        def reparameterize(self,mean,logvar):
            eps = tf.random.normal(shape=mean.shape)

reparameterize ๋ฌด์ž‘์œ„ ์ƒ˜ํ”Œ๋ง

        def decode(self,z,apply_sigmoid=False):
            logits = self.decoder(z)
            if apply_sigmoid:
                probs = tf.sigmoid(logits)
                return probs
            return logits

decode ๋žœ๋ค ์ƒ˜ํ”Œ๋ง sigmoid -> logits

optimizer = tf.keras.optimizers.Adam(1e-4)

def log_normal_pdf(sample, mean, logvar, raxis=1):
    log2pi = tf.math.log(2.*np.pi)
    return tf.reduce_sum(
        -.5 * ((sample-mean)**2.*tf.exp(-logvar)+logvar+log2pi),
        axis=raxis)
        
def compute_loss(model,x):
    mean, logvar = model.encode(x)
    z = model.reparameterize(mean, logvar)
    x_logit = model.decode(z)
    cross_ent = tf.nn.sigmoid_cross_entropy_with_logits(logits=x_logit,labels=x)
    logpx_z = -tf.reduce_sum(cross_ent,axis=[1,2,3])
    logpz = log_normal_pdf(z,0.,0.)
    logqz_x = log_normal_pdf(z,mean,logvar)
    return -tf.reduce_mean(logpx_z+logpz-logqz_x)
 
 
def train_step(model,x,optimizer):
    with tf.GradientTape() as tape:
        loss = compute_loss(model,x)
    gradients = tape.gradient(loss,model.trainable_variables)
    optimizer.apply_gradients(zip(gradients,model.trainable_variables))

optimizer ์„ ์–ธ
log_normal_pdf
Erec=(โˆ’xijlogyijโˆ’(1โˆ’xij)log(1โˆ’yij))
compute_loss
loss ๊ณ„์‚ฐ
train_step
ํ•™์Šต

epochs = 10
latent_dim = 2
num_examples_to_generate = 16
random_vector_for_generation = tf.random.normal(
    shape=[num_examples_to_generate,latent_dim])
model = CVAE(latent_dim)

random_vector_for_generation 
(16,2) random dim ์ƒ์„ฑ
model
CVAE ๋ชจ๋ธ ์„ ์–ธ

def generate_and_save_images(model, epoch, test_sample):
    mean, logvar = model.encode(test_sample)
    z = model.reparameterize(mean,logvar)
    predictions = model.sample(z)
    fig = plt.figure(figsize=(4,4))
    for i in range(predictions.shape[0]):
        plt.subplot(4,4,i+1)
        plt.imshow(predictions[i,:,:,0],cmap='gray')
        plt.axis('off')
        
    plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
    plt.show()

generate_and_save_images
์ด๋ฏธ์ง€ ์ €์žฅ ๋ฐ ์ƒ์„ฑ

assert batch_size >= num_examples_to_generate
for test_batch in test_datasets.take(1):
    test_sample = test_batch[0:num_examples_to_generate,:,:,:] #  TensorShape([16, 28, 28, 1])

 

assert ํ”„๋กœ๊ทธ๋žจ ๋‚ด๋ถ€์˜ ์ง„๋‹จ 
batch_size(32)๊ฐ€ num_examples_to_genrate(16) ๋ณด๋‹ค ํฐ ๊ฒƒ์„ ํ™•์ธ(์ž‘์„ ๊ฒฝ์šฐ ์—๋Ÿฌ)

generate_and_save_images(model, 0, test_sample)

for epoch in range(1, epochs + 1):
  start_time = time.time()
  for train_x in train_dataset:
    train_step(model, train_x, optimizer)
  end_time = time.time()

  loss = tf.keras.metrics.Mean()
  for test_x in test_dataset:
    loss(compute_loss(model, test_x))
  elbo = -loss.result()
  display.clear_output(wait=False)
  print('Epoch: {}, Test set ELBO: {}, time elapse for current epoch: {}'
        .format(epoch, elbo, end_time - start_time))
  generate_and_save_images(model, epoch, test_sample)

์ƒ์„ฑ ํ›„ ํ•™์Šต  # Epoch: 10, Test set ELBO: -156.81210327148438, time elapse for current epoch: 4.33378791809082

def display_image(epoch_no):
  return PIL.Image.open('image_at_epoch_{:04d}.png'.format(epoch_no))

 

plt.imshow(display_image(epoch))
plt.axis('off') 
anim_file = 'cvae.gif'

with imageio.get_writer(anim_file, mode='I') as writer:
  filenames = glob.glob('image*.png')
  filenames = sorted(filenames)
  for filename in filenames:
    image = imageio.imread(filename)
    writer.append_data(image)
  image = imageio.imread(filename)
  writer.append_data(image)

import tensorflow_docs.vis.embed as embed
embed.embed_file(anim_file)

www.tensorflow.org/tutorials/generative/cvae?hl=ko ์ถœ์ฒ˜

 

 

์ปจ๋ณผ๋ฃจ์…”๋„ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”  |  TensorFlow Core

์ด ๋…ธํŠธ๋ถ์€ MNIST ๋ฐ์ดํ„ฐ์„ธํŠธ์—์„œ ๋ณ€์ดํ˜• ์˜คํ† ์ธ์ฝ”๋”(VAE, Variational Autoencoder)๋ฅผ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค(1 , 2). VAE๋Š” ์˜คํ† ์ธ์ฝ”๋”์˜ ํ™•๋ฅ ๋ก ์  ํ˜•ํƒœ๋กœ, ๋†’์€ ์ฐจ์›์˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์ž‘์€ ํ‘œํ˜„

www.tensorflow.org

 

๋ฐ˜์‘ํ˜•
๋‹คํ–ˆ๋‹ค