<jupyter_start><jupyter_text>Generative Adversarial NetworksIn this notebook, we play with the GAN described in the [course](https://mlelarge.github.io/dataflowr/Slides/GAN/index.html) on a double moon dataset.Then we implement a Conditional GAN and an InfoGAN.<jupyter_code># all of these libraries are used for plotting
import numpy as np
import matplotlib.pyplot as plt

x_min, x_max = -1.4, 2.8
y_min, y_max = -4, 2.8

# Plot the dataset
def plot_data(ax, X, Y, color = 'bone'):
    plt.axis('off')
    ax.scatter(X[:, 0], X[:, 1], s=1, c=Y, cmap=color)
    plt.axis([x_min, x_max, y_min, y_max])
%matplotlib inline
# load the data and visualize it
data = np.load('./double_moon.npz')
X = data['X']
n_samples = X.shape[0]
Y = np.ones(n_samples)
fig, ax = plt.subplots(1, 1, facecolor='#4B6EA9')
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
plot_data(ax, X, Y)
plt.show()
import torch
use_gpu = torch.cuda.is_available()
def gpu(tensor, gpu=use_gpu):
    if gpu:
        return tensor.cuda()
    else:
        return tensor<jupyter_output><empty_output><jupyter_text>A simple GANWe start with the simple GAN described in the course.<jupyter_code>import torch.nn as nn

z_dim = 32
hidden_dim = 128

net_G = nn.Sequential(nn.Linear(z_dim,hidden_dim),
                     nn.ReLU(), nn.Linear(hidden_dim, 2))

net_D = nn.Sequential(nn.Linear(2,hidden_dim),
                     nn.ReLU(),
                     nn.Linear(hidden_dim,1),
                     nn.Sigmoid())

net_G = gpu(net_G)
net_D = gpu(net_D)<jupyter_output><empty_output><jupyter_text>Training loop as described in the course, keeping the losses for the discriminator and the generator.<jupyter_code>batch_size = 50
lr = 1e-4
nb_epochs = 1000

optimizer_G = torch.optim.Adam(net_G.parameters(),lr=lr)
optimizer_D = torch.optim.Adam(net_D.parameters(),lr=lr)

loss_D_epoch = []
loss_G_epoch = []
for e in range(nb_epochs):
    np.random.shuffle(X)
    real_samples = torch.from_numpy(X).type(torch.FloatTensor)
    loss_G = 0
    loss_D = 0
    for t, real_batch in enumerate(real_samples.split(batch_size)):
            #improving D
        z = gpu(torch.empty(batch_size,z_dim).normal_())
        fake_batch = net_G(z)
        D_scores_on_real = net_D(gpu(real_batch))
        D_scores_on_fake = net_D(fake_batch)
            
        loss = -torch.mean(torch.log(1-D_scores_on_fake) + torch.log(D_scores_on_real))
        optimizer_D.zero_grad()
        loss.backward()
        optimizer_D.step()
        loss_D += loss
                    
            # improving G
        z = gpu(torch.empty(batch_size,z_dim).normal_())
        fake_batch = net_G(z)
        D_scores_on_fake = net_D(fake_batch)
            
        loss = -torch.mean(torch.log(D_scores_on_fake))
        optimizer_G.zero_grad()
        loss.backward()
        optimizer_G.step()
        loss_G += loss
           
    loss_D_epoch.append(loss_D)
    loss_G_epoch.append(loss_G)
plt.plot(loss_D_epoch)
plt.plot(loss_G_epoch)
z = gpu(torch.empty(n_samples,z_dim).normal_())
fake_samples = net_G(z)
fake_data = fake_samples.cpu().data.numpy()
fig, ax = plt.subplots(1, 1, facecolor='#4B6EA9')
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
all_data = np.concatenate((X,fake_data),axis=0)
Y2 = np.concatenate((np.ones(n_samples),np.zeros(n_samples)))
plot_data(ax, all_data, Y2)
plt.show();<jupyter_output><empty_output><jupyter_text>We can generate more points:<jupyter_code>z = gpu(torch.empty(10*n_samples,z_dim).normal_())
fake_samples = net_G(z)
fake_data = fake_samples.cpu().data.numpy()
fig, ax = plt.subplots(1, 1, facecolor='#4B6EA9')
all_data = np.concatenate((X,fake_data),axis=0)
Y2 = np.concatenate((np.ones(n_samples),np.zeros(10*n_samples)))
plot_data(ax, all_data, Y2)
plt.show();<jupyter_output><empty_output><jupyter_text>Conditional GANWe are now implementing a [conditional GAN](https://arxiv.org/abs/1411.1784).We start by separating the two half moons in two clusters as follows:<jupyter_code>X = data['X']
n_samples = X.shape[0]
Y = data['Y']
fig, ax = plt.subplots(1, 1, facecolor='#4B6EA9')
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
plot_data(ax, X, Y)
plt.show()<jupyter_output><empty_output><jupyter_text>The task is now given a white or black label to generate points in the corresponding cluster.Both the generator and the discriminator take in addition a one hot encoding of the label. The generator will now generate fake points corresponding to the input label. The discriminator, given a pair of sample and label should detect if this is a fake or a real pair.<jupyter_code>z_dim = 32
hidden_dim = 128
label_dim = 2


class generator(nn.Module):
    def __init__(self,z_dim = z_dim, label_dim=label_dim,hidden_dim =hidden_dim):
        super(generator,self).__init__()
        self.net = nn.Sequential(nn.Linear(z_dim+label_dim,hidden_dim),
                     nn.ReLU(), nn.Linear(hidden_dim, 2))
        
    def forward(self, input, label_onehot):
        x = torch.cat([input, label_onehot], 1)
        return self.net(x)
    
class discriminator(nn.Module):
    def __init__(self,z_dim = z_dim, label_dim=label_dim,hidden_dim =hidden_dim):
        super(discriminator,self).__init__()
        self.net =  nn.Sequential(nn.Linear(2+label_dim,hidden_dim),
                     nn.ReLU(),
                     nn.Linear(hidden_dim,1),
                     nn.Sigmoid())
        
    def forward(self, input, label_onehot):
        x = torch.cat([input, label_onehot], 1)
        return self.net(x)
        

net_CG = gpu(generator())
net_CD = gpu(discriminator())<jupyter_output><empty_output><jupyter_text>You need to code the training loop:<jupyter_code>batch_size = 50
lr = 1e-4
nb_epochs = 1000

optimizer_CG = torch.optim.Adam(net_CG.parameters(),lr=lr)
optimizer_CD = torch.optim.Adam(net_CD.parameters(),lr=lr)
loss_D_epoch = []
loss_G_epoch = []
for e in range(nb_epochs):
    rperm = np.random.permutation(X.shape[0]);
    np.take(X,rperm,axis=0,out=X);
    np.take(Y,rperm,axis=0,out=Y);
    real_samples = torch.from_numpy(X).type(torch.FloatTensor)
    real_labels = torch.from_numpy(Y).type(torch.LongTensor)
    loss_G = 0
    loss_D = 0
    for real_batch, real_batch_label in zip(real_samples.split(batch_size),real_labels.split(batch_size)):
            #improving D
        z = gpu(torch.empty(batch_size,z_dim).normal_())
        #
        # your code here
        # hint: https://discuss.pytorch.org/t/convert-int-into-one-hot-format/507/4
        #
        
        loss = -torch.mean(torch.log(1-D_scores_on_fake) + torch.log(D_scores_on_real))
        optimizer_CD.zero_grad()
        loss.backward()
        optimizer_CD.step()
        loss_D += loss
            
            # improving G
        z = gpu(torch.empty(batch_size,z_dim).normal_())
        #
        # your code here
        #
            
        loss = -torch.mean(torch.log(D_scores_on_fake))
        optimizer_CG.zero_grad()
        loss.backward()
        optimizer_CG.step()
        loss_G += loss
                    
    loss_D_epoch.append(loss_D)
    loss_G_epoch.append(loss_G)
plt.plot(loss_D_epoch)
plt.plot(loss_G_epoch)
z = torch.empty(n_samples,z_dim).normal_().cuda()
label = torch.LongTensor(n_samples,1).random_() % label_dim
label_onehot = torch.FloatTensor(n_samples, label_dim).zero_()
label_onehot = label_onehot.scatter_(1, label, 1).cuda()
fake_samples = net_CG(z, label_onehot)
fake_data = fake_samples.cpu().data.numpy()
fig, ax = plt.subplots(1, 1, facecolor='#4B6EA9')
ax.set_xlim(x_min, x_max)
ax.set_ylim(y_min, y_max)
plot_data(ax, fake_data, label.squeeze().numpy())
plot_data(ax, X, Y, 'spring')
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12891849529780564, 'fraction_numerical': 0.013845350052246604, 'mean_word_length': 3.5067686874632136, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '269518', 'license': 'Apache-2.0', 'n_tokens_mistral': 2952, 'n_tokens_neox': 2884, 'n_words': 533, 'path': 'Notebooks/GAN_double_moon_empty.ipynb', 'repo_name': 'lasofivec/dataflowr', 'size': '7656'}