Commit d58fd255 authored by Nicolas Pernoud's avatar Nicolas Pernoud
Browse files

feat : added gans with convolution and control

parent 9ba50e07
# A simple GAN
import matplotlib.pyplot as plt
import numpy as np
......
# A more evoluted GAN with convolution
import matplotlib.pyplot as plt
import numpy as np
from keras.layers import Dense, Flatten, Reshape, Activation, BatchNormalization
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.models import Sequential
from keras.datasets import fashion_mnist
from keras.optimizers import Adam
z_dim = 100
img_lines = 28
img_columns = 28
img_channels = 1
img_shape = (img_lines, img_columns, img_channels)
def build_generator_conv(z_dim):
model = Sequential()
# Adapt according to img_lines and img_columns (7*7*256 must be multiple of img_lines*img_colums)
model.add(Dense(7*7*256, input_dim=z_dim))
model.add(Reshape((7, 7, 256)))
model.add(Conv2DTranspose(128, kernel_size=3, strides=2, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.01))
model.add(Conv2DTranspose(64, kernel_size=3, strides=1, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.01))
model.add(Conv2DTranspose(1, kernel_size=3, strides=2, padding='same'))
model.add(Activation('tanh'))
return model
def build_discriminator_conv(img_shape):
model = Sequential()
# Get image signature with convolutional neural network
model.add(Conv2D(32, kernel_size=3, strides=2,
input_shape=img_shape, padding='same'))
model.add(LeakyReLU(alpha=0.001))
model.add(Conv2D(64, kernel_size=3, strides=2,
input_shape=img_shape, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.001))
model.add(Conv2D(128, kernel_size=3, strides=2,
input_shape=img_shape, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.001))
# Work out if image is of required shape with conventionnal neural network
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
return model
def build_gan(generator, discriminator):
model = Sequential()
model.add(generator)
model.add(discriminator)
discriminator.trainable = False
model.compile(loss='binary_crossentropy', optimizer=Adam())
return model
discriminator = build_discriminator_conv(img_shape)
discriminator.compile(loss='binary_crossentropy',
optimizer=Adam(), metrics=['accuracy'])
generator = build_generator_conv(z_dim)
gan = build_gan(generator, discriminator)
def sample_images(generator, iter, img_per_l=4, img_per_c=4):
z = np.random.normal(0, 1, (img_per_l*img_per_c, z_dim))
img_gen = generator.predict(z)
img_gen = 0.5*img_gen+0.5
_, ax = plt.subplots(img_per_l, img_per_c, figsize=(
4, 4), sharey=True, sharex=True)
cpt = 0
for i in range(img_per_l):
for j in range(img_per_c):
ax[i, j].imshow(img_gen[cpt, :, :, 0], cmap='gray')
ax[i, j].axis('off')
cpt += 1
plt.savefig("test_"+f'{iter:05d}'+".png", dpi=150)
def train(iterations, batch_size, sample_interval):
losses = []
accuracies = []
iteration_checkpoints = []
((X_train, _), (_, _)) = fashion_mnist.load_data()
X_train = X_train/127.5-1
X_train = np.expand_dims(X_train, axis=3)
real = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))
for iteration in range(iterations):
idx = np.random.randint(0, X_train.shape[0], batch_size)
imgs = X_train[idx]
z = np.random.normal(0, 1, (batch_size, z_dim))
gen_imgs = generator.predict(z)
d_loss_real = discriminator.train_on_batch(imgs, real)
d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)
d_loss, accuracy = 0.5*np.add(d_loss_real, d_loss_fake)
z = np.random.normal(0, 1, (batch_size, z_dim))
gen_imgs = generator.predict(z)
g_loss = gan.train_on_batch(z, real)
if (iteration+1) % sample_interval == 0 or iteration == 0:
losses.append((d_loss, g_loss))
accuracies.append((100*accuracy))
iteration_checkpoints.append(iteration+1)
status = 'iteration: {:} [D loss: {:}, acc.: {:2.2%}] [G loss: {:}]'.format(
iteration+1, d_loss, accuracy, g_loss)
print(status)
sample_images(generator, iteration+1)
iterations = 20000
batch_size = 128
sample_interval = 1000
train(iterations, batch_size, sample_interval)
# A more evoluted GAN with convolution and control over the produced image
import matplotlib.pyplot as plt
import numpy as np
from keras.layers import Dense, Flatten, Reshape, Activation, BatchNormalization, Dropout, Input, Embedding, Multiply, Concatenate
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import Conv2D, Conv2DTranspose
from keras.models import Sequential, Model
from keras.datasets import fashion_mnist
from keras.optimizers import Adam
z_dim = 100
img_lines = 28
img_columns = 28
img_channels = 1
img_shape = (img_lines, img_columns, img_channels)
nb_classes = 10
def build_generator_conv(z_dim):
model = Sequential()
# Adapt according to img_lines and img_columns (7*7*256 must be multiple of img_lines*img_colums)
model.add(Dense(7*7*256, input_dim=z_dim))
model.add(Reshape((7, 7, 256)))
model.add(Conv2DTranspose(128, kernel_size=3, strides=2, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.01))
model.add(Conv2DTranspose(64, kernel_size=3, strides=1, padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.01))
model.add(Conv2DTranspose(1, kernel_size=3, strides=2, padding='same'))
model.add(Activation('tanh'))
return model
def build_generator_cond(z_dim):
z = Input(shape=(z_dim,))
input_class = Input(shape=(1,), dtype='int32')
class_embedding = Embedding(nb_classes, z_dim, input_length=1)(input_class)
class_embedding = Flatten()(class_embedding)
Embedded_class_vector = Multiply()([z, class_embedding])
generator = build_generator_conv(z_dim)
img_cond = generator(Embedded_class_vector)
return Model([z, input_class], img_cond)
def build_discriminator_conv(img_shape):
model = Sequential()
# Get image signature with convolutional neural network
model.add(Conv2D(32, kernel_size=3, strides=2,
input_shape=(img_shape[0], img_shape[1], img_shape[2]+1), padding='same'))
model.add(LeakyReLU(alpha=0.001))
model.add(Conv2D(64, kernel_size=3, strides=2,
input_shape=(img_shape[0], img_shape[1], img_shape[2]+1), padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.001))
model.add(Conv2D(128, kernel_size=3, strides=2,
input_shape=(img_shape[0], img_shape[1], img_shape[2]+1), padding='same'))
model.add(BatchNormalization())
model.add(LeakyReLU(alpha=0.001))
# Work out if image is of required shape with conventionnal neural network
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
return model
def build_discriminator_cond(img_shape):
img = Input(shape=img_shape)
input_class = Input(shape=(1,), dtype='int32')
class_embedding = Embedding(nb_classes, np.prod(
img_shape), input_length=1)(input_class)
class_embedding = Flatten()(class_embedding)
class_embedding = Reshape(img_shape)(class_embedding)
embedded_class_tensor = Concatenate(axis=-1)([img, class_embedding])
discriminator = build_discriminator_conv(img_shape)
output_class = discriminator(embedded_class_tensor)
return Model([img, input_class], output_class)
def build_gan_cond(generator, discriminator):
z = Input(shape=(z_dim,))
input_class = Input(shape=(1,))
img = generator([z, input_class])
output_class = discriminator([img, input_class])
model = Model([z, input_class], output_class)
discriminator.trainable = False
model.compile(loss='binary_crossentropy', optimizer=Adam())
return model
discriminator = build_discriminator_cond(img_shape)
discriminator.compile(loss='binary_crossentropy',
optimizer=Adam(), metrics=['accuracy'])
generator = build_generator_cond(z_dim)
gan = build_gan_cond(generator, discriminator)
def sample_images(generator, iter, img_per_l=4, img_per_c=4):
z = np.random.normal(0, 1, (img_per_l*img_per_c, z_dim))
labels = np.random.randint(
0, nb_classes, img_per_l*img_per_c).reshape(-1, 1)
img_gen = generator.predict([z, labels])
img_gen = 0.5*img_gen+0.5
_, ax = plt.subplots(img_per_l, img_per_c, figsize=(
4, 4), sharey=True, sharex=True)
cpt = 0
for i in range(img_per_l):
for j in range(img_per_c):
ax[i, j].imshow(img_gen[cpt, :, :, 0], cmap='gray')
ax[i, j].axis('off')
cpt += 1
plt.savefig("test_"+f'{iter:05d}'+".png", dpi=150)
def train(iterations, batch_size, sample_interval):
losses = []
iteration_checkpoints = []
((X_train, Y_train), (_, _)) = fashion_mnist.load_data()
X_train = X_train/127.5-1
X_train = np.expand_dims(X_train, axis=3)
real = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))
for iteration in range(iterations):
idx = np.random.randint(0, X_train.shape[0], batch_size)
imgs = X_train[idx]
labels = Y_train[idx]
z = np.random.normal(0, 1, (batch_size, z_dim))
gen_imgs = generator.predict([z, labels])
d_loss_real = discriminator.train_on_batch([imgs, labels], real)
d_loss_fake = discriminator.train_on_batch([gen_imgs, labels], fake)
d_loss = 0.5*np.add(d_loss_real, d_loss_fake)
z = np.random.normal(0, 1, (batch_size, z_dim))
label = np.random.randint(0, nb_classes, batch_size).reshape(-1, 1)
gen_imgs = generator.predict([z, label])
g_loss = gan.train_on_batch([z, label], real)
if (iteration+1) % sample_interval == 0 or iteration == 0:
losses.append((d_loss, g_loss))
iteration_checkpoints.append(iteration+1)
status = 'iteration: {:} [D loss: {:}] [G loss: {:}]'.format(
iteration+1, d_loss, g_loss)
print(status)
sample_images(generator, iteration+1)
iterations = 20000
batch_size = 128
sample_interval = 1000
train(iterations, batch_size, sample_interval)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment