Pix2Pix Liberato – Trasformare immagini con superpoteri creativi

Pix2Pix Liberato - Trasforma le immagini con superpoteri creativi

Introduzione

Immagina un programma speciale per computer che può rendere vivi i disegni creati dai bambini. Conosci quei disegni colorati e fantasiosi che i bambini fanno? Questo programma può trasformare quei disegni in immagini sembranti reali, quasi come per magia! Ed è chiamato Pix2Pix. Sappiamo come il mago può fare trucchi incredibili con un mazzo di carte. Allo stesso modo, Pix2Pix può fare cose incredibili con i disegni. Pix2Pix ha causato un cambiamento significativo nella comprensione e nel lavoro delle immagini da parte dei computer. Ci permette di avere un controllo davvero accurato sulle immagini che crea. È come avere un superpotere per creare e modificare immagini!

Fonte: X.com

Obiettivi di Apprendimento

  • Scoprire cosa è Pix2Pix, come funziona ed esplorare le sue applicazioni nel mondo reale
  • Provarlo utilizzando Pix2Pix per trasformare i disegni in immagini, utilizzando un dataset di facciate di edifici.
  • Comprendere il funzionamento di pix2pix nell’implementazione e capire come pix2pix risolve il problema che molti compiti di traduzione di immagini affrontano.

Questo articolo è stato pubblicato come parte del Data Science Blogathon.

Reti Antagoniste Generative (GAN)

Una delle più entusiasmanti recenti invenzioni dell’intelligenza artificiale è la Rete Antagonista Generativa o GAN. Queste potenti reti neurali possono creare nuovi contenuti, inclusi immagini, musica e testo. Le GAN sono composte da due reti neurali. Una è il generatore che crea contenuti, l’altra è il discriminatore che giudica i contenuti creati.

Il Generatore è responsabile della creazione dei contenuti. Parte da rumore casuale o dati e li raffina progressivamente in qualcosa di significativo. Ad esempio, nella generazione di immagini, può creare immagini dal nulla. Può iniziare regolando i valori dei pixel casuali per assomigliare a immagini belle e autentiche. Il ruolo del Discriminatore è valutare i contenuti generati dal generatore. Decide se il contenuto è reale o falso. Man mano che esamina più contenuti e fornisce feedback al generatore, diventa sempre migliore durante l’addestramento.

Fonte: Neptune.ai

L’intero processo di addestramento della GAN è noto come addestramento avversario. È molto semplice da capire. Il generatore crea contenuti inizialmente lontani dalla perfezione. Il discriminatore valuta i contenuti. Significa che cerca di distinguere tra reale e falso. Il generatore riceve feedback dal discriminatore e regola i suoi contenuti per renderli più convincenti e, quindi, fornisce contenuti migliori rispetto al precedente. In risposta ai miglioramenti del generatore, il discriminatore migliora la sua capacità di individuare contenuti falsi. In questo modo, l’addestramento avversario continua a rendere le GAN più potenti.

Pix2Pix

Il concetto di trasformazione e manipolazione di immagini è iniziato con le tecniche tradizionali di elaborazione delle immagini. Queste includono ridimensionamento delle immagini, correzione del colore e filtraggio. Tuttavia, questi metodi tradizionali avevano limitazioni per compiti più complessi come la traduzione di immagini in immagini. L’apprendimento automatico, in particolare il deep learning, ha rivoluzionato il campo della trasformazione delle immagini. Le reti neurali convoluzionali (CNN) sono diventate importanti per automatizzare compiti di elaborazione delle immagini. Tuttavia, lo sviluppo delle Reti Antagoniste Generative (GAN) ha segnato un traguardo nella traduzione di immagini in immagini.

Pix2Pix è un modello di deep learning utilizzato per compiti di traduzione delle immagini. L’idea principale dietro Pix2Pix è prendere un’immagine di input da un dominio e generare un’immagine di output corrispondente in un altro dominio. Traduce le immagini da uno stile a un altro. Questo approccio è chiamato GAN condizionale perché Pix2Pix utilizza una configurazione condizionata in cui l’immagine di input condiziona il generatore. Pix2Pix sfrutta l’architettura GAN in una forma condizionale chiamata Conditional GAN (cGAN). Sulla base della condizione, verrà generato l’output.

Fonte: Phillipi

Una Conditional Generative Adversarial Network, o CGAN, è una versione avanzata del framework GAN che permette un controllo preciso sulle immagini generate. Può generare immagini in una categoria specifica. Pix2Pix GAN è un’istanza di CGAN in cui il processo di generazione di un’immagine dipende dalla presenza di un’altra immagine data. Nell’immagine possiamo vedere le meraviglie che pix2pix ha creato. Posso creare scene di strada dall’etichetta, facciate dall’etichetta, bianco e nero a colori, viste aeree a una mappa reale, fotografie diurne a vista notturna e foto basate sui bordi.

Sfide nella traduzione immagine-immagine

La traduzione immagine-immagine è un complesso compito di visione artificiale, specialmente quando l’obiettivo è convertire un’immagine da un dominio in un’altra immagine di un diverso dominio. Qui, bisogna preservare il contenuto e la struttura sottostanti. La sfida nella traduzione immagine-immagine risiede nella cattura delle complesse relazioni tra i domini di input e output. Una delle soluzioni rivoluzionarie a questo problema è Pix2Pix.

Le immagini generate possono presentare problemi, come sfocature o distorsioni. Pix2pix cerca di migliorare l’aspetto delle immagini usando due reti: una che crea le immagini (generatore) e un’altra che verifica se sembrano reali (discriminatore). Il discriminatore aiuta il generatore a creare immagini più nitide e simili a foto reali, riducendo così i problemi di sfocatura e distorsioni.

In compiti come la colorizzazione di immagini, i colori nell’immagine generata possono diffondersi nelle regioni adiacenti, producendo una distribuzione di colore irrealistica. Pix2pix utilizza tecniche come i GAN condizionali per controllare meglio il processo di colorizzazione. Ciò rende la colorizzazione più naturale e meno confusionaria.

Architettura di Pix2Pix

L’architettura di Pix2Pix è composta da due componenti principali: il Generatore e il Discriminatore. Un approccio comune alla costruzione dei modelli di generatore e discriminatore consiste nell’utilizzare blocchi di costruzione standard composti da livelli come Convoluzione-BatchNormalization-ReLU. Combinare questi blocchi di costruzione per formare reti neurali convoluzionali profonde.

Modello generatore U-NET

Qui, per il generatore, viene utilizzata l’architettura del modello U-Net. Il modello encoder-decoder tradizionale prende un’immagine in input e la ridimensiona per alcune layer. Il processo continua finché un layer nell’immagine non viene ridimensionato per alcune layer e viene prodotta un’immagine finale. L’architettura UNet implica anche il ridimensionamento e il ridimensionamento dell’immagine. Ma la differenza qui sta nelle connessioni di salto tra le layer della stessa dimensione nell’encoder e nel decoder. Le connessioni di salto consentono al modello di combinare caratteristiche di basso e alto livello, affrontando il problema della perdita di informazioni durante il processo di riduzione delle dimensioni.

La parte superiore della forma “U” consiste in una serie di layer di convoluzione e pooling che riducono progressivamente le dimensioni spaziali dell’immagine in input aumentando contemporaneamente il numero di canali di feature. Questa particolare parte della rete è responsabile per catturare informazioni contestuali dall’immagine in input. U-Net è diventato un’architettura fondamentale nell’apprendimento profondo per compiti di segmentazione delle immagini. Infine, questo generatore genererà immagini indistinguibili dalle immagini reali.

Source: GitHub

Modello discriminatore PatchGAN

Progetta il modello del discriminatore per prendere due immagini come input. Prende un’immagine dal dominio di origine e un’immagine dal dominio di destinazione. Il compito principale è valutare e determinare la probabilità che l’immagine sia reale o generata dal generatore.

Il modello del discriminatore utilizza un GAN tradizionale con una rete neurale convoluzionale profonda per classificare le immagini. Il discriminatore di Pix2Pix utilizza PatchGAN anziché GAN tradizionale. Invece di classificare l’intera immagine di input come reale o falsa, progetta questa rete neurale convoluzionale profonda per identificare patch dell’immagine. Divide le immagini reali e generate in patch più piccole e non sovrapposte e le valuta singolarmente. PatchGAN fornisce un feedback dettagliato al generatore e gli consente di concentrarsi sul miglioramento dei dettagli locali dell’immagine. Ciò rende il training del generatore migliore. È particolarmente utile in alcuni compiti in cui preservare i dettagli fini è cruciale. Questi compiti includono il superamento della risoluzione delle immagini. Aiuta a generare risultati ad alta risoluzione e realistici.

Source: ResearchGate

Applicazioni di Pix2Pix

Ora vediamo alcune delle applicazioni di Pix2Pix.

  • Progettazione Architettonica: Pix2Pix può convertire bozzetti approssimativi di progetti di edifici in dettagliate bozze architettoniche. Ciò aiuta gli architetti a progettare edifici migliori.
  • Trasferimento di Stile: Può trasferire lo stile di un’immagine su un’altra. Può prendere lo stile di un dipinto famoso e applicarlo a una fotografia.
  • Sistemi di Navigazione: Pix2Pix ha applicazioni nei sistemi di navigazione. Possiamo catturare un’immagine panoramica stradale e utilizzando Pix2Pix, possiamo convertirla in mappe precise. Può essere prezioso per i sistemi di navigazione autonomi.
  • Imaging Medico: Pix2Pix può migliorare e tradurre immagini mediche nell’imaging medico. Le immagini ad alta risoluzione sono sempre utili nell’industria medica per fornire un migliore trattamento. Questo Pix2Pix aiuta a convertire le scansioni MRI a bassa risoluzione in quelle ad alta risoluzione o a generare immagini CT da immagini a raggi X.
  • Arte e Creatività: Utilizzare Pix2Pix per scopi creativi. Genera immagini o animazioni uniche e artistiche basate sull’input dell’utente.

Aziende che Utilizzano Pix2Pix

Ora vediamo alcune aziende che utilizzano Pix2Pix.

  • Adobe ha utilizzato Pix2Pix per sviluppare funzionalità per i suoi prodotti Creative Cloud. Questo include la conversione di schizzi in immagini realistiche e la traduzione di immagini da uno stile ad un altro. Pix2Pix è anche utilizzato da Adobe per generare dati sintetici per l’addestramento dei suoi modelli di apprendimento automatico.
  • Google ha utilizzato Pix2Pix per sviluppare funzionalità di prodotti per mappe e foto. Crea viste realistiche della strada da immagini satellitari e colora le foto in bianco e nero.
  • Nvidia utilizza Pix2Pix per la sua piattaforma AI. Ha la capacità di generare set di dati sintetici per l’addestramento di modelli di apprendimento automatico. Crea anche nuovi stili per le immagini.
  • Magenta Studio di Google è un progetto di ricerca che esplora l’apprendimento automatico e l’arte. Magenta Studio di Google ha utilizzato Pix2Pix per creare molti strumenti per la creazione artistica. Magenta Studio ha rilasciato molti Quaderni Colab che utilizzano Pix2Pix per creare diverse forme d’arte, come la traduzione di immagini, il completamento di immagini e l’inpainting di immagini. L’inpainting delle immagini include la rimozione di oggetti dalle immagini o il riempimento delle parti mancanti dell’immagine. Magenta Studio ha inoltre rilasciato numerosi modelli Magenta che impiegano Pix2Pix per produrre diverse forme d’arte. Questi modelli includono Pix2PixHD, che genera immagini ad alta risoluzione da quelle a bassa risoluzione; Disco Diffusion, che crea immagini ispirate a diversi stili artistici, e GANPaint, che produce immagini che mescolano realismo e immaginazione.

