Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add simple DCgan model and ac_gan model on mnist dataset #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions configs/acgan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"exp": {
"name": "ac_gan",
"parent_dir": "./data/",
"experiments_dir": "experiments"
},
"dataset": {
"name": "mnist_dataset",
"image_size": 28,
"data_loader": {
"type": "simple_mnist",
"num_proc": 3,
"fit_resize": true,
"random_fit": true,
"random_fit_max_ratio": 1.3,
"random_flip": true,
"random_brightness": true,
"random_contrast": true,
"use_lmdb": false
}
},
"model": {
"structure": "ac_gan",
"generator": {
"model": "generator",
"lr": 0.0002,
"dropout": false,
"beta1": 0.5,
"recons_weight": 10,
"identity_weight": 5,
"clipvalue": 0,
"clipnorm": 0
},
"discriminator": {
"model": "ac_gan_discriminator",
"lr": 0.0002,
"beta1": 0.5,
"clipvalue": 0,
"clipnorm": 0
}
},
"trainer": {
"num_epochs": 200,
"batch_size": 128,
"fake_pool_size": 50,
"label_smoothing": false,
"keep_checkpoint_freq": 10,
"pred_save_batch_size": 100,
"pred_save_row_size": 10,
"pred_rate": 5,
"epoch_to_continue": 0,
"gpus": 2,
"gpu_memory_fraction": 0.9
},
"callbacks": {
"checkpoint_dir": "./save_dir",
"tensorboard_log_dir": "./tensorboard_dir",
"predicted_dir": "./predict_dir"
}
}
59 changes: 59 additions & 0 deletions configs/dcgan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"exp": {
"name": "simple_mnist_gan",
"parent_dir": "./data/",
"experiments_dir": "experiments"
},
"dataset": {
"name": "mnist_dataset",
"image_size": 28,
"data_loader": {
"type": "simple_mnist",
"num_proc": 3,
"fit_resize": true,
"random_fit": true,
"random_fit_max_ratio": 1.3,
"random_flip": true,
"random_brightness": true,
"random_contrast": true,
"use_lmdb": false
}
},
"model": {
"structure": "dc_gan",
"generator": {
"model": "generator",
"lr": 0.0002,
"dropout": false,
"beta1": 0.5,
"recons_weight": 10,
"identity_weight": 5,
"clipvalue": 0,
"clipnorm": 0
},
"discriminator": {
"model": "dc_gan_discriminator",
"lr": 0.0002,
"beta1": 0.5,
"clipvalue": 0,
"clipnorm": 0
}
},
"trainer": {
"num_epochs": 200,
"batch_size": 128,
"fake_pool_size": 50,
"label_smoothing": false,
"keep_checkpoint_freq": 10,
"pred_save_batch_size": 8,
"pred_rate": 5,
"epoch_to_continue": 0,
"gpus": 2,
"gpu_memory_fraction": 0.9
},
"callbacks": {
"checkpoint_dir": "./save_dir",
"tensorboard_log_dir": "./tensorboard_dir",
"predicted_dir": "./predict_dir"
}
}
100 changes: 100 additions & 0 deletions data_loader/simple_mnist_dataloader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import numpy as np
from keras.datasets import mnist
from keras.utils import to_categorical

from base.base_data_loader import BaseDataLoader


class MnistDataLoader(BaseDataLoader):
def __init__(self, config):
BaseDataLoader.__init__(self, config)
train_data, test_data = mnist.load_data()

train_x_data, train_labels = train_data
test_x_data, test_labels = test_data

train_labels = to_categorical(train_labels, num_classes=10, dtype=np.float64)
test_labels = to_categorical(test_labels, num_classes=10, dtype=np.float64)

self.train_data = train_data
self.train_data_with_labels = (train_x_data, train_labels)
self.test_data = test_data
self.test_data_with_labels = (test_x_data, test_labels)
self.train_data_size = len(train_data[0])
self.test_data_size = len(test_data[0])

def get_train_data(self):
images = []
while True:
for (image, label) in zip(self.train_data[0], self.train_data[1]):
images.append(image)
if len(images) >= self.config.trainer.batch_size:
data = np.array(images) / 127.5 - 1
data = np.expand_dims(data, -1)
images.clear()
yield data

