Top Related Projects
Code and hyperparameters for the paper "Generative Adversarial Networks"
Software that can generate photos from paintings, turn horses into zebras, perform style transfer, and more.
starter from "How to Train a GAN?" at NIPS2016
Keras implementations of Generative Adversarial Networks.
A tensorflow implementation of "Deep Convolutional Generative Adversarial Networks"
Code for the paper "Improved Techniques for Training GANs"
Quick Overview
WassersteinGAN is a GitHub repository that implements the Wasserstein GAN (WGAN) algorithm, an improved version of Generative Adversarial Networks (GANs). This project provides a PyTorch implementation of WGAN, which aims to address some of the stability issues associated with traditional GANs by using the Wasserstein distance as a loss function.
Pros
- Improved stability compared to traditional GANs
- Better convergence properties and less mode collapse
- Provides a clear and interpretable loss metric
- Includes implementations for both WGAN and WGAN with gradient penalty
Cons
- Requires more computational resources than standard GANs
- May be more complex to understand and implement for beginners
- Limited to PyTorch implementation
- Repository hasn't been updated recently, potentially lacking newer improvements
Code Examples
- Defining the WGAN generator:
class Generator(nn.Module):
def __init__(self, ngpu):
super(Generator, self).__init__()
self.ngpu = ngpu
self.main = nn.Sequential(
nn.ConvTranspose2d(nz, ngf * 8, 4, 1, 0, bias=False),
nn.BatchNorm2d(ngf * 8),
nn.ReLU(True),
# ... (more layers)
nn.ConvTranspose2d(ngf, nc, 4, 2, 1, bias=False),
nn.Tanh()
)
def forward(self, input):
return self.main(input)
- Training loop for WGAN:
for epoch in range(opt.niter):
for i, data in enumerate(dataloader, 0):
############################
# (1) Update D network
###########################
for p in netD.parameters():
p.requires_grad = True
for iter_d in range(CRITIC_ITERS):
real_cpu, _ = data
netD.zero_grad()
# ... (training steps for discriminator)
############################
# (2) Update G network
###########################
for p in netD.parameters():
p.requires_grad = False
netG.zero_grad()
# ... (training steps for generator)
- Calculating Wasserstein loss:
def calc_gradient_penalty(netD, real_data, fake_data):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, real_data.nelement()//BATCH_SIZE).contiguous().view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if use_cuda else alpha
interpolates = alpha * real_data + ((1 - alpha) * fake_data)
interpolates = interpolates.cuda() if use_cuda else interpolates
interpolates = autograd.Variable(interpolates, requires_grad=True)
disc_interpolates = netD(interpolates)
gradients = autograd.grad(outputs=disc_interpolates, inputs=interpolates,
grad_outputs=torch.ones(disc_interpolates.size()).cuda() if use_cuda else torch.ones(
disc_interpolates.size()),
create_graph=True, retain_graph=True, only_inputs=True)[0]
gradient_penalty = ((gradients.norm(2, dim=1) - 1) ** 2).mean() * LAMBDA
return gradient_penalty
Getting Started
To get started with WassersteinGAN:
-
Clone the repository:
git clone https://github.com/martinarjovsky/WassersteinGAN.git cd WassersteinGAN
-
Install dependencies:
pip install -r requirements.txt
-
Run the training script:
python main.py
Note: Make sure you have PyTorch installed and a compatible CUDA version if using GPU acceleration.
Competitor Comparisons
Code and hyperparameters for the paper "Generative Adversarial Networks"
Pros of adversarial
- Broader focus on adversarial examples and machine learning security
- More comprehensive codebase with various attack and defense methods
- Active community and ongoing development
Cons of adversarial
- Less specialized in GANs compared to WassersteinGAN
- May require more setup and configuration for specific GAN tasks
- Potentially steeper learning curve due to broader scope
Code Comparison
WassersteinGAN:
def calc_gradient_penalty(netD, real_data, fake_data, LAMBDA, cuda):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, int(real_data.nelement()/BATCH_SIZE)).contiguous()
alpha = alpha.view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if cuda else alpha
adversarial:
def fgsm(x, predictions, eps, clip_min=None, clip_max=None):
return fgm(x, predictions, eps, ord=np.inf, clip_min=clip_min,
clip_max=clip_max)
The code snippets show that WassersteinGAN focuses on GAN-specific operations, while adversarial provides more general adversarial example generation methods.
Software that can generate photos from paintings, turn horses into zebras, perform style transfer, and more.
Pros of CycleGAN
- Capable of unpaired image-to-image translation, allowing for more flexible dataset requirements
- Implements cycle consistency loss, which helps preserve content while changing style
- Provides pre-trained models for various image translation tasks
Cons of CycleGAN
- More complex architecture and training process compared to WassersteinGAN
- May struggle with preserving fine details in some translation tasks
- Requires more computational resources for training and inference
Code Comparison
CycleGAN:
def forward(self, input):
return self.model(input)
class ResnetGenerator(nn.Module):
def __init__(self, input_nc, output_nc, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False, n_blocks=6, padding_type='reflect'):
super(ResnetGenerator, self).__init__()
# ... (implementation details)
WassersteinGAN:
def calc_gradient_penalty(netD, real_data, fake_data, LAMBDA=10):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, int(real_data.nelement()/BATCH_SIZE)).contiguous()
alpha = alpha.view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if use_cuda else alpha
# ... (implementation details)
starter from "How to Train a GAN?" at NIPS2016
Pros of ganhacks
- Provides a comprehensive list of tips and tricks for training GANs
- Covers a wide range of GAN-related topics, not limited to a specific architecture
- Regularly updated with community contributions
Cons of ganhacks
- Lacks implementation details or code examples
- Does not focus on a specific GAN architecture or methodology
Code comparison
WassersteinGAN:
def calc_gradient_penalty(netD, real_data, fake_data, LAMBDA, cuda):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, int(real_data.nelement()/BATCH_SIZE)).contiguous()
alpha = alpha.view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if cuda else alpha
ganhacks:
No specific code implementation is provided in the ganhacks repository, as it focuses on general tips and best practices rather than code examples.
Summary
WassersteinGAN is a specific implementation of the Wasserstein GAN architecture, providing detailed code and mathematical explanations. In contrast, ganhacks is a collection of general tips and tricks for training GANs, covering a broader range of topics but lacking specific code implementations. WassersteinGAN is more suitable for those looking to understand and implement a particular GAN architecture, while ganhacks serves as a valuable resource for improving GAN training across various architectures.
Keras implementations of Generative Adversarial Networks.
Pros of Keras-GAN
- Implements multiple GAN variants in a single repository
- Uses Keras, making it more accessible for deep learning beginners
- Provides a consistent API across different GAN implementations
Cons of Keras-GAN
- May not be as optimized for performance as specialized implementations
- Lacks some of the more advanced techniques used in WassersteinGAN
- Could be less suitable for cutting-edge research due to its generalized approach
Code Comparison
WassersteinGAN:
def calc_gradient_penalty(netD, real_data, fake_data, LAMBDA, cuda):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, int(real_data.nelement()/BATCH_SIZE)).contiguous()
alpha = alpha.view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if cuda else alpha
Keras-GAN:
def wasserstein_loss(y_true, y_pred):
return K.mean(y_true * y_pred)
def gradient_penalty_loss(y_true, y_pred, averaged_samples):
gradients = K.gradients(y_pred, averaged_samples)[0]
gradients_sqr = K.square(gradients)
gradients_sqr_sum = K.sum(gradients_sqr, axis=np.arange(1, len(gradients_sqr.shape)))
The code snippets show different approaches to implementing gradient penalty, with WassersteinGAN using PyTorch and Keras-GAN using Keras/TensorFlow backend functions.
A tensorflow implementation of "Deep Convolutional Generative Adversarial Networks"
Pros of DCGAN-tensorflow
- Implements DCGAN architecture, which is known for stable training and high-quality image generation
- Uses TensorFlow, a widely-used and well-supported deep learning framework
- Includes pre-trained models for quick experimentation
Cons of DCGAN-tensorflow
- May suffer from mode collapse, a common issue in traditional GANs
- Limited to DCGAN architecture, which might not be suitable for all tasks
- Potentially slower convergence compared to Wasserstein GAN
Code Comparison
DCGAN-tensorflow:
def discriminator(image, reuse=False):
with tf.variable_scope("discriminator") as scope:
if reuse:
scope.reuse_variables()
# Discriminator network implementation
WassersteinGAN:
def discriminator(x):
x = nn.Conv2d(3, DIM, 4, 2, 1)(x)
x = nn.LeakyReLU(0.2)(x)
# Rest of the discriminator network
The DCGAN-tensorflow implementation uses TensorFlow's variable scoping, while WassersteinGAN uses PyTorch's functional API. WassersteinGAN's code is more concise due to PyTorch's dynamic computation graph.
Code for the paper "Improved Techniques for Training GANs"
Pros of improved-gan
- Implements multiple GAN improvements beyond WGAN, including feature matching and minibatch discrimination
- Provides a more comprehensive codebase with examples for various datasets
- Offers better documentation and usage instructions
Cons of improved-gan
- May be more complex to understand and implement for beginners
- Potentially higher computational requirements due to additional features
- Less focused on the specific WGAN algorithm compared to WassersteinGAN
Code Comparison
WassersteinGAN:
def calc_gradient_penalty(netD, real_data, fake_data, LAMBDA, cuda):
alpha = torch.rand(BATCH_SIZE, 1)
alpha = alpha.expand(BATCH_SIZE, int(real_data.nelement()/BATCH_SIZE)).contiguous()
alpha = alpha.view(BATCH_SIZE, 3, 32, 32)
alpha = alpha.cuda() if cuda else alpha
improved-gan:
def feature_matching_loss(fake_features, real_features):
loss = 0
for fake_feature, real_feature in zip(fake_features, real_features):
loss += torch.mean(torch.abs(torch.mean(fake_feature, 0) - torch.mean(real_feature, 0)))
return loss
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Wasserstein GAN
Code accompanying the paper "Wasserstein GAN"
A few notes
- The first time running on the LSUN dataset it can take a long time (up to an hour) to create the dataloader. After the first run a small cache file will be created and the process should take a matter of seconds. The cache is a list of indices in the lmdb database (of LSUN)
- The only addition to the code (that we forgot, and will add, on the paper) are the lines 163-166 of main.py. These lines act only on the first 25 generator iterations or very sporadically (once every 500 generator iterations). In such a case, they set the number of iterations on the critic to 100 instead of the default 5. This helps to start with the critic at optimum even in the first iterations. There shouldn't be a major difference in performance, but it can help, especially when visualizing learning curves (since otherwise you'd see the loss going up until the critic is properly trained). This is also why the first 25 iterations take significantly longer than the rest of the training as well.
- If your learning curve suddenly takes a big drop take a look at this. It's a problem when the critic fails to be close to optimum, and hence its error stops being a good Wasserstein estimate. Known causes are high learning rates and momentum, and anything that helps the critic get back on track is likely to help with the issue.
Prerequisites
- Computer with Linux or OSX
- PyTorch
- For training, an NVIDIA GPU is strongly recommended for speed. CPU is supported but training is very slow.
Two main empirical claims:
Generator sample quality correlates with discriminator loss
Improved model stability
Reproducing LSUN experiments
With DCGAN:
python main.py --dataset lsun --dataroot [lsun-train-folder] --cuda
With MLP:
python main.py --mlp_G --ngf 512
Generated samples will be in the samples
folder.
If you plot the value -Loss_D
, then you can reproduce the curves from the paper. The curves from the paper (as mentioned in the paper) have a median filter applied to them:
med_filtered_loss = scipy.signal.medfilt(-Loss_D, dtype='float64'), 101)
More improved README in the works.
Top Related Projects
Code and hyperparameters for the paper "Generative Adversarial Networks"
Software that can generate photos from paintings, turn horses into zebras, perform style transfer, and more.
starter from "How to Train a GAN?" at NIPS2016
Keras implementations of Generative Adversarial Networks.
A tensorflow implementation of "Deep Convolutional Generative Adversarial Networks"
Code for the paper "Improved Techniques for Training GANs"
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot