Logo elodees  elodees

Une IA bien-veillante pour un monde meilleur













Seuls les caractères alphabétiques accentués ou non ainsi que l'espace sont acceptés

Logo IA




Réseau antagoniste génératif





Pas encore de compte ?

Inscrivez-vous pour accéder à tous les contenus




Un réseau antagoniste génératif (GAN) est un cadre de réseau neuronal profond capable d'apprendre à partir d'un ensemble de données d'entraînement et de générer de nouvelles données avec les mêmes caractéristiques que les données d'entraînement.

Les réseaux antagonistes génératifs sont constitués de deux réseaux de neurones, le générateur et le discriminateur, qui se font concurrence.

Le générateur est formé pour produire de fausses données.

Le discriminateur est formé pour distinguer les fausses données du générateur des exemples réels.









Un réseau antagoniste génératif très simple



Testé sous Anaconda et Python 3.7

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.autograd import Variable
 
matplotlib_is_available = True
try:
  from matplotlib import pyplot as plt
except ImportError:
  print("Will skip plotting; matplotlib is not available.")
  matplotlib_is_available = False
 
# Data params
data_mean = 4
data_stddev = 1.25
 
# ### Uncomment only one of these to define what data is actually sent to the Discriminator
#(name, preprocess, d_input_func) = ("Raw data", lambda data: data, lambda x: x)
#(name, preprocess, d_input_func) = ("Data and variances", lambda data: decorate_with_diffs(data, 2.0), lambda x: x * 2)
#(name, preprocess, d_input_func) = ("Data and diffs", lambda data: decorate_with_diffs(data, 1.0), lambda x: x * 2)
(name, preprocess, d_input_func) = ("Only 4 moments", lambda data: get_moments(data), lambda x: 4)
 
print("Using data [%s]" % (name))
 
# ##### DATA: Target data and generator input data
 
def get_distribution_sampler(mu, sigma):
    return lambda n: torch.Tensor(np.random.normal(mu, sigma, (1, n)))  # Gaussian
 
def get_generator_input_sampler():
    return lambda m, n: torch.rand(m, n)  # Uniform-dist data into generator, _NOT_ Gaussian
 
# ##### MODELS: Generator model and discriminator model
 
class Generator(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, f):
        super(Generator, self).__init__()
        self.map1 = nn.Linear(input_size, hidden_size)
        self.map2 = nn.Linear(hidden_size, hidden_size)
        self.map3 = nn.Linear(hidden_size, output_size)
        self.f = f
 
    def forward(self, x):
        x = self.map1(x)
        x = self.f(x)
        x = self.map2(x)
        x = self.f(x)
        x = self.map3(x)
        return x
 
class Discriminator(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, f):
        super(Discriminator, self).__init__()
        self.map1 = nn.Linear(input_size, hidden_size)
        self.map2 = nn.Linear(hidden_size, hidden_size)
        self.map3 = nn.Linear(hidden_size, output_size)
        self.f = f
 
    def forward(self, x):
        x = self.f(self.map1(x))
        x = self.f(self.map2(x))
        return self.f(self.map3(x))
 
def extract(v):
    return v.data.storage().tolist()
 
def stats(d):
    return [np.mean(d), np.std(d)]
 
def get_moments(d):
    # Return the first 4 moments of the data provided
    mean = torch.mean(d)
    diffs = d - mean
    var = torch.mean(torch.pow(diffs, 2.0))
    std = torch.pow(var, 0.5)
    zscores = diffs / std
    skews = torch.mean(torch.pow(zscores, 3.0))
    kurtoses = torch.mean(torch.pow(zscores, 4.0)) - 3.0  # excess kurtosis, should be 0 for Gaussian
    final = torch.cat((mean.reshape(1,), std.reshape(1,), skews.reshape(1,), kurtoses.reshape(1,)))
    return final
 
def decorate_with_diffs(data, exponent, remove_raw_data=False):
    mean = torch.mean(data.data, 1, keepdim=True)
    mean_broadcast = torch.mul(torch.ones(data.size()), mean.tolist()[0][0])
    diffs = torch.pow(data - Variable(mean_broadcast), exponent)
    if remove_raw_data:
        return torch.cat([diffs], 1)
    else:
        return torch.cat([data, diffs], 1)
 
def train():
    # Model parameters
    g_input_size = 1      # Random noise dimension coming into generator, per output vector
    g_hidden_size = 5     # Generator complexity
    g_output_size = 1     # Size of generated output vector
    d_input_size = 500    # Minibatch size - cardinality of distributions
    d_hidden_size = 10    # Discriminator complexity
    d_output_size = 1     # Single dimension for 'real' vs. 'fake' classification
    minibatch_size = d_input_size
 
    d_learning_rate = 1e-3
    g_learning_rate = 1e-3
    sgd_momentum = 0.9
 
    num_epochs = 5000
    print_interval = 100
    d_steps = 20
    g_steps = 20
 
    dfe, dre, ge = 0, 0, 0
    d_real_data, d_fake_data, g_fake_data = None, None, None
 
    discriminator_activation_function = torch.sigmoid
    generator_activation_function = torch.tanh
 
    d_sampler = get_distribution_sampler(data_mean, data_stddev)
    gi_sampler = get_generator_input_sampler()
    G = Generator(input_size=g_input_size,
                  hidden_size=g_hidden_size,
                  output_size=g_output_size,
                  f=generator_activation_function)
    D = Discriminator(input_size=d_input_func(d_input_size),
                      hidden_size=d_hidden_size,
                      output_size=d_output_size,
                      f=discriminator_activation_function)
    criterion = nn.BCELoss()  # Binary cross entropy: http://pytorch.org/docs/nn.html#bceloss
    d_optimizer = optim.SGD(D.parameters(), lr=d_learning_rate, momentum=sgd_momentum)
    g_optimizer = optim.SGD(G.parameters(), lr=g_learning_rate, momentum=sgd_momentum)
 
    for epoch in range(num_epochs):
        for d_index in range(d_steps):
            # 1. Train D on real+fake
            D.zero_grad()
 
            #  1A: Train D on real
            d_real_data = Variable(d_sampler(d_input_size))
            d_real_decision = D(preprocess(d_real_data))
            d_real_error = criterion(d_real_decision, Variable(torch.ones([1])))  # ones = true
            d_real_error.backward() # compute/store gradients, but don't change params
 
            #  1B: Train D on fake
            d_gen_input = Variable(gi_sampler(minibatch_size, g_input_size))
            d_fake_data = G(d_gen_input).detach()  # detach to avoid training G on these labels
            d_fake_decision = D(preprocess(d_fake_data.t()))
            d_fake_error = criterion(d_fake_decision, Variable(torch.zeros([1])))  # zeros = fake
            d_fake_error.backward()
            d_optimizer.step()     # Only optimizes D's parameters; changes based on stored gradients from backward()
 
            dre, dfe = extract(d_real_error)[0], extract(d_fake_error)[0]
 
        for g_index in range(g_steps):
            # 2. Train G on D's response (but DO NOT train D on these labels)
            G.zero_grad()
 
            gen_input = Variable(gi_sampler(minibatch_size, g_input_size))
            g_fake_data = G(gen_input)
            dg_fake_decision = D(preprocess(g_fake_data.t()))
            g_error = criterion(dg_fake_decision, Variable(torch.ones([1])))  # Train G to pretend it's genuine
 
            g_error.backward()
            g_optimizer.step()  # Only optimizes G's parameters
            ge = extract(g_error)[0]
 
        if epoch % print_interval == 0:
            print("Epoch %s: D (%s real_err, %s fake_err) G (%s err); Real Dist (%s),  Fake Dist (%s) " %
                  (epoch, dre, dfe, ge, stats(extract(d_real_data)), stats(extract(d_fake_data))))
 
    if matplotlib_is_available:
        print("Plotting the generated distribution...")
        values = extract(g_fake_data)
        print(" Values: %s" % (str(values)))
        plt.hist(values, bins=50)
        plt.xlabel('Value')
        plt.ylabel('Count')
        plt.title('Histogram of Generated Distribution')
        plt.grid(True)
        plt.show()
 
train()
 


pytorch-generative-adversarial-networks

License: Apache 2.0LicenseApache 2.0  Copyright (c) Apache.


GitHub



Image gratuite et libre de droits fournie par pexel.com




GAN architecture



Image gratuite et libre de droits fournie par pexel.com


generative-adversarial-networks

License: MITLicenseMIT  Copyright (c) 2017 Jon Bruner


GitHub





Implémentations Keras des réseaux antagonistes génératifs bidirectionnels



Testé sous Anaconda et Python 3.7

from __future__ import print_function, division
 
from keras.datasets import mnist
from keras.layers import Input, Dense, Reshape, Flatten, Dropout
from keras.layers import BatchNormalization, Activation, ZeroPadding2D
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import UpSampling2D, Conv2D
from keras.models import Sequential, Model
from keras.optimizers import Adam
 
import matplotlib.pyplot as plt
 
import sys
 
import numpy as np
 
class GAN():
    def __init__(self):
        self.img_rows = 28
        self.img_cols = 28
        self.channels = 1
        self.img_shape = (self.img_rows, self.img_cols, self.channels)
        self.latent_dim = 100
 
        optimizer = Adam(0.0002, 0.5)
 
        # Build and compile the discriminator
        self.discriminator = self.build_discriminator()
        self.discriminator.compile(loss='binary_crossentropy',
            optimizer=optimizer,
            metrics=['accuracy'])
 
        # Build the generator
        self.generator = self.build_generator()
 
        # The generator takes noise as input and generates imgs
        z = Input(shape=(self.latent_dim,))
        img = self.generator(z)
 
        # 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(img)
 
        # The combined model  (stacked generator and discriminator)
        # Trains the generator to fool the discriminator
        self.combined = Model(z, validity)
        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)
 
 
    def build_generator(self):
 
        model = Sequential()
 
        model.add(Dense(256, input_dim=self.latent_dim))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(512))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(1024))
        model.add(LeakyReLU(alpha=0.2))
        model.add(BatchNormalization(momentum=0.8))
        model.add(Dense(np.prod(self.img_shape), activation='tanh'))
        model.add(Reshape(self.img_shape))
 
        model.summary()
 
        noise = Input(shape=(self.latent_dim,))
        img = model(noise)
 
        return Model(noise, img)
 
    def build_discriminator(self):
 
        model = Sequential()
 
        model.add(Flatten(input_shape=self.img_shape))
        model.add(Dense(512))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dense(256))
        model.add(LeakyReLU(alpha=0.2))
        model.add(Dense(1, activation='sigmoid'))
        model.summary()
 
        img = Input(shape=self.img_shape)
        validity = model(img)
 
        return Model(img, validity)
 
    def train(self, epochs, batch_size=128, sample_interval=50):
 
        # Load the dataset
        (X_train, _), (_, _) = mnist.load_data()
 
        # Rescale -1 to 1
        X_train = X_train / 127.5 - 1.
        X_train = np.expand_dims(X_train, axis=3)
 
        # Adversarial ground truths
        valid = np.ones((batch_size, 1))
        fake = np.zeros((batch_size, 1))
 
        for epoch in range(epochs):
 
            # ---------------------
            #  Train Discriminator
            # ---------------------
 
            # Select a random batch of images
            idx = np.random.randint(0, X_train.shape[0], batch_size)
            imgs = X_train[idx]
 
            noise = np.random.normal(0, 1, (batch_size, self.latent_dim))
 
            # Generate a batch of new images
            gen_imgs = self.generator.predict(noise)
 
            # Train the discriminator
            d_loss_real = self.discriminator.train_on_batch(imgs, valid)
            d_loss_fake = self.discriminator.train_on_batch(gen_imgs, fake)
            d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
 
            # ---------------------
            #  Train Generator
            # ---------------------
 
            noise = np.random.normal(0, 1, (batch_size, self.latent_dim))
 
            # Train the generator (to have the discriminator label samples as valid)
            g_loss = self.combined.train_on_batch(noise, 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:
                self.sample_images(epoch)
 
    def sample_images(self, epoch):
        r, c = 5, 5
        noise = np.random.normal(0, 1, (r * c, self.latent_dim))
        gen_imgs = self.generator.predict(noise)
 
        # Rescale images 0 - 1
        gen_imgs = 0.5 * gen_imgs + 0.5
 
        fig, axs = plt.subplots(r, c)
        cnt = 0
        for i in range(r):
            for j in range(c):
                axs[i,j].imshow(gen_imgs[cnt, :,:,0], cmap='gray')
                axs[i,j].axis('off')
                cnt += 1
        fig.savefig("images/%d.png" % epoch)
        plt.close()
 
 
if __name__ == '__main__':
    gan = GAN()
    gan.train(epochs=30000, batch_size=32, sample_interval=200)
 


Keras-GAN

License: MITLicenseMIT  Copyright (c) 2017 Erik Linder-Norén


GitHub



Pix2pix


Réseau profond convolutif antagoniste génératif

Réseaux profond antagoniste génératif Wasserstein

Réseaux antagonistes génératifs de classificateur auxiliaire

Réseaux antagonistes génératifs bidirectionnel

Empilement de réseaux antagonistes génératifs

Réseaux antagonistes génératifs des moindres carrés

Réseaux antagonistes génératifs semi supervisé

Réseaux antagonistes génératifs couplés

Réseaux antagonistes génératifs conditionnels

Pix2Pix

Réseaux antagonistes génératifs conditionnels contextuels

Réseaux antagonistes génératifs conditionnels continus

Réseaux antagonistes génératifs à la recherche de frontières

Réseaux profond antagoniste génératif de fuites

Informations maximisant les réseaux antagonistes génératifs

Réseaux antagonistes génératifs à double apprentissage non supervisés

Réseaux antagonistes génératifs à super résolution

Réseaux antagonistes génératifs de Wasserstein avec pénalité de gradient Réseaux antagonistes génératifs

Réseau antagoniste génératif par cycle

Apprendre à découvrir les relations inter-domaines avec les réseaux antagonistes génératifs

Réseaux antagonistes génératifs de style

Réseaux antagonistes génératifs d'adaptation de domaine au niveau du pixel non supervisés

Réseaux antagonistes génératifs analytiques à profonds regrets

Réseaux antagonistes génératifs à l'équilibre des frontières

Réseau antagoniste génératif basé sur l'énergie

Coloriser une image noir et blanc

Réseaux antagonistes génératifs pour la transformation de photos en dessins de bande dessinée

Réseaux antagonistes génératifs pour la transformation de vidéos en bande dessinée

Manipulation d'images faciales

Synthèse d'images sémantiques

Trajectoires socialement acceptables avec des réseaux antagonistes génératifs

Encodeur de contexte

Génération d'un réseau antagoniste génératif à partir d'une seule image naturelle pour la manipulation d'images

Réseau antagoniste génératif auto-supervisé

Déflouter avec les réseaux antagonistes génératifs

Débruiter avec les réseaux antagonistes génératifs

Dérainer avec les réseaux antagonistes génératifs

Images surdimensionnées avec une super résolution à l'aide des réseaux antagonistes génératifs

Synchronisation labiale

Streamlit - Le générateur de visage GAN contrôlable













Bienvenu, je m’appelle Eric Soupet et je suis l'administrateur du site elodees.com. elodees.com est un état de l'art de l'Intelligence Artificielle et se veut collaboratif, vous pouvez dès à présent proposer du contenu tels que des articles, des événements, des tutoriels, ... alors n'hésitez pas !

Crédit des images de la plate-forme : Pixabay - Pixabay License | Pexels - Pexels License