Skip to content

Commit

Permalink
fix(gans): Load and save model fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabclmnt committed May 7, 2020
1 parent 096d25a commit 50f8d36
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 64 deletions.
74 changes: 29 additions & 45 deletions models/cgan/model.py
@@ -1,6 +1,5 @@
import os
import numpy as np
import pandas as pd

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Dropout, Flatten, Embedding, multiply
Expand All @@ -9,47 +8,46 @@
from tensorflow.keras.optimizers import Adam

class CGAN():

def __init__(self, gan_args):
[self.batch_size, lr, self.noise_dim,
self.data_dim, num_classes, self.classes, layers_dim] = gan_args



self.generator = Generator(self.batch_size, num_classes). \
build_model(input_shape=(self.noise_dim,), dim=layers_dim, data_dim=self.data_dim)

self.discriminator = Discriminator(self.batch_size, num_classes). \
build_model(input_shape=(self.data_dim,), dim=layers_dim)

optimizer = Adam(lr, 0.5)

# Build and compile the discriminator
self.discriminator.compile(loss='binary_crossentropy',
optimizer=optimizer,
metrics=['accuracy'])

# The generator takes noise as input and generates imgs
z = Input(shape=(self.noise_dim,), batch_size=self.batch_size)
label = Input(shape=(1,), batch_size=self.batch_size)
record = self.generator([z, label])

# For the combined model we will only train the generator
self.discriminator.trainable = False

# The discriminator takes generated images as input and determines validity
validity = self.discriminator([record, label])

# The combined model (stacked generator and discriminator)
# Trains the generator to fool the discriminator
self.combined = Model([z, label], validity)
self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

def get_data_batch(self, train, batch_size, seed=0):
# # random sampling - some samples will have excessively low or high sampling, but easy to implement
# np.random.seed(seed)
# x = train.loc[ np.random.choice(train.index, batch_size) ].values
# iterate through shuffled indices, so every sample gets covered evenly

start_i = (batch_size * seed) % len(train)
stop_i = start_i + batch_size
shuffle_seed = (batch_size * seed) // len(train)
Expand All @@ -58,42 +56,40 @@ def get_data_batch(self, train, batch_size, seed=0):
train_ix = list(train_ix) + list(train_ix) # duplicate to cover ranges past the end of the set
x = train.loc[train_ix[start_i: stop_i]].values
return np.reshape(x, (batch_size, -1))

def train(self, data, train_arguments):
[cache_prefix, label_dim, epochs, sample_interval, data_dir] = train_arguments

data_cols = data.columns


# Adversarial ground truths
valid = np.ones((self.batch_size, 1))
fake = np.zeros((self.batch_size, 1))

for epoch in range(epochs):
# ---------------------
# Train Discriminator
# ---------------------
batch_x = self.get_data_batch(data, self.batch_size)
label = batch_x[:, label_dim]
noise = tf.random.normal((self.batch_size, self.noise_dim))

# Generate a batch of new records
gen_records = self.generator.predict([noise, label])

# Train the discriminator
d_loss_real = self.discriminator.train_on_batch([batch_x, label], valid)
d_loss_fake = self.discriminator.train_on_batch([gen_records, label], fake)
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

# ---------------------
# Train Generator
# ---------------------
noise = tf.random.normal((self.batch_size, self.noise_dim))
# Train the generator (to have the discriminator label samples as valid)
g_loss = self.combined.train_on_batch([noise, label], valid)

# Plot the progress
print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100 * d_loss[1], g_loss))

# If at save interval => save generated image samples
if epoch % sample_interval == 0:
# Test here data generation step
Expand All @@ -102,41 +98,43 @@ def train(self, data, train_arguments):
self.generator.save_weights(model_checkpoint_base_name.format('generator', epoch))
self.discriminator.save_weights(model_checkpoint_base_name.format('discriminator', epoch))

#Here is generating synthetic data
z = tf.random.normal((432, self.noise_dim))
label_z = tf.random.uniform((432,), minval=min(self.classes), maxval=max(self.classes)+1, dtype=tf.dtypes.int32)
gen_data = self.generator([z, label_z])
print('generated_data')

def save(self, path, name):
assert os.path.isdir(path) == True, \
"Please provide a valid path. Path must be a directory."
model_path = os.path.join(path, name)
self.generator.save_weights(model_path) # Load the generator
return

def load(self):
return

def load(self, path):
assert os.path.isdir(path) == True, \
"Please provide a valid path. Path must be a directory."
self.generator = Generator(self.batch_size)
self.generator = self.generator.load_weights(path)
return self.generator

class Generator():
def __init__(self, batch_size, num_classes):
self.batch_size = batch_size
self.num_classes = num_classes

def build_model(self, input_shape, dim, data_dim):
noise = Input(shape=input_shape, batch_size=self.batch_size)
label = Input(shape=(1,), batch_size=self.batch_size, dtype='int32')
label_embedding = Flatten()(Embedding(self.num_classes, 1)(label))
input = multiply([noise, label_embedding])

x = Dense(dim, activation='relu')(input)
x = Dense(dim * 2, activation='relu')(x)
x = Dense(dim * 4, activation='relu')(x)
x = Dense(data_dim)(x)

return Model(inputs=[noise, label], outputs=x)


class Discriminator():
def __init__(self, batch_size, num_classes):
self.batch_size = batch_size
Expand All @@ -145,7 +143,6 @@ def __init__(self, batch_size, num_classes):
def build_model(self, input_shape, dim):
events = Input(shape=input_shape, batch_size=self.batch_size)
label = Input(shape=(1,), batch_size=self.batch_size, dtype='int32')

label_embedding = Flatten()(Embedding(self.num_classes, 1)(label))
events_flat = Flatten()(events)
input = multiply([events_flat, label_embedding])
Expand All @@ -156,22 +153,9 @@ def build_model(self, input_shape, dim):
x = Dropout(0.1)(x)
x = Dense(dim, activation='relu')(x)
x = Dense(1, activation='sigmoid')(x)

return Model(inputs=[events, label], outputs=x)


if __name__ == '__main__':
data = pd.read_csv('../../data/data_processed.csv', index_col=[0])
y = data['Class']

gan_args = [128, 0.00002, 32, data.shape[1], len(y.unique()), y.unique(), 128]
train_args = ['', 30,300, 50, '.']

GAN_synth = CGAN(gan_args)
GAN_synth.train(data, train_args)






32 changes: 13 additions & 19 deletions models/gan/model.py
@@ -1,28 +1,26 @@
import os
import numpy as np
import pandas as pd

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Dropout
from tensorflow.keras import Model
from tensorflow.keras.models import save_model, load_model

from tensorflow.keras.optimizers import Adam
from tensorflow.keras.utils import plot_model



class GAN():

def __init__(self, gan_args):
[self.batch_size, lr, self.noise_dim,
self.data_dim, layers_dim] = gan_args

self.generator = Generator(self.batch_size).\
build_model(input_shape=(self.noise_dim,), dim=layers_dim, data_dim=self.data_dim)

self.discriminator = Discriminator(self.batch_size).\
build_model(input_shape=(self.data_dim,), dim=layers_dim)

optimizer = Adam(lr, 0.5)

# Build and compile the discriminator
Expand Down Expand Up @@ -50,7 +48,7 @@ def get_data_batch(self, train, batch_size, seed=0):
# np.random.seed(seed)
# x = train.loc[ np.random.choice(train.index, batch_size) ].values
# iterate through shuffled indices, so every sample gets covered evenly

start_i = (batch_size * seed) % len(train)
stop_i = start_i + batch_size
shuffle_seed = (batch_size * seed) // len(train)
Expand All @@ -77,11 +75,11 @@ def train(self, data, train_arguments):
noise = tf.random.normal((self.batch_size, self.noise_dim))

# Generate a batch of new images
gen_imgs = self.generator.predict(noise)
gen_data = self.generator.predict(noise)

# Train the discriminator
d_loss_real = self.discriminator.train_on_batch(batch_data, valid)
d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake)
d_loss_fake = self.discriminator.train_on_batch(gen_data, fake)
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)

# ---------------------
Expand All @@ -94,35 +92,31 @@ def train(self, data, train_arguments):
# Plot the progress
print("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, d_loss[0], 100 * d_loss[1], g_loss))

# If at save interval => save generated image samples
# If at save interval => save generated events
if epoch % sample_interval == 0:
#Test here data generation step
# save model checkpoints
model_checkpoint_base_name = './cache/' + cache_prefix + '_{}_model_weights_step_{}.h5'
self.generator.save_weights(model_checkpoint_base_name.format('generator', epoch))
self.discriminator.save_weights(model_checkpoint_base_name.format('discriminator', epoch))

#Aqui tentar gerar os dados?
#Here is generating the data
z = tf.random.normal((432, self.noise_dim))
gen_data = self.generator(z)
print('generated_data')

def save(self, path, name):
assert os.path.isdir(path)==True, \
assert os.path.isdir(path) == True, \
"Please provide a valid path. Path must be a directory."
model_path = os.path.join(path, name)

save_model(
self.generator, model_path, overwrite=True, include_optimizer=True, save_format=None,
signatures=None, options=None
)
self.generator.save_weights(model_path) # Load the generator
return

def load(self, path):
assert os.path.isdir(path) == True, \
"Please provide a valid path. Path must be a directory."
self.generator = Generator(self.batch_size)
if __name__ == '__main__':
self.generator = self.generator.load_weights(path)
self.generator = self.generator.load_weights(path)
return self.generator

class Generator():
Expand Down

0 comments on commit 50f8d36

Please sign in to comment.