GANs vs. Autoencoders: Comparison of Deep Generative Models

A collection of high-quality anime faces.

Contribute to Mckinsey666/Anime-Face-Dataset development by creating an…github.

comDC-GAN on Anime DatasetThe first thing we need to do is create anime directory and download the data.

This can either be done from the link above or directly from Amazon Web Services (if this way of accessing the data is still available).

# Create anime directory and download from AWSimport zipfile!mkdir anime-faces && wget https://s3.

amazonaws.

com/gec-harvard-dl2-hw2-data/datasets/anime-faces.

zipwith zipfile.

ZipFile("anime-faces.

zip","r") as anime_ref: anime_ref.

extractall("anime-faces/")It is always good practice to check the data before moving ahead, so we do this now.

from skimage import ioimport matplotlib.

pyplot as pltfilePath='anime-faces/data/'imgSets=[]for i in range(1,20001): imgName=filePath+str(i)+'.

png' imgSets.

append(io.

imread(imgName))plt.

imshow(imgSets[1234])plt.

axis('off')plt.

show()We now create and compile our DC-GAN model.

# Create and compile a DC-GAN modelfrom keras.

models import Sequential, Modelfrom keras.

layers import Input, Dense, Dropout, Activation, Flatten, LeakyReLU, BatchNormalization, Conv2DTranspose, Conv2D, Reshapefrom keras.

layers.

advanced_activations import LeakyReLUfrom keras.

layers.

convolutional import UpSampling2Dfrom keras.

optimizers import Adam, RMSprop,SGDfrom keras.

initializers import RandomNormalimport numpy as npimport matplotlib.

pyplot as pltimport os, globfrom PIL import Imagefrom tqdm import tqdm_notebookimage_shape = (64, 64, 3)#noise_shape = (100,)Noise_dim = 128img_rows = 64img_cols = 64channels = 3def generator_model(latent_dim=100, leaky_alpha=0.

2): model = Sequential() # layer1 (None,500)>>(None,128*16*16) model.

add(Dense(128 * 16 * 16, activation="relu", input_shape=(Noise_dim,))) # (None,16*16*128)>>(None,16,16,128) model.

add(Reshape((16, 16, 128))) # (None,16,16,128)>>(None,32,32,128) model.

add(UpSampling2D()) model.