Implementazione

Cominciamo importando tutte le librerie e i moduli necessari. Se manca qualche modulo, importalo usando il comando pip.

import numpy as npfrom matplotlib import pylab as pltimport cv2import tensorflow as tfimport tensorflow.keras.layers as layersfrom tensorflow.keras.models import Modelfrom glob import globimport timeimport os

Dataset

Il dataset utilizzato in questo progetto è disponibile su Kaggle e puoi scaricarlo da qui.

Link: https://www.kaggle.com/datasets/balraj98/facades-dataset

Questo dataset contiene immagini di facciate di edifici e la loro segmentazione corrispondente. È stato diviso in sottoinsiemi di train e test. In totale, contiene 506 immagini di facciate di edifici.

Fonte: Kaggle

Preelaborazione

Il nostro prossimo passo è caricare i dati e preelaborarli in base alla nostra definizione del problema. Definiremo una funzione che esegue tutti i passaggi necessari per questo. Carica batch di immagini e le corrispondenti etichette, le preelabora e le restituisce come array NumPy pronti per essere inseriti nel tuo modello. Prima di tutto, specifica i percorsi in cui si trovano le immagini di test e le relative etichette. Usa la funzione glob per trovare tutti i file nelle due directory. Crea due liste vuote, img_A e img_2. Queste liste vuote conterranno le immagini preelaborate dai batch 1 e 2. Una volta creato il ciclo, scorre coppie di percorsi dei file dai batch 1 e 2. Per ogni coppia, leggi le immagini usando openCV e memorizzale in variabili.

Canali di colore

Invertiamo i canali di colore delle immagini, un passaggio spesso necessario per allinearle alle specifiche di input del modello di deep learning. Successivamente, ridimensioniamo le immagini a 256×256 pixel e infine aggiungiamo le immagini preprocessate alle rispettive liste. Dopo avere elaborato tutte le immagini nel batch, il codice converte le liste img_A e img_B in array NumPy e ridimensiona i valori dei pixel nell’intervallo [-1, 1]. Infine, restituisce le immagini elaborate come img_A e img_B.

def load_data(batch_size):    path1=sorted(glob('../test_picture/*'))    path2=sorted(glob('../test_label/*'))    i=np.random.randint(0,27)    batch1=path1[i*batch_size:(i+1)*batch_size]    batch2=path2[i*batch_size:(i+1)*batch_size]        img_A=[]    img_B=[]    for filename1,filename2 in zip(batch1,batch2):        img1=cv2.imread(filename1)        img2=cv2.imread(filename2)        img1=img1[...,::-1]        img2=img2[...,::-1]        img1=cv2.resize(img1,(256,256),interpolation=cv2.INTER_AREA)        img2=cv2.resize(img2,(256,256),interpolation=cv2.INTER_AREA)        img_A.append(img1)        img_B.append(img2)          img_A=np.array(img_A)/127.5-1    img_B=np.array(img_B)/127.5-1        return img_A,img_B 

Allo stesso modo, dobbiamo creare un’altra funzione per fare lo stesso per i dati di addestramento. In precedenza, abbiamo eseguito tutti i passaggi di preprocessing per i dati di test e infine abbiamo salvato tutte le immagini nella lista, che rimangono fino alla fine. Ma qui, per il preprocessing dei dati di addestramento, non dobbiamo conservarli tutti fino alla fine. Quindi, facciamo uso della funzione generator. L’istruzione yield viene utilizzata per creare una funzione generator. Restituisce le immagini elaborate come img_A e img_B per il batch corrente, consentendo di iterare attraverso i dati di addestramento un batch alla volta senza caricarli tutti in memoria contemporaneamente. Questa è la bellezza dei generator.

