GAN
임포트
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Dropout, LeakyReLU
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import initializers
import tqdm.notebook
설정
np.random.seed(10)
random_dim = 32
데이터
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train = x_train[y_train < 2]
x_train = (x_train.astype(np.float32) - 127.5)/127.5
x_train = x_train.reshape(-1, 784)
생성자
generator = tf.keras.models.Sequential([
Dense(256, input_dim=random_dim,
kernel_initializer=initializers.RandomNormal(stddev=0.02)),
LeakyReLU(0.2),
Dense(784, activation='tanh')
])
generator.compile(loss='binary_crossentropy',
optimizer=Adam(learning_rate=0.0002, beta_1=0.5))
구분자
discriminator = tf.keras.models.Sequential([
Dense(1024, input_dim=784,
kernel_initializer=initializers.RandomNormal(stddev=0.02)),
LeakyReLU(0.2),
Dropout(0.3),
Dense(1, activation='sigmoid'),
])
discriminator.compile(loss='binary_crossentropy',
optimizer=Adam(learning_rate=0.0002, beta_1=0.5))
GAN
discriminator.trainable = False
gan_input = Input(shape=(random_dim,))
x = generator(gan_input)
gan_output = discriminator(x)
gan = tf.keras.models.Model(inputs=gan_input, outputs=gan_output)
gan.compile(loss='binary_crossentropy',
optimizer=Adam(learning_rate=0.0002, beta_1=0.5))
예시 이미지 생성 함수
def plot_generated_images(epoch, generator, dim=(5, 5)):
examples = dim[0] * dim[1]
noise = np.random.normal(0, 1, size=[examples, random_dim])
generated_images = generator.predict(noise, verbose=0)
generated_images = generated_images.reshape(examples, 28, 28)
plt.figure(figsize=dim)
for i in range(generated_images.shape[0]):
plt.subplot(dim[0], dim[1], i+1)
plt.imshow(generated_images[i], interpolation='nearest', cmap='gray_r')
plt.axis('off')
plt.tight_layout()
plt.savefig(f'gan{epoch:02d}.png')
훈련
epochs = 3
batch_size = 128
batch_count = x_train.shape[0] // batch_size
progress = tqdm.notebook.tqdm(total=epochs * batch_count)
for e in range(epochs):
for _ in range(batch_count):
# 실제 이미지
idx = np.random.randint(0, x_train.shape[0], size=batch_size)
image_batch = x_train[idx]
# 가짜 이미지 생성
noise = np.random.normal(0, 1, size=[batch_size, random_dim]) # 노이즈
generated_images = generator.predict(noise, verbose=0)
# 구분자 훈련 데이터
X = np.concatenate([image_batch, generated_images])
y_dis = np.zeros(2*batch_size)
y_dis[:batch_size] = 0.9 # 실제 = 0.9(label smoothing), 가짜 = 0
# 구분자 훈련
discriminator.trainable = True
discriminator.fit(X, y_dis, batch_size=batch_size, verbose=0)
# 생성자 훈련 데이터
noise = np.random.normal(0, 1, size=[batch_size, random_dim])
y_gen = np.ones(batch_size)
# 생성자 훈련
discriminator.trainable = False
gan.fit(noise, y_gen, batch_size=batch_size, verbose=0)
progress.update(1)
plot_generated_images(e, generator)
progress.close()
0%| | 0/294 [00:00<?, ?it/s]