add(Conv2D(256, kernel_size=3, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(Activation("relu")) #(None,32,32,128)>>(None,64,64,128) model.

add(UpSampling2D()) # (None,64,64,128)>>(None,64,64,64) model.

add(Conv2D(128, kernel_size=3, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(Activation("relu")) # (None,64,64,128)>>(None,64,64,32) model.

add(Conv2D(32, kernel_size=3, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(Activation("relu")) # (None,64,64,32)>>(None,64,64,3) model.

add(Conv2D(channels, kernel_size=3, padding="same")) model.

add(Activation("tanh")) model.

summary() model.

compile(loss='binary_crossentropy', optimizer=Adam(lr=0.

0001, beta_1=0.

5), metrics=['accuracy']) return modeldef discriminator_model(leaky_alpha=0.

2, dropRate=0.

3): model = Sequential() # layer1 (None,64,64,3)>>(None,32,32,32) model.

add(Conv2D(32, kernel_size=3, strides=2, input_shape=image_shape, padding="same")) model.

add(LeakyReLU(alpha=leaky_alpha)) model.

add(Dropout(dropRate)) # layer2 (None,32,32,32)>>(None,16,16,64) model.

add(Conv2D(64, kernel_size=3, strides=2, padding="same")) # model.

add(ZeroPadding2D(padding=((0, 1), (0, 1)))) model.

add(BatchNormalization(momentum=0.

8)) model.

add(LeakyReLU(alpha=leaky_alpha)) model.

add(Dropout(dropRate)) # (None,16,16,64)>>(None,8,8,128) model.

add(Conv2D(128, kernel_size=3, strides=2, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(LeakyReLU(alpha=0.

2)) model.

add(Dropout(dropRate)) # (None,8,8,128)>>(None,8,8,256) model.

add(Conv2D(256, kernel_size=3, strides=1, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(LeakyReLU(alpha=0.

2)) model.

add(Dropout(dropRate)) # (None,8,8,256)>>(None,8,8,64) model.

add(Conv2D(64, kernel_size=3, strides=1, padding="same")) model.

add(BatchNormalization(momentum=0.

8)) model.

add(LeakyReLU(alpha=0.

2)) model.

add(Dropout(dropRate)) # (None,8,8,64) model.

add(Flatten()) model.

add(Dense(1, activation='sigmoid')) model.

summary() sgd=SGD(lr=0.

0002) model.

compile(loss='binary_crossentropy', optimizer=Adam(lr=0.

0001, beta_1=0.

5), metrics=['accuracy']) return modeldef DCGAN(sample_size=Noise_dim): # generator g = generator_model(sample_size, 0.

2) # discriminator d = discriminator_model(0.

2) d.

trainable = False # GAN gan = Sequential([g, d]) sgd=SGD() gan.

compile(optimizer=Adam(lr=0.

0001, beta_1=0.

5), loss='binary_crossentropy') return gan, g, ddef get_image(image_path, width, height, mode): image = Image.

open(image_path) #print(image.

size) return np.

array(image.

convert(mode))def get_batch(image_files, width, height, mode): data_batch = np.

array([get_image(sample_file, width, height, mode) for sample_file in image_files]) return data_batchdef show_imgs(generator,epoch): row=3 col = 5 noise = np.

random.

normal(0, 1, (row * col, Noise_dim)) gen_imgs = generator.

predict(noise) # Rescale images 0 – 1 gen_imgs = 0.

5 * gen_imgs + 0.

5 fig, axs = plt.

subplots(row, col) #fig.

suptitle("DCGAN: Generated digits", fontsize=12) cnt = 0 for i in range(row): for j in range(col): axs[i, j].

imshow(gen_imgs[cnt, :, :, :]) axs[i, j].

axis('off') cnt += 1 #plt.

close() plt.

show()We can now train the model on the Anime dataset.

We will do this in two different ways, the first will involve training the discriminator and generator with a 1:1 proportion of training times.

# Training the discriminator and generator with the 1:1 proportion of training timesdef train(epochs=30, batchSize=128): filePath = r'anime-faces/data/' X_train = get_batch(glob.

glob(os.

path.

join(filePath, '*.

png'))[:20000], 64, 64, 'RGB') X_train = (X_train.

astype(np.

float32) – 127.

5) / 127.

5 halfSize = int(batchSize / 2) batchCount=int(len(X_train)/batchSize) dLossReal = [] dLossFake = [] gLossLogs = [] gan, generator, discriminator = DCGAN(Noise_dim) for e in range(epochs): for i in tqdm_notebook(range(batchCount)): index = np.

random.

randint(0, X_train.

shape[0], halfSize) images = X_train[index] noise = np.

random.

normal(0, 1, (halfSize, Noise_dim)) genImages = generator.

predict(noise) # one-sided labels discriminator.

trainable = True dLossR = discriminator.

train_on_batch(images, np.

ones([halfSize, 1])) dLossF = discriminator.

train_on_batch(genImages, np.

zeros([halfSize, 1])) dLoss = np.

add(dLossF, dLossR) * 0.

5 discriminator.

trainable = False noise = np.

random.

normal(0, 1, (batchSize, Noise_dim)) gLoss = gan.

train_on_batch(noise, np.

ones([batchSize, 1])) dLossReal.

append([e, dLoss[0]]) dLossFake.

append([e, dLoss[1]]) gLossLogs.

append([e, gLoss]) dLossRealArr = np.

array(dLossReal) dLossFakeArr = np.

array(dLossFake) gLossLogsArr = np.

array(gLossLogs) # At the end of training plot the losses vs epochs show_imgs(generator, e) plt.

plot(dLossRealArr[:, 0], dLossRealArr[:, 1], label="Discriminator Loss – Real") plt.

plot(dLossFakeArr[:, 0], dLossFakeArr[:, 1], label="Discriminator Loss – Fake") plt.

plot(gLossLogsArr[:, 0], gLossLogsArr[:, 1], label="Generator Loss") plt.

xlabel('Epochs') plt.

ylabel('Loss') plt.

legend() plt.

title('GAN') plt.

grid(True) plt.

show() return gan, generator, discriminatorGAN,Generator,Discriminator=train(epochs=20, batchSize=128) train(epochs=1000, batchSize=128, plotInternal=200)The output will now start printing a series of anime characters.

They are very grainy at first, and over time gradually become more and more pronounced.

We will also get a plot of our generator and discriminator loss functions.

Now we will do the same but with different training times for the discriminator and generator to see what the effect has been.

Before moving forward, it is good to save the weights of the model somewhere so that you do not need to run the entire training again, and can instead just load the weights into the network.

To save the weights:discriminator.

save_weights('/content/gdrive/My Drive/discriminator_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')gan.

save_weights('/content/gdrive/My Drive/gan_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')generator.

save_weights('/content/gdrive/My Drive/generator_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')To load the weights:discriminator.

load_weights('/content/gdrive/My Drive/discriminator_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')gan.

load_weights('/content/gdrive/My Drive/gan_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')generator.

load_weights('/content/gdrive/My Drive/generator_DCGAN_lr0.

0001_deepgenerator+proportion2.

h5')Now we move onto the second network implementation without worrying about saving over our previous network.

# Train the discriminator and generator separately and with different training timesdef train(epochs=300, batchSize=128, plotInternal=50): gLoss = 1 filePath = r'anime-faces/data/' X_train = get_batch(glob.

glob(os.

path.

join(filePath,'*.

png'))[:20000],64,64,'RGB') X_train=(X_train.

astype(np.

float32)-127.

5)/127.

5 halfSize= int (batchSize/2) dLossReal=[] dLossFake=[] gLossLogs=[] for e in range(epochs): index=np.

random.

randint(0,X_train.

shape[0],halfSize) images=X_train[index] noise=np.

random.

normal(0,1,(halfSize,Noise_dim)) genImages=generator.

predict(noise) if e < int(epochs*0.

5): #one-sided labels discriminator.

trainable=True dLossR=discriminator.

train_on_batch(images,np.

ones([halfSize,1])) dLossF=discriminator.

train_on_batch(genImages,np.

zeros([halfSize,1])) dLoss=np.

add(dLossF,dLossR)*0.

5 discriminator.

trainable=False cnt = e while cnt > 3: cnt = cnt – 4 if cnt == 0: noise=np.

random.

normal(0,1,(batchSize,Noise_dim)) gLoss=gan.

train_on_batch(noise,np.

ones([batchSize,1])) elif e>= int(epochs*0.

5) : cnt = e while cnt > 3: cnt = cnt – 4 if cnt == 0: #one-sided labels discriminator.

trainable=True dLossR=discriminator.

train_on_batch(images,np.

ones([halfSize,1])) dLossF=discriminator.

train_on_batch(genImages,np.

zeros([halfSize,1])) dLoss=np.

add(dLossF,dLossR)*0.

5 discriminator.

trainable=False noise=np.

random.

normal(0,1,(batchSize,Noise_dim)) gLoss=gan.

train_on_batch(noise,np.

ones([batchSize,1])) if e % 20 == 0: print("epoch: %d [D loss: %f, acc.

: %.

2f%%] [G loss: %f]" % (e, dLoss[0], 100 * dLoss[1], gLoss)) dLossReal.

append([e,dLoss[0]]) dLossFake.

append([e,dLoss[1]]) gLossLogs.

append([e,gLoss]) if e % plotInternal == 0 and e!=0: show_imgs(generator, e) dLossRealArr= np.

array(dLossReal) dLossFakeArr = np.

array(dLossFake) gLossLogsArr = np.

array(gLossLogs) chk = e while chk > 50: chk = chk – 51 if chk == 0: discriminator.

save_weights('/content/gdrive/My Drive/discriminator_DCGAN_lr=0.

0001,proportion2,deepgenerator_Fake.

h5') gan.

save_weights('/content/gdrive/My Drive/gan_DCGAN_lr=0.

0001,proportion2,deepgenerator_Fake.

h5') generator.

save_weights('/content/gdrive/My Drive/generator_DCGAN_lr=0.

0001,proportion2,deepgenerator_Fake.

h5') # At the end of training plot the losses vs epochs plt.

plot(dLossRealArr[:, 0], dLossRealArr[:, 1], label="Discriminator Loss – Real") plt.

plot(dLossFakeArr[:, 0], dLossFakeArr[:, 1], label="Discriminator Loss – Fake") plt.

plot(gLossLogsArr[:, 0], gLossLogsArr[:, 1], label="Generator Loss") plt.

xlabel('Epochs') plt.

ylabel('Loss') plt.

legend() plt.

title('GAN') plt.

grid(True) plt.

show() return gan, generator, discriminatorgan, generator, discriminator = DCGAN(Noise_dim)train(epochs=4000, batchSize=128, plotInternal=200)Let us compare the output of these two networks.

By running the line:show_imgs(Generator)the network will output some images from the generator (this is one of the functions we defined earlier).

Generated images from 1:1 training of discriminator vs.

generator.

Now let’s check the second model.

Generated images from the second network with different training times for the discriminator and generator.

We can see that the details of the generated images are improved and the texture of them are slightly more detailed.

However, in comparison to the training images they are still sub-par.

Training images from Anime dataset.

Perhaps the VAE-GAN will perform better?VAE-GAN on Anime DatasetTo reiterate what I said previously about the VAE-GAN, the term VAE-GAN was first used by Larsen et.

al in their paper “Autoencoding beyond pixels using a learned similarity metric”.

VAE-GAN models differentiate themselves from GANs in that their generators are variation autoencoders.

VAE-GAN architecture.

Source: https://arxiv.

org/abs/1512.

09300First we need to create and compile the VAE-GAN and make a summary for each of the networks (this is a good way to simply check the architecture).

# Create and compile a VAE-GAN, and make a summary for themfrom keras.

models import Sequential, Modelfrom keras.

layers import Input, Dense, Dropout, Activation, Flatten, LeakyReLU, BatchNormalization, Conv2DTranspose, Conv2D, Reshape,MaxPooling2D,UpSampling2D,InputLayer, Lambdafrom keras.

layers.

advanced_activations import LeakyReLUfrom keras.

layers.

convolutional import UpSampling2Dfrom keras.

optimizers import Adam, RMSprop,SGDfrom keras.

initializers import RandomNormalimport numpy as npimport matplotlib.

pyplot as pltimport os, globfrom PIL import Imageimport pandas as pdfrom scipy.

stats import normimport kerasfrom keras.

utils import np_utils, to_categoricalfrom keras import backend as Kimport randomfrom keras import metricsfrom tqdm import tqdm# plotInternalplotInternal = 50#######latent_dim = 256batch_size = 256rows = 64columns = 64channel = 3epochs = 4000# datasize = len(dataset)# optimizersSGDop = SGD(lr=0.

0003)ADAMop = Adam(lr=0.

0002)# filtersfilter_of_dis = 16filter_of_decgen = 16filter_of_encoder = 16def sampling(args): mean, logsigma = args epsilon = K.

random_normal(shape=(K.

shape(mean)[0], latent_dim), mean=0.

, stddev=1.

0) return mean + K.

exp(logsigma / 2) * epsilondef vae_loss(X , output , E_mean, E_logsigma): # compute the average MSE error, then scale it up, ie.

simply sum on all axes reconstruction_loss = 2 * metrics.

mse(K.

flatten(X), K.

flatten(output)) # compute the KL loss kl_loss = – 0.

5 * K.

sum(1 + E_logsigma – K.

square(E_mean) – K.

exp(E_logsigma), axis=-1) total_loss = K.

mean(reconstruction_loss + kl_loss) return total_loss def encoder(kernel, filter, rows, columns, channel): X = Input(shape=(rows, columns, channel)) model = Conv2D(filters=filter, kernel_size=kernel, strides=2, padding='same')(X) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*2, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*4, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*8, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Flatten()(model) mean = Dense(latent_dim)(model) logsigma = Dense(latent_dim, activation='tanh')(model) latent = Lambda(sampling, output_shape=(latent_dim,))([mean, logsigma]) meansigma = Model([X], [mean, logsigma, latent]) meansigma.

compile(optimizer=SGDop, loss='mse') return meansigmadef decgen(kernel, filter, rows, columns, channel): X = Input(shape=(latent_dim,)) model = Dense(2*2*256)(X) model = Reshape((2, 2, 256))(model) model = BatchNormalization(epsilon=1e-5)(model) model = Activation('relu')(model) model = Conv2DTranspose(filters=filter*8, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = Activation('relu')(model) model = Conv2DTranspose(filters=filter*4, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = Activation('relu')(model) model = Conv2DTranspose(filters=filter*2, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = Activation('relu')(model) model = Conv2DTranspose(filters=filter, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = Activation('relu')(model) model = Conv2DTranspose(filters=channel, kernel_size=kernel, strides=2, padding='same')(model) model = Activation('tanh')(model) model = Model(X, model) model.

compile(loss='binary_crossentropy', optimizer=Adam(lr=0.

0001, beta_1=0.

5), metrics=['accuracy']) return modeldef discriminator(kernel, filter, rows, columns, channel): X = Input(shape=(rows, columns, channel)) model = Conv2D(filters=filter*2, kernel_size=kernel, strides=2, padding='same')(X) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*4, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*8, kernel_size=kernel, strides=2, padding='same')(model) model = BatchNormalization(epsilon=1e-5)(model) model = LeakyReLU(alpha=0.

2)(model) model = Conv2D(filters=filter*8, kernel_size=kernel, strides=2, padding='same')(model) dec = BatchNormalization(epsilon=1e-5)(model) dec = LeakyReLU(alpha=0.

2)(dec) dec = Flatten()(dec) dec = Dense(1, activation='sigmoid')(dec) output = Model(X, dec) output.

compile(loss='binary_crossentropy', optimizer=Adam(lr=0.

0002, beta_1=0.

5), metrics=['accuracy']) return output def VAEGAN(decgen,discriminator): # generator g = decgen # discriminator d = discriminator d.

trainable = False # GAN gan = Sequential([g, d]) # sgd=SGD() gan.

compile(optimizer=Adam(lr=0.

0001, beta_1=0.

5), loss='binary_crossentropy') return g, d, ganWe once again define some functions so that we can just print images from the generator.

def get_image(image_path, width, height, mode): image = Image.

open(image_path) #print(image.

size) return np.

array(image.

convert(mode))def show_imgs(generator): row=3 col = 5 noise = np.

random.

normal(0, 1, (row*col, latent_dim)) gen_imgs = generator.

predict(noise) # Rescale images 0 – 1 gen_imgs = 0.

5 * gen_imgs + 0.

5 fig, axs = plt.

subplots(row, col) #fig.

suptitle("DCGAN: Generated digits", fontsize=12) cnt = 0 for i in range(row): for j in range(col): axs[i, j].

imshow(gen_imgs[cnt, :, :, :]) axs[i, j].

axis('off') cnt += 1 #plt.

close() plt.

show()The parameters of the generator will be affected by both the GAN and VAE training.

# note: The parameters of the generator will be affected by both the GAN and VAE trainingG, D, GAN = VAEGAN(decgen(5, filter_of_decgen, rows, columns, channel),discriminator(5, filter_of_dis, rows, columns, channel))# encoderE = encoder(5, filter_of_encoder, rows, columns, channel)print("This is the summary for encoder:")E.

summary()# generator/decoder# G = decgen(5, filter_of_decgen, rows, columns, channel)print("This is the summary for dencoder/generator:")G.

summary()# discriminator# D = discriminator(5, filter_of_dis, rows, columns, channel)print("This is the summary for discriminator:")D.

summary()D_fixed = discriminator(5, filter_of_dis, rows, columns, channel)D_fixed.

compile(optimizer=SGDop, loss='mse')# ganprint("This is the summary for GAN:")GAN.

summary()# VAEX = Input(shape=(rows, columns, channel))E_mean, E_logsigma, Z = E(X)output = G(Z)# G_dec = G(E_mean + E_logsigma)# D_fake, F_fake = D(output)# D_fromGen, F_fromGen = D(G_dec)# D_true, F_true = D(X)# print("type(E)",type(E))# print("type(output)",type(output))# print("type(D_fake)",type(D_fake))VAE = Model(X, output)VAE.

add_loss(vae_loss(X, output, E_mean, E_logsigma))VAE.

compile(optimizer=SGDop)print("This is the summary for vae:")VAE.

summary()In the below cell we begin training our model.

Note that we use the previous method to train the discriminator and GAN and VAE for different lengths of time.

We emphasize the training of the discriminator in the first half of the training process and we train the generator more in the second half because we want to improve the quality of output images.

# We train our model in this celldLoss=[]gLoss=[]GLoss = 1GlossEnc = 1GlossGen = 1Eloss = 1halfbatch_size = int(batch_size*0.

5)for epoch in tqdm(range(epochs)): if epoch < int(epochs*0.

5): noise = np.

random.

normal(0, 1, (halfbatch_size, latent_dim)) index = np.

random.

randint(0,dataset.

shape[0], halfbatch_size) images = dataset[index] latent_vect = E.

predict(images)[0] encImg = G.

predict(latent_vect) fakeImg = G.

predict(noise) D.

Trainable = True DlossTrue = D.

train_on_batch(images, np.

ones((halfbatch_size, 1))) DlossEnc = D.

train_on_batch(encImg, np.

ones((halfbatch_size, 1))) DlossFake = D.

train_on_batch(fakeImg, np.

zeros((halfbatch_size, 1)))# DLoss=np.

add(DlossTrue,DlossFake)*0.

5 DLoss=np.

add(DlossTrue,DlossEnc) DLoss=np.

add(DLoss,DlossFake)*0.

33 D.

Trainable = False cnt = epoch while cnt > 3: cnt = cnt – 4 if cnt == 0: noise = np.

random.

normal(0, 1, (batch_size, latent_dim)) index = np.

random.

randint(0,dataset.

shape[0], batch_size) images = dataset[index] latent_vect = E.

predict(images)[0] GlossEnc = GAN.

train_on_batch(latent_vect, np.

ones((batch_size, 1))) GlossGen = GAN.

train_on_batch(noise, np.

ones((batch_size, 1))) Eloss = VAE.

train_on_batch(images, None) GLoss=np.

add(GlossEnc,GlossGen) GLoss=np.

add(GLoss,Eloss)*0.

33 dLoss.

append([epoch,DLoss[0]]) gLoss.

append([epoch,GLoss]) elif epoch >= int(epochs*0.

5): cnt = epoch while cnt > 3: cnt = cnt – 4 if cnt == 0: noise = np.

random.

normal(0, 1, (halfbatch_size, latent_dim)) index = np.

random.

randint(0,dataset.

shape[0], halfbatch_size) images = dataset[index] latent_vect = E.

predict(images)[0] encImg = G.

predict(latent_vect) fakeImg = G.

predict(noise) D.

Trainable = True DlossTrue = D.

train_on_batch(images, np.

ones((halfbatch_size, 1))) # DlossEnc = D.

train_on_batch(encImg, np.

ones((halfbatch_size, 1))) DlossFake = D.

train_on_batch(fakeImg, np.

zeros((halfbatch_size, 1))) DLoss=np.

add(DlossTrue,DlossFake)*0.

5 # DLoss=np.

add(DlossTrue,DlossEnc)# DLoss=np.

add(DLoss,DlossFake)*0.

33 D.

Trainable = False noise = np.

random.

normal(0, 1, (batch_size, latent_dim)) index = np.

random.

randint(0,dataset.

shape[0], batch_size) images = dataset[index] latent_vect = E.

predict(images)[0] GlossEnc = GAN.

train_on_batch(latent_vect, np.

ones((batch_size, 1))) GlossGen = GAN.

train_on_batch(noise, np.

ones((batch_size, 1))) Eloss = VAE.

train_on_batch(images, None) GLoss=np.

add(GlossEnc,GlossGen) GLoss=np.

add(GLoss,Eloss)*0.

33 dLoss.

append([epoch,DLoss[0]]) gLoss.

append([epoch,GLoss]) if epoch % plotInternal == 0 and epoch!=0: show_imgs(G) dLossArr= np.

array(dLoss) gLossArr = np.

array(gLoss) # print("dLossArr.

shape:",dLossArr.

shape)# print("gLossArr.

shape:",gLossArr.

shape) chk = epoch while chk > 50: chk = chk – 51 if chk == 0: D.

save_weights('/content/gdrive/My Drive/VAE discriminator_kernalsize5_proportion_32.

h5') G.

save_weights('/content/gdrive/My Drive/VAE generator_kernalsize5_proportion_32.

h5') E.

save_weights('/content/gdrive/My Drive/VAE encoder_kernalsize5_proportion_32.

h5') if epoch%20 == 0: print("epoch:", epoch + 1," ", "DislossTrue loss:",DlossTrue[0],"D accuracy:",100* DlossTrue[1], "DlossFake loss:", DlossFake[0],"GlossEnc loss:", GlossEnc, "GlossGen loss:",GlossGen, "Eloss loss:",Eloss)# print("loss:")# print("D:", DlossTrue, DlossEnc, DlossFake)# print("G:", GlossEnc, GlossGen)# print("VAE:", Eloss)print('Training done,saving weights')D.

save_weights('/content/gdrive/My Drive/VAE discriminator_kernalsize5_proportion_32.

h5')G.

save_weights('/content/gdrive/My Drive/VAE generator_kernalsize5_proportion_32.

h5')E.

save_weights('/content/gdrive/My Drive/VAE encoder_kernalsize5_proportion_32.

h5')print('painting losses')# At the end of training plot the losses vs epochsplt.

plot(dLossArr[:, 0], dLossArr[:, 1], label="Discriminator Loss")plt.

plot(gLossArr[:, 0], gLossArr[:, 1], label="Generator Loss")plt.

xlabel('Epochs')plt.

ylabel('Loss')plt.

legend()plt.

title('GAN')plt.

grid(True)plt.

show()print('end')If you are planning on running this network, beware that the training process takes a REALLY long time.

I would not attempt this unless you have access to some powerful GPUs or are willing to run the model for an entire day.

Now our VAE-GAN training is complete, we can check to see how our output images look and compare them to our previous GANs.

# In this cell, we generate and visualize 15 images.

show_imgs(G)We can see that in this implementation of VAE-GAN, we got a nice model which can generate images that are clear and of a similar style to the original images.

Our VAE-GAN can create images more robustly and this can be done without extra noise of the anime faces.

However, the competence of generalization of our model is not very good, it seldom changes the manner or sex of the character, so this is a point that we could try to improve.

Final CommentsIt is not necessarily clear that any one of the models is better than the others, and none of these methods have been optimized properly so it is difficult to make a comparison.

This is still an active area of research, so if you are interested I recommend getting yourself stuck in and try and use GANs within your own work to see what you can come up with.

I hope you have enjoyed this trilogy of articles on GANs and now have a much better idea of what they are, what they can do, and how to make your own.

Thank you for reading!Further ReadingRun BigGAN in COLAB:https://colab.

research.

google.

com/github/tensorflow/hub/blob/master/examples/colab/biggan_generation_with_tf_hub.

ipynbMore code help + examples:https://www.

jessicayung.

com/explaining-tensorflow-code-for-a-convolutional-neural-network/https://lilianweng.

github.

io/lil-log/2017/08/20/from-GAN-to-WGAN.

htmlhttps://pytorch.

org/tutorials/beginner/dcgan_faces_tutorial.

htmlhttps://github.

com/tensorlayer/srganhttps://junyanz.

github.

io/CycleGAN/ https://affinelayer.

com/pixsrv/https://tcwang0509.

github.

io/pix2pixHD/Influential Papers:DCGAN https://arxiv.

org/pdf/1511.

06434v2.

pdfWasserstein GAN (WGAN) https://arxiv.

org/pdf/1701.

07875.

pdfConditional Generative Adversarial Nets (CGAN) https://arxiv.

org/pdf/1411.

1784v1.

pdfDeep Generative Image Models using a Laplacian Pyramid of Adversarial Networks (LAPGAN) https://arxiv.

org/pdf/1506.

05751.

pdfPhoto-Realistic Single Image Super-Resolution Using a Generative Adversarial Network (SRGAN) https://arxiv.

org/pdf/1609.

04802.

pdfUnpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks (CycleGAN) https://arxiv.

org/pdf/1703.

10593.

pdfInfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets https://arxiv.

org/pdf/1606.

03657DCGAN https://arxiv.

org/pdf/1704.

00028.

pdfImproved Training of Wasserstein GANs (WGAN-GP) https://arxiv.

org/pdf/1701.

07875.

pdfEnergy-based Generative Adversarial Network (EBGAN) https://arxiv.

org/pdf/1609.

03126.

pdfAutoencoding beyond pixels using a learned similarity metric (VAE-GAN) https://arxiv.

org/pdf/1512.

09300.

pdfAdversarial Feature Learning (BiGAN) https://arxiv.

org/pdf/1605.

09782v6.

pdfStacked Generative Adversarial Networks (SGAN) https://arxiv.

org/pdf/1612.

04357.

pdfStackGAN++: Realistic Image Synthesis with Stacked Generative Adversarial Networks https://arxiv.

org/pdf/1710.

10916.

pdfLearning from Simulated and Unsupervised Images through Adversarial Training (SimGAN) https://arxiv.

org/pdf/1612.

07828v1.

pdf.

. More details

Leave a Reply