# Funzione Generatordef load_batch(batch_size):    path1=sorted(glob('../train_picture/*'))    path2=sorted(glob('../train_label/*'))    n_batches=int(len(path1)/batch_size)      for i in range(n_batches):        batch1=path1[i*batch_size:(i+1)*batch_size]        batch2=path2[i*batch_size:(i+1)*batch_size]        img_A,img_B=[],[]        for filename1,filename2 in zip(batch1,batch2):            img1=cv2.imread(filename1)            img2=cv2.imread(filename2)            img1=img1[...,::-1]            img2=img2[...,::-1]            img1=cv2.resize(img1,(256,256),interpolation=cv2.INTER_AREA)                img2=cv2.resize(img2,(256,256),interpolation=cv2.INTER_AREA)            img_A.append(img1)            img_B.append(img2)              img_A=np.array(img_A)/127.5-1        img_B=np.array(img_B)/127.5-1            yield img_A,img_B 

In seguito, definiremo una classe chiamata pix2pix in cui definiremo tutte le funzioni necessarie al suo interno. Definiremo un costruttore, un generatore, un discriminatore, un metodo di addestramento e un sample_images per visualizzare l’output. Ognuno di questi metodi verrà approfondito.

class pix2pix():    def __init__(self):      pass    def build_generator(self):      pass    def build_discriminator(self):      pass    def train(self,epochs,batch_size=1):      pass    def sample_images(self, epoch):      pass     

Metodo Costruttore

Prima di tutto, definiremo il metodo costruttore. Questo metodo inizializza gli attributi e i componenti del modello pix2pix. È un metodo unico che viene automaticamente invocato quando viene creato un oggetto di una classe. Abbiamo definito le dimensioni dell’immagine e il numero di canali. Si prevede che le immagini siano di dimensioni 256×256 pixel con 3 canali di colore (RGB). self.gf e self.df sono gli attributi che definiscono il numero di filtri (canali) per i modelli del generatore e del discriminatore, rispettivamente.

In seguito, definiremo un ottimizzatore in cui utilizzeremo un ottimizzatore Adam con un tasso di apprendimento specifico e un parametro beta per l’addestramento del modello. Successivamente, viene creato il modello del discriminatore. È configurato con la perdita di entropia incrociata binaria e l’ottimizzatore Adam definito in precedenza. Congeliamo anche i pesi del discriminatore durante l’addestramento del modello combinato. L’attributo self.combined rappresenta il modello combinato, che consiste nel generatore seguito dal discriminatore. Il generatore produce immagini false e il discriminatore ne verifica la validità. Questo modello combinato addestra il generatore a produrre immagini più realistiche.

def __init__(self):        self.img_rows = 256        self.img_cols = 256        self.channels = 3        self.img_shape = (self.img_rows, self.img_cols, self.channels)            patch = int(self.img_rows / (2**4)) # 2**4 = 16        self.disc_patch = (patch, patch, 1)            self.gf = 64        self.df = 64            optimizer = tf.keras.optimizers.legacy.Adam(learning_rate=0.0002, beta_1=0.5)            self.discriminator = self.build_discriminator()        # self.discriminator.summary()        self.discriminator.compile(loss='binary_crossentropy', optimizer=optimizer)            self.generator = self.build_generator()        # self.generator.summary()            img_A = layers.Input(shape=self.img_shape)       # immagine - etichetta        img_B = layers.Input(shape=self.img_shape)       # etichetta - reale            img = self.generator(img_A)            self.discriminator.trainable = False            valid = self.discriminator([img,img_A])            self.combined = Model(img_A, valid)        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

Generatore di costruzione

Il nostro prossimo passo è costruire un generatore. Questo metodo definisce l’architettura del modello del generatore in uno stile GAN di tipo pix2pix. All’interno di questo, abbiamo bisogno di due diverse funzioni. Sono conv2d e deconv2d. La conv2d è una funzione ausiliaria che crea uno strato convoluzionale con normalizzazione batch opzionale. Prende in input il tensore, il numero di canali, la dimensione del kernel e la bn, un booleano che indica se utilizzare la normalizzazione batch. Applica una convoluzione 2D, attivazione LeakyReLU e normalizzazione batch opzionale e restituisce il tensore risultante.

Come conv2d, questa è anche una funzione di utilità per la creazione di uno strato convoluzionale trasposto (noto anche come strato di deconvoluzione o di sovracampionamento) con eliminazione casuale e normalizzazione batch opzionale. Prende un tensore di input, un tensore di input da uno strato precedente, da concatenare con il numero di canali, la dimensione del kernel e il tasso di eliminazione casuale. Applica uno strato di sovracampionamento, una convoluzione, una attivazione, l’eliminazione casuale (se specificata), normalizzazione batch, concatenazione con input_skip e restituisce il tensore risultante.

Il modello del generatore è costituito da diversi strati, a partire da uno strato di input. Successivamente, attraversa una serie di strati convoluzionali (conv2d) e deconvoluzionali (deconv2d). Qui, d1 a d7 sono strati convoluzionali che riducono progressivamente le dimensioni aumentando il numero di canali. Allo stesso modo, u1 a u7 sono strati deconvoluzionali che aumentano progressivamente le dimensioni riducendo il numero di canali. Le connessioni di salto aiutano a preservare i dettagli fini dall’immagine di input all’output, rendendola adatta a compiti come la traduzione da immagine a immagine nel framework pix2pix. Lo strato finale è uno strato convoluzionale con una funzione di attivazione tymh. Questo produce l’immagine di output. Ha lo stesso numero di canali dell’immagine di input (self.channels) e mira a generare un’immagine simile al dominio di destinazione.

def build_generator(self):        def conv2d(layer_input, filters, f_size=(4,4), bn=True):            d = layers.Conv2D(filters, kernel_size=f_size, strides=(2,2),            padding='same')(layer_input)            d = layers.LeakyReLU(0.2)(d)            if bn:                d = layers.BatchNormalization()(d)            return d            def deconv2d(layer_input, skip_input, filters, f_size=(4,4), dropout_rate=0):            u = layers.UpSampling2D((2,2))(layer_input)            u = layers.Conv2D(filters, kernel_size=f_size, strides=(1,1),            padding='same', activation='relu')(u)            if dropout_rate:                u = layers.Dropout(dropout_rate)(u)            u = layers.BatchNormalization()(u)            u = layers.Concatenate()([u, skip_input])            return u            d0 = layers.Input(shape=self.img_shape)            d1 = conv2d(d0, self.gf, bn=False)         d2 = conv2d(d1, self.gf*2)                 d3 = conv2d(d2, self.gf*4)                 d4 = conv2d(d3, self.gf*8)                 d5 = conv2d(d4, self.gf*8)                 d6 = conv2d(d5, self.gf*8)                    d7 = conv2d(d6, self.gf*8)                     u1 = deconv2d(d7, d6, self.gf*8, dropout_rate=0.5)           u2 = deconv2d(u1, d5, self.gf*8, dropout_rate=0.5)           u3 = deconv2d(u2, d4, self.gf*8, dropout_rate=0.5)           u4 = deconv2d(u3, d3, self.gf*4)           u5 = deconv2d(u4, d2, self.gf*2)           u6 = deconv2d(u5, d1, self.gf)             u7 = layers.UpSampling2D((2,2))(u6)            output_img = layers.Conv2D(self.channels, kernel_size=(4,4), strides=(1,1),        padding='same', activation='tanh')(u7)            return Model(d0, output_img)

Costruire il discriminatore

Il nostro prossimo passo è quello di costruire un modello discriminatore. Questo metodo definisce l’architettura del modello discriminatore in uno stile GAN pix2pix. Simile alla funzione conv2d nel generatore, qui definiremo la funzione d_layer. Questa funzione di supporto crea uno strato convoluzionale con normalizzazione batch opzionale. Prende in input il tensore di input, il numero di canali, le dimensioni del kernel e bn, un booleano che indica se utilizzare la normalizzazione batch. Applica una convoluzione 2D, l’attivazione LeakyReLU e la normalizzazione batch opzionale e restituisce il tensore risultante. Il modello discriminatore ha due strati di input, img_A e img_B, ciascuno con una forma definita da self.img_shape.

Questi input rappresentano coppie di immagini: una dal dominio di origine (img_A) e una dal dominio di destinazione (img_B). Le immagini di input img_A e img_B vengono concatenate lungo l’asse dei canali (axis=-1) per creare immagini combinate. L’architettura del discriminatore è composta da strati convoluzionali, da d1 a d4, con filtri crescenti. Questi strati ridimensionano le dimensioni spaziali dell’immagine di input mentre estraggono le caratteristiche. L’ultimo strato è uno strato convoluzionale con una funzione di attivazione sigmoide. Produce un’uscita a singolo canale che rappresenta la probabilità che la coppia di immagini di input sia reale o falsa. Utilizza questa uscita per classificare la coppia di immagini di input come reale o falsa.

def build_discriminator(self):        def d_layer(layer_input,filters,f_size=(4,4),bn=True):            d=layers.Conv2D(filters,kernel_size=f_size,strides=(2,2),            padding='same')(layer_input)            d=layers.LeakyReLU(0.2)(d)            if bn:                d=layers.BatchNormalization()(d)            return d            img_A=layers.Input(shape=self.img_shape)        img_B=layers.Input(shape=self.img_shape)            combined_imgs=layers.Concatenate(axis=-1)([img_A,img_B])            d1=d_layer(combined_imgs,self.df,bn=False)        d2=d_layer(d1,self.df*2)        d3=d_layer(d2,self.df*4)        d4=d_layer(d3,self.df*8)            validity=layers.Conv2D(1,kernel_size=(4,4),strides=(1,1),padding='same',        activation='sigmoid')(d4)            return Model([img_A,img_B],validity)

Allenamento

Dobbiamo creare il metodo di allenamento che allena il modello quando viene invocato. L’array “valid” è composto da uno in forma di array numpy, che rappresenta le etichette di immagine reali. Allo stesso modo, l’array “fake” è composto da zeri in un array numpy, che rappresentano le etichette di immagini false (generate). Successivamente, iniziamo un ciclo for per iterare attraverso il numero designato di epoche. In ogni epoca, avviamo un timer per registrare il tempo impiegato per quella specifica epoca. Viene utilizzato un generatore per caricare i dati di addestramento a batch all’interno di ogni epoca, che restituisce coppie di immagini, img_A (input) e img_B (target).

Il generatore utilizza le immagini di input per produrre immagini. Il discriminatore viene allenato per classificare le coppie di immagini reali come reali, calcolando la perdita per le immagini reali. Allo stesso modo, il discriminatore viene allenato per classificare le coppie di immagini generate come false, calcolando successivamente la perdita per le immagini false. La perdita totale del discriminatore viene determinata dalla media delle perdite per le immagini reali e false. L’obiettivo di allenamento del generatore è generare immagini che ingannino il discriminatore facendole classificare come reali.

def train(self,epochs,batch_size=1):        valid=np.ones((batch_size,)+self.disc_patch)        fake=np.zeros((batch_size,)+self.disc_patch)            for epoch in range(epochs):            start=time.time()            for batch_i,(img_A,img_B) in enumerate(load_batch(1)):                gen_imgs=self.generator.predict(img_A)                        d_loss_real = self.discriminator.train_on_batch([img_B, img_A], valid)                d_loss_fake = self.discriminator.train_on_batch([gen_imgs, img_A], fake)                d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)                        g_loss = self.combined.train_on_batch(img_A,valid)                if batch_i % 500 == 0:                    print ("[Epoca %d] [Batch %d] [Perdita D: %f] [Perdita G: %f]" % (epoch,batch_i,                                                                                d_loss,g_loss))                        self.sample_images(epoch)            print('Il tempo per l\'epoca {} è {} sec'.format(epoch,time.time()-start))

Visualizzazioni

Il metodo sample_images genera e visualizza immagini di esempio per visualizzare i progressi del generatore durante l’allenamento. Qui r e c sono impostati su 3, indicando che la griglia di immagini visualizzate avrà 3 righe e 3 colonne. Qui vengono caricate 3 coppie di immagini di input e target. Il generatore viene utilizzato per generare immagini finte basate sulle immagini di input. Le immagini vengono quindi concatenate in un singolo array per scopi di visualizzazione. I valori dei pixel vengono ridimensionati dall’intervallo [-1, 1] a [0, 1] per una corretta visualizzazione. Le immagini vengono visualizzate sugli assi secondari. La figura viene salvata come file immagine con il numero di epoca come nome file.

def campione_immagini(self, epoca):        r, c = 3, 3        img_A, img_B =load_data(3)        fake_A = self.generator.predict(img_A)        gen_imgs = np.concatenate([img_A, fake_A, img_B])        # Ridimensiona le immagini da 0 a 1        gen_imgs = 0.5 * gen_imgs + 0.5        titoli = ['Immagine di input', 'Immagine predetta', 'Ground Truth']        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])                axs[i,j].set_title(titoli[i])                axs[i,j].axis('off')                cnt += 1        fig.savefig("./%d.png" % (epoca))        plt.show()

Risultati

Dopo aver definito tutti i metodi necessari, devi chiamare il metodo principale. Crea un oggetto chiamato gan della classe pix2pix. Quindi, addestra il modello specificando il numero di epoche e la dimensione del batch.

Dopo ogni epoca, l’immagine predetta verrà visualizzata insieme alle immagini di input e ground truth. Man mano che l’addestramento continua, è possibile osservare i cambiamenti nell’immagine. Man mano che il numero di epoche aumenta, l’immagine sarà più precisa. Alla fine, otterrai un’immagine indistinguibile dall’immagine ground truth. Questa è la potenza delle GAN.

if __name__ == '__main__':    gan = pix2pix()    gan.train(epoche=50, dimensione_batch=1)

Risultato della 1° epoca:

Dopo 10 epoche, il risultato è:

Risultato dopo 50 epoche:

Conclusioni

Il successo di Pix2Pix risiede nella sua capacità di apprendere dai dati e generare immagini che non sono solo realistiche ma anche artisticamente espressive. Che si tratti di convertire scene diurne in scene notturne o di trasformare foto in bianco e nero in colori vibranti, Pix2Pix ha dimostrato la propria capacità. Pix2Pix è diventato un superpotere creativo consentendo ad artisti e designer di trasformare e manipolare immagini in modi innovativi e immaginativi. Man mano che la tecnologia continua a progredire, Pix2Pix apre ancora più fantastiche opportunità. È un campo entusiasmante da esplorare per chiunque ami combinare arte e intelligenza artificiale.

Punti chiave

  • Pix2Pix è un amico computer intelligente che ci aiuta a creare immagini incredibili dalle nostre idee. È come magia per il mondo digitale!
  • Pix2Pix è diventato una tecnologia rivoluzionaria nella visione artificiale e nell’elaborazione delle immagini.
  • Offre possibilità entusiasmanti ma anche sfide, come la stabilità dell’addestramento e la necessità di set di dati consistenti.
  • Il Magenta Studio di Google, un progetto di ricerca che esplora l’apprendimento automatico e l’arte, ha utilizzato Pix2Pix per creare diversi strumenti per l’arte.
  • In questo articolo, abbiamo visto come funziona effettivamente Pix2Pix e compreso la sua potenza magica.
  • Abbiamo imparato come utilizzare Pix2Pix con i dati della facciata degli edifici per trasformare i disegni in immagini di edifici dall’aspetto reale, ottenendo così una comprensione pratica.

Domande frequenti

I contenuti multimediali mostrati in questo articolo non sono di proprietà di Analytics Vidhya e vengono utilizzati a discrezione dell’autore.