def get_train_data_with_labels(self):
images = []
labels = []
while True:
for (image, label) in zip(self.train_data_with_labels[0], self.train_data_with_labels[1]):
images.append(image)
labels.append(label)
if len(images) >= self.config.trainer.batch_size:
x_data = np.array(images) / 127.5 - 1
x_data = np.expand_dims(x_data, -1)
y_data = np.array(labels, dtype=np.float64)
images.clear()
labels.clear()
yield x_data, y_data

def get_test_data(self):
images = []
while True:
for (image, label) in zip(self.test_data[0], self.test_data[1]):
images.append(image)
if len(images) >= self.config.trainer.batch_size:
data = np.array(images) / 127.5 - 1
data = np.expand_dims(data, -1)
images.clear()
yield data

def get_test_data_with_labels(self):
images = []
labels = []
while True:
for (image, label) in zip(self.test_data[0], self.test_data[1]):
images.append(image)
labels.append(label)
if len(images) >= self.config.trainer.batch_size:
x_data = np.array(images) / 127.5 - 1
x_data = np.expand_dims(x_data, -1)
y_data = np.array(labels, dtype=np.float64)
images.clear()
labels.clear()
yield x_data, y_data

def get_train_data_generator(self):
return self.get_train_data()

def get_train_data_generator_with_labels(self):
return self.get_train_data_with_labels()

def get_validation_data_generator(self):
raise NotImplementedError

def get_test_data_generator(self):
return self.get_test_data()

def get_test_data_generator_with_labels(self):
return self.get_test_data_with_labels()

def get_train_data_size(self):
return self.train_data_size

def get_validation_data_size(self):
raise NotImplementedError

def get_test_data_size(self):
return self.test_data_size
43 changes: 43 additions & 0 deletions model_trainer_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@
from base.base_model import BaseModel
from base.base_trainer import BaseTrainer
from models.cyclegan_combined import CycleganCombined
from models.dc_gan import SimpleGan
from models.dc_gan_generator import SimpleGenerator
from models.patchgan_discriminator import PatchGanDiscriminator
from models.resnet_generator import ResnetGenerator
from models.with_load_weights import WithLoadWeights, WithLoadOptimizerWeights
from trainers.ac_gan_mnist_trainer import CGanMnistTrainer
from trainers.cyclegan_trainer import CycleGanModelTrainer
from trainers.dc_gan_mnist_trainer import MnistTrainer


def get_generator_model_builder(config: DotMap) -> BaseModel:
model_name = config.model.generator.model
if model_name == 'resnet':
return ResnetGenerator(config)
elif model_name == 'generator':
return SimpleGenerator(config)
else:
raise ValueError(f"unknown generator model {model_name}")

Expand All @@ -25,6 +31,10 @@ def get_discriminator_model_builder(config: DotMap) -> BaseModel:
model_name = config.model.discriminator.model
if model_name == 'patchgan':
return PatchGanDiscriminator(config)
elif model_name == 'dc_gan_discriminator':
return SimpleDiscriminator(config)
elif model_name == 'ac_gan_discriminator':
return CGanDiscriminator(config)
else:
raise ValueError(f"unknown discriminator model {model_name}")

Expand Down Expand Up @@ -53,5 +63,38 @@ def build_model_and_trainer(config: DotMap, data_loader: BaseDataLoader) -> Tupl
data_loader=data_loader, config=config)

return combined_model, trainer
elif model_structure == 'dc_gan':
generator = generator_builder.define_model(model_name='generator')
discriminator, parallel_discriminator = WithLoadWeights(discriminator_builder,
model_name='dc_gan_discriminator') \
.build_model(model_name='dc_gan_discriminator')
combined_model, parallel_combined_model = WithLoadWeights(SimpleGan(config), model_name='combined_model') \
.build_model(generator=generator, discriminator=discriminator, model_name='combined_model')

trainer = MnistTrainer(generator=generator,
discriminator=discriminator,
parallel_discriminator=parallel_discriminator,
combined_model=combined_model,
parallel_combined_model=parallel_combined_model,
data_loader=data_loader,
config=config)

return combined_model, trainer
elif model_structure == 'ac_gan':
generator = generator_builder.define_model(model_name='generator')
discriminator, parallel_discriminator = WithLoadWeights(discriminator_builder,
model_name='ac_gan_discriminator') \
.build_model(model_name='ac_gan_discriminator')
combined_model, parallel_combined_model = WithLoadWeights(CGan(config), model_name='ac_gan_combined_model') \
.build_model(generator=generator, discriminator=discriminator, model_name='ac_gan_combined_model')

trainer = CGanMnistTrainer(generator=generator,
discriminator=discriminator,
parallel_discriminator=parallel_discriminator,
combined_model=combined_model,
parallel_combined_model=parallel_combined_model,
data_loader=data_loader,
config=config)
return combined_model, trainer
else:
raise ValueError(f"unknown model structure {model_structure}")
23 changes: 23 additions & 0 deletions models/ac_gan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from keras.layers import Input
from keras.models import Model
from keras.optimizers import Adam

from base.base_model import BaseModel


class CGan(BaseModel):
def define_model(self, generator, discriminator, model_name):
discriminator.trainable = False
latent = Input(shape=(100,), name='noise')
generated_image = generator(latent)
logit, aux = discriminator(generated_image)
return Model(inputs=latent, outputs=[logit, aux], name=model_name)

def build_model(self, generator, discriminator, model_name):
combined = self.define_model(generator, discriminator, model_name)
optimizer = Adam(self.config.model.generator.lr)
parallel_combined = self.multi_gpu_model(combined)

parallel_combined.compile(optimizer=optimizer, loss=['binary_crossentropy', 'categorical_crossentropy'],
metrics=['accuracy'])
return combined, parallel_combined
26 changes: 26 additions & 0 deletions models/ac_gan_discriminator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from keras.layers import Dense, Input, Flatten, Conv2D
from keras.models import Model
from keras.optimizers import SGD

from base.base_model import BaseModel


class CGanDiscriminator(BaseModel):
def define_model(self, model_name):
inputs = Input(shape=(28, 28, 1), name=f'{model_name}_input')
x = Conv2D(32, kernel_size=3, strides=1, padding='valid')(inputs)
x = Conv2D(64, kernel_size=3, strides=1, padding='valid')(x)
x = Conv2D(256, kernel_size=3, strides=1, padding='valid')(x)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
logit = Dense(1, activation='sigmoid')(x)
aux = Dense(10, activation='sigmoid')(x)
return Model(inputs=inputs, outputs=[logit, aux], name=model_name)

def build_model(self, model_name):
model = self.define_model(model_name)
optimizer = SGD(self.config.model.discriminator.lr)
parallel_model = self.multi_gpu_model(model)
parallel_model.compile(optimizer=optimizer, loss=['binary_crossentropy', 'categorical_crossentropy'],
metrics=['accuracy'])
return model, parallel_model
24 changes: 24 additions & 0 deletions models/cnn_discriminator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from keras.layers import Dense, Input, Flatten, Conv2D
from keras.models import Model
from keras.optimizers import SGD

from base.base_model import BaseModel


class SimpleDiscriminator(BaseModel):
def define_model(self, model_name):
inputs = Input(shape=(28, 28, 1), name=f'{model_name}_input')
x = Conv2D(32, kernel_size=3, strides=1, padding='valid')(inputs)
x = Conv2D(64, kernel_size=3, strides=1, padding='valid')(x)
x = Conv2D(256, kernel_size=3, strides=1, padding='valid')(x)
x = Flatten()(x)
x = Dense(64, activation='relu')(x)
logit = Dense(1, activation='sigmoid')(x)
return Model(inputs=inputs, outputs=logit, name=model_name)

def build_model(self, model_name):
model = self.define_model(model_name)
optimizer = SGD(self.config.model.discriminator.lr)
parallel_model = self.multi_gpu_model(model)
parallel_model.compile(optimizer=optimizer, loss='binary_crossentropy', metrics=['accuracy'])
return model, parallel_model
23 changes: 23 additions & 0 deletions models/dc_gan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from keras.layers import Input
from keras.models import Model
from keras.optimizers import Adam

from base.base_model import BaseModel


class SimpleGan(BaseModel):
def define_model(self, generator, discriminator, model_name):
discriminator.trainable = False

latent = Input(shape=(100,), name='noise')
generated_image = generator(latent)
logit = discriminator(generated_image)
return Model(inputs=latent, outputs=logit, name=model_name)

def build_model(self, generator, discriminator, model_name):
combined = self.define_model(generator, discriminator, model_name)
optimizer = Adam(self.config.model.generator.lr)
parallel_combined = self.multi_gpu_model(combined)

parallel_combined.compile(optimizer=optimizer, loss='binary_crossentropy')
return combined, parallel_combined
Loading