Cálculos generativos versus discriminativos

Para comprender las GAN, debe darse cuenta de cómo funcionan los cálculos generativos, y para eso, destacarlos de los cálculos discriminativos es esclarecedor. Los cálculos discriminatorios intentan caracterizar la información de entrada; es decir, dados los aspectos más destacados de una ocasión de información, anticipan un nombre o clase en el que esa información tiene un lugar.

Por ejemplo, dadas cada una de las palabras en un correo electrónico (el caso de información), un cálculo discriminatorio podría prever si el mensaje es spam o no spam. el spam es uno de los nombres, y el paquete de palabras acumulado del correo electrónico es lo más destacado que comprende la información de información. En el momento en que este problema se comunica científicamente, el nombre se llama y y los resaltados se llaman x. La definición p (y | x) se utiliza para significar “la probabilidad de y dada x”, lo que para esta situación significaría “la probabilidad de que un correo electrónico sea spam dadas las palabras que contiene”.
Por lo tanto, los cálculos discriminativos asignan puntos destacados a las marcas. Se ocupan exclusivamente de esa conexión. Un enfoque para considerar los cálculos generativos es que hacen lo inverso. En lugar de anticipar una marca dada ciertos aspectos destacados, se esfuerzan por prever aspectos destacados con un nombre específico.
La pregunta que un cálculo generativo intenta responder es: Esperando que este correo electrónico sea spam, ¿con qué probabilidad son estos aspectos destacados? Mientras que los modelos discriminativos se preocupan por la conexión entre y y x, los modelos generativos se preocupan por “cómo se obtiene x”. Permiten capturar p (x | y), la probabilidad de x dada y, o la probabilidad de resaltar dado un nombre o clase. (A fin de cuentas, los cálculos generativos también se pueden utilizar como clasificadores. Por alguna extraña razón, pueden lograr más que la información de entrada de pedidos).

Otro enfoque para considerarlo es reconocer discriminativo de generativo como este:

Los modelos discriminatorios se familiarizan con el límite entre clases.

Los modelos generativos modelan la dispersión de clases individuales.
Cómo funcionan las GAN

Un arreglo neuronal, llamado generador, crea nuevas ocurrencias de información, mientras que el otro, el discriminador, las evalúa para determinar su realidad; por ejemplo, el discriminador elige si cada aparición de información que encuesta tiene un lugar con el conjunto de datos de preparación genuino o no.

Supongamos que estamos intentando lograr algo más común que copiar la Mona Lisa. Crearemos números escritos manualmente como los que se encuentran en el conjunto de datos MNIST, que se toma de esta realidad actual. El objetivo del discriminador, cuando se indica una ocurrencia del conjunto de datos MNIST genuino, es percibir aquellos que son de buena fe.

Mientras tanto, el generador está haciendo nuevas imágenes de ingeniería que va al discriminador. Lo hace como tal en las expectativas de que ellos también serán estimados válidos, a pesar del hecho de que son falsos. El objetivo del generador es crear dígitos tolerables escritos a mano: mentir sin ser atrapados. El objetivo del discriminador es reconocer las imágenes que se originan en el generador como falsas.

Estos son los medios que toma una GAN:

El generador toma un número arbitrario y devuelve una imagen.

Esta imagen creada se refuerza en el discriminador cerca de una oleada de imágenes tomadas del conjunto de datos real y real.

El discriminador toma imágenes genuinas y falsificadas y devuelve probabilidades, un número en algún lugar en el rango de 0 y 1, con 1 hablando con una expectativa de credibilidad y 0 hablando para falsificar.

Entonces tienes un círculo de entrada doble:

El discriminador está en un círculo de entrada con la verdad básica de las imágenes, que sabemos.

El generador está en un círculo de entrada con el discriminador.

GAN schema

Crédito: O’Reilly

Puedes pensar en una GAN como la restricción de un falsificador y un policía en una ronda de felinos y ratones, donde el falsificador está descubriendo cómo pasar notas falsas, y el policía está descubriendo cómo reconocerlas. Ambos son dinámicos; por ejemplo, el policía también se está preparando (para ampliar la relación, posiblemente el banco nacional está acusando los cargos que pasaron a escondidas), y cada parte se familiariza con las diferentes técnicas en una aceleración constante.

Para MNIST, el organizador discriminador es un arreglo convolucional estándar que puede clasificar las imágenes reforzadas, un clasificador binomial que marca las imágenes como genuinas o falsas. El generador es un arreglo convolucional inverso, podría decirse: mientras que un clasificador convolucional estándar toma una imagen y la baja para mostrar una probabilidad, el generador toma un vector de conmoción irregular y lo sube a una imagen. El principal descarta información a través de estrategias de muestreo descendente como maxpooling, y el segundo produce nueva información.

Las dos redes intentan racionalizar una capacidad objetivo alternativa y contradictoria, o un trabajo de desgracia, en un juego de cero zum. Este es básicamente un modelo de experto en personajes en pantalla. A medida que el discriminador cambia su conducta, también lo hace el generador, y viceversa. Sus desgracias empujan uno contra el otro.

GANs

GAN, codificadores automáticos y VAE

Puede ser valioso contrastar los sistemas generativos mal dispuestos con otros sistemas neuronales, por ejemplo, autoencoders y autoencoders variacionales.
Los codificadores automáticos codifican la información de entrada como vectores. Hacen una representación encubierta, o compacta, de la información cruda. Son útiles en la disminución de la dimensionalidad; es decir, el vector que se completa como una representación oculta empaqueta la información cruda en menos mediciones notables. Los codificadores automáticos se pueden combinar con un supuesto decodificador, que le permite recrear la información de entrada dependiente de su representación oculta, tal como lo haría con una máquina limitada de Boltzmann.

autencoder schema

Consejos para preparar una GAN

En el momento en que entrenes al discriminador, mantén las estimaciones del generador consistentes; y cuando entrenes al generador, mantén el discriminador estable. Cada uno debe prepararse contra un enemigo estático. Por ejemplo, esto le da al generador una lectura superior en la pendiente por la que debe aprender.

De manera similar, preentrenar al discriminador contra MNIST antes de comenzar a preparar el generador establecerá una inclinación más clara.

Cada lado de la GAN puede abrumar al otro. En el caso de que el discriminador sea excesivamente grande, arrojará estimaciones tan cercanas a 0 o 1 que el generador luchará para examinar la inclinación. En el caso de que el generador sea excesivamente grande, aventurará tenazmente las deficiencias en el discriminador que conducen a falsos negativos. Esto podría ser moderado por las tasas de aprendizaje individual de las redes. Los dos sistemas neuronales deben tener un “nivel de aptitud” comparable. 1

Las GAN reservaron un largo esfuerzo para prepararse. En una GPU solitaria, una GAN puede llevar horas, y en una CPU solitaria durante un día. Si bien es difícil de sintonizar y, por lo tanto, de utilizar, las GAN han fortalecido una tonelada de fascinante exploración y composición.
Aquí hay un ejemplo de una GAN codificada en Keras, desde la cual se pueden importar modelos a Deeplearning4j.
clase 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)
 
        optimizador = Adam (0.0002, 0.5)
 
        # Construye y compila el discriminador
        self.discriminator = self.build_discriminator ()
        self.discriminator.compile (loss = ‘binary_crossentropy’,
            optimizador = optimizador,
            métricas = [‘precisión’])
 
        # Construye y compila el generador
        self.generator = self.build_generator ()
        self.generator.compile (pérdida = ‘binary_crossentropy’, optimizador = optimizador)
 
        # El generador toma el ruido como entrada y genera imgs
        z = Entrada (forma = (100,))
        img = self.generator (z)
 
        # Para el modelo combinado solo entrenaremos al generador
        self.discriminator.trainable = False
 
        # El válido toma imágenes generadas como entrada y determina la validez
        válido = self.discriminator (img)
 
        # El modelo combinado (generador apilado y discriminador) toma
        # ruido como entrada => genera imágenes => determina la validez
        self.combined = Modelo (z, válido)
        self.combined.compile (pérdida = ‘binary_crossentropy’, optimizador = optimizador)
 
    def build_generator (self):
 
        noise_shape = (100,)
 
        modelo = secuencial ()
 
        model.add (Denso (256, input_shape = noise_shape))
        model.add (LeakyReLU (alpha = 0.2))
        model.add (BatchNormalization (momentum = 0.8))
        model.add (Denso (512))
        model.add (LeakyReLU (alpha = 0.2))
        model.add (BatchNormalization (momentum = 0.8))
        model.add (Denso (1024))
        model.add (LeakyReLU (alpha = 0.2))
        model.add (BatchNormalization (momentum = 0.8))
        model.add (Denso (np.prod (self.img_shape), activación = ‘tanh’))
        model.add (Reformar (self.img_shape))
 
        Resumen Modelo()
 
        ruido = Entrada (forma = ruido_forma)
        img = modelo (ruido)
 
        Modelo de retorno (ruido, img)
 
    def build_discriminator (self):
 
        img_shape = (self.img_rows, self.img_cols, self.channels)
 
        modelo = secuencial ()
 
        model.add (Flatten (input_shape = img_shape))
        model.add (Denso (512))
        model.add (LeakyReLU (alpha = 0.2))
        model.add (Denso (256))
        model.add (LeakyReLU (alpha = 0.2))
        model.add (Denso (1, activación = ‘sigmoide’))
        Resumen Modelo()
 
        img = Entrada (forma = img_shape)
        validez = modelo (img)
 
        Modelo de devolución (img, validez)
 
    tren de definición (self, epochs, batch_size = 128, save_interval = 50):
 
        # Cargar el conjunto de datos
        (X_train, ), (, _) = mnist.load_data ()
 
        # Reescalar -1 a 1
        X_train = (X_train.astype (np.float32) – 127.5) / 127.5
        X_train = np.expand_dims (X_train, axis = 3)
 
        half_batch = int (batch_size / 2)
 
        para época en rango (épocas):

———————

            # Discriminador de trenes
            # ———————
 
            # Seleccione un medio lote aleatorio de imágenes
            idx = np.random.randint (0, X_train.shape [0], half_batch)
            imgs = X_train [idx]
 
            ruido = np.random.normal (0, 1, (half_batch, 100))
 
            # Generar medio lote de nuevas imágenes
            gen_imgs = self.generator.predict (ruido)
 
            # Entrenar al discriminador
            d_loss_real = self.discriminator.train_on_batch (imgs, np.ones ((half_batch, 1)))
            d_loss_fake = self.discriminator.train_on_batch (gen_imgs, np.zeros ((half_batch, 1)))
            d_loss = 0.5 * np.add (d_loss_real, d_loss_fake)
 
 
            # ———————
            # Generador de trenes
            # ———————
 
            ruido = np.random.normal (0, 1, (batch_size, 100))
 
            # El generador quiere que el discriminador etiquete las muestras generadas
            # como válido (unos)
            valid_y = np.array ([1] * batch_size)
 
            # Entrena el generador
            g_loss = self.combined.train_on_batch (noise, valid_y)
 
            # Trazar el progreso
            print (“% d [D loss:% f, acc .:% .2f %%] [G loss:% f]”% (epoch, d_loss [0], 100 * d_loss [1], g_loss))
 
            # Si en el intervalo de guardado => guardar muestras de imagen generadas
            if epoch% save_interval == 0:
                self.save_imgs (época)
 
    def save_imgs (self, epoch):
        r, c = 5, 5
        ruido = np.random.normal (0, 1, (r * c, 100))
        gen_imgs = self.generator.predict (ruido)
 
        # Reescalar imágenes 0-1
        gen_imgs = 0.5 * gen_imgs + 0.5
 
        fig, axs = plt.subplots (r, c)
        cnt = 0
        para i en rango (r):
            para j en el rango (c):
                axs [i, j] .imshow (gen_imgs [cnt,:,:, 0], cmap = ‘gray’)
                ejes [i, j] .axis (‘off’)
                cnt + = 1
        fig.savefig (“gan / images / mnist_% d.png”% epoch)
        plt.close ()
 
 
if name == ‘main‘:
    gan = GAN ()
    gan.train (epochs = 30000, batch_size = 32, save_interval = 200)