www.tensorflow.org/tutorials/generative/cvae?hl=ko
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()
[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
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
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 = \mu + \sigma \odot \epsilon$
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 = $\mu$
logva = $\sigma$
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
$E_{rec} = (-x_{ij}\log{y_{ij}}-(1-x_{ij})\log{(1-y_{ij}}))$
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 ์ถ์ฒ
'๐พ Deep Learning' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Transformer] Position-wise Feed-Forward Networks (2) (0) | 2021.02.20 |
---|---|
[Transformer] Self-Attension ์ ํ ์ดํ ์ (0) (0) | 2021.02.19 |
Tensorflow Initializer ์ด๊ธฐํ ์ข ๋ฅ (0) | 2021.02.18 |
VAE(Variational Autoencoder) (2) (0) | 2021.02.18 |
VAE(Variational Autoencoder) (1) (0) | 2021.02.18 |