Menü Kapat

Üretken Çekişmeli Ağlar Kullanarak Kedi Üretmek ve Temel Bileşen Analizi

Amaç

Bu makale size Keras kitaplığı kullanılarak yazılan bir Üretken Çekişme Ağı’nın genel çerçevesini sağlayacaktır. Kendi görüntü veri kümelerinizi kullanarak üretken modelleri eğitmek için bu genel GAN şablonunu kullanabileceksiniz.

Kodun tam sürümü bu GitHub deposunda mevcuttur.

Veri Kümesi

Bu proje için kullandığım veri seti Kaggle’dan indirilebilir. Modeli eğitmek için 64×64 kedi resimlerinden oluşan bir veri kümesi kullandım. Görüntüler arasında ne kadar az fark olduğundan, bu veri kümesiyle GAN’lar için çalışmak özellikle kolaydır. Çılgınca değişen görüntülere sahip diğer veri kümeleri, Generative Adversarial Network’ünüzün yakınsamasını zorlaştırabilir.
 
Bu denetimli öğrenme görevinde, bu kedi resimleri veri setimizdeki Y değerleridir. Görüntüler, üretken modellerimizin çıkardığı şeylerdir. Şimdi soru, resimlerimize girdi olarak eşlemek için X değerlerimiz olarak ne kullanacağımızdır. Bu görüntüleri rastgele bir gürültü dağılımıyla eşleştirebiliriz. Bu temel teknik, belirli veri kümeleri için işe yarar. Aşağıdaki bu GIF, bir üretici modelin gizli uzayındaki ara değerli noktalar aracılığıyla örneklemeyi gösterir.
Bu model, girdi olarak Gauss gürültünün dağılımı ve çıktı olarak aynı veri kümesi kullanılarak eğitilmiştir. Model, girdinin rastgeleliği göz önüne alındığında yakınsamada mücadele etti ve ifade edici olmayan çıktılarla vasat sonuçlar üretti.
 
Veri kümesine bağlı olarak, görüntülere eşlenen rastgele girdileri kullanmak, belirli GAN’ların yakınsaması için yeterince iyi olabilir. Klasik MNIST kıyaslama veri kümesi, rastgele girdilerle çalışmak için yeterince basittir. Bu Etkileşimli GAN ayrıca, çok düşük varyanslı bir veri kümesine eşlenmiş bir Gauss gürültü dağılımı kullanılarak eğitildi.
 
Ancak nihayetinde, bu teknikle ilgili sorun, Sinir Ağlarının girdi olarak tamamen rastgele sayılar kullanarak veri kümesinden görüntüleri yeniden oluşturmasının zor olmasıdır. İdeal olarak, veri setimizin X değerleri, veri setimizdeki Y değeri görüntülerinin anlamlı bir temsili olacaktır. Bu, Generator modelinin çıktıyı örneklemek ve doğru bir şekilde yeniden oluşturmak için girdide anlamlı ayrıntılar bulmasına olanak tanır. Şimdi soru, veri setimizdeki her Y değeri görüntüsüyle uyumlu anlamlı X değerlerini nasıl oluşturabiliriz?
 
Bu bizi, Temel Bileşen Analizi (PCA) adı verilen denetimsiz bir öğrenme tekniğine götürür. PCA, verileri veri kümesinin kovaryans matrisinin Öz vektörlerine yansıtarak verileri daha düşük bir boyuta yansıtmamızı sağlar. Bu tekniği kullanarak, veri setimizdeki her 64x64x3 görüntüyü 512 elemanlı bir vektöre yansıtabiliyoruz. Bu, bilgilerin %95,3’ünü korurken verileri depolamak için alanın %4,16’sını kullanmaya eşdeğerdir. Veri setimizde sahip olduğumuz her çıktı görüntüsü için anlamlı bir girdi vektörü bu şekilde elde edeceğiz. Bu verileri işlemenin arkasındaki kod, load_data() yönteminde tam olarak açıklanacaktır.

Girdiler

Girdi [1]:
from keras.layers import Input, Dense, Reshape, Flatten
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.convolutional import UpSampling2D, Conv2D, MaxPooling2D
from keras.models import Sequential, Model
from keras.optimizers import Adam
from sklearn.utils import shuffle
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
import os
from PIL import Image
 
Using TensorFlow backend
Bu proje aşağıdaki kitaplıkları gerekiyor;
  • Keras (2.3.1 kullanıyorum)
  • Tensorflow (1.14.0 kullanıyorum)
  • Sklearn
  • Scipy
  • Numpy
  • Matplotlib
  • PIL
  • Keract (Model Görselleştirme için İsteğe Bağlı)

Parametreleri Ayarlayın

Başlangıç olarak, yerel dosya yolları ve Sinir Ağlarının ayarları ile ilgili parametreleri tanımlayacağız. Mevcut parametreler, 8 GB VRAM’li bir GPU’da kullanılmak üzere tasarlanmıştır. Daha az güçlü bir GPU ile çalışıyorsanız, evrişimli filtrelerin sayısını ve çekirdek boyutunu buna göre azaltın. Bellek kısıtlamaları nedeniyle toplu iş boyutu da azaltılabilir. Kendi veri kümenizi kullanmak istiyorsanız, veri yolunu görüntüleri içeren klasöre işaret edecek şekilde ayarlayın. Görüntüler PNG ise, png Boolean değişkenini True olarak ayarlayın. Bu, load_data() içindeki veri önişleme sırasında görüntülerden alfa katmanını kaldıracaktır.
 
Girdi [2]:
# Folder containing dataset
data_path = r'D:\Downloads\cats-faces-64x64-for-generative-models\cats'

# Dimensions of the images inside the dataset
img_dimensions = (64,64,3)

# Folder where you want to save to model as well as generated samples
model_path = r"C:\Users\Vee\Desktop\python\GAN\pca_new"

# How many epochs between saving your model
interval = 10

# How many epochs to run the model
epoch = 500

# How many images to train at one time.
# Ideally this number would be a factor of the size of your dataset
batch = 181

# How many convolutional filters for each convolutional layer of the generator and the discrminator
conv_filters = 64

# Size of kernel used in the convolutional layers
kernel = (5,5)

# Boolean flag, set to True if the data has pngs to remove alpha layer from images
png = False

Derin Evrişimli GAN Sınıfı Oluşturun

Bu sınıf 8 yöntem içerir.
  • __init __ (self): Sınıf, girdi vektörünün boyutları ve çıktı görüntüsü tanımlanarak başlatılır. Generator ve Discriminator modelleri build_generator() ve build_discriminator() kullanılarak başlatılır.
  • build_generator(self): Generator modelini tanımlar. 8x8x8’den 64x64x3’e yukarı örneklenen 5 evrişimli katman vardır. DCGAN sınıfı başlatıldığında çağrılır.
  • build_discriminator(self): Discriminator modelini tanımlar. 64x64x3’ten 1 skaler tahmine altörneklenen 5 evrişimli katman vardır. DCGAN sınıfı başlatıldığında çağrılır.
  • load_data(self): Kullanıcı tarafından belirtilen dosya yolundan, data_path verileri yükler. Görüntü veri kümesini X_Train veri kümesi olarak daha düşük bir boyuta yansıtmak için PCA kullanır. Görüntü veri kümesini işler ve Y_Train veri kümesi için 4 boyuta yeniden şekillendirir. train() yönteminde çağrılır.
  • train(self, epochs, batch_size, save_interval): Generative Adversarial Network’ü eğitir. Her dönem modeli, batch_size ile tanımlanan parçalara ayrılmış veri kümesinin tamamını kullanarak eğitir. Dönem, save_interval‘deyse, yöntem, örnekleri oluşturmak için save_imgs() öğesini çağırır ve mevcut dönemin modelini kaydeder.
  • save_imgs (self, epoch, gen_imgs, y_points): Modeli kaydeder ve kullanıcı tarafından belirtilen yol, model_path‘ta belirli bir dönem için tahmin örnekleri oluşturur. Her örnek, oluşturulan 8 tahmin ve 8 eğitim örneği içerir.

Başlatma

Girdi [3]:
class DCGAN():
    
    # Initialize parameters, generator, and discriminator models
    def __init__(self):
        
        # Set dimensions of the output image
        self.img_rows = img_dimensions[0]
        self.img_cols = img_dimensions[1]
        self.channels = img_dimensions[2]
        self.img_shape = (self.img_rows, self.img_cols, self.channels)
        
        # Set dimensions of the input noise
        self.latent_dim = 512
        
        # Chose optimizer for the models
        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()
        generator = self.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
        valid = self.discriminator(img)

        # The combined model  (stacked generator and discriminator)
        # Trains the generator to fool the discriminator
        self.combined = Model(z, valid)
        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

DCGAN sınıfı başlatıldığında, Sinir Ağının veri setinden beklemesi gereken görüntülerin boyutunu tanımlarız. Bu, Tuple img_dimensions tarafından belirtilir. Ayrıca, PCA’dan oluşturulan girdi vektörümüzün boyutu olan gizli boyutları da tanımlarız. Bu, latent_dim tamsayısı ile belirtilir.

Her iki model için de kullandığımız optimize edici, Adam optimize edicidir. Optimize edicinin öğrenme oranı ve beta değerleri ile denemekten çekinmeyin ve ne tür sonuçlar aldığınızı görün.

Generative Adversarial Network’ün mimarisi, her iki modelde İkili Çapraz Entropi kaybını kullanarak burada tanımlanmıştır. Kayıp fonksiyonu olarak İkili Çapraz Entropi seçimi burada açıklanmıştır. Diğer kayıp fonksiyonlarını denemekten çekinmeyin, ancak her iki modelin de aynı kayıp fonksiyonunu kullanması gerektiğini unutmayın.

Veri yükle

Girdi [3]:
class DCGAN():
    
    # Initialize parameters, generator, and discriminator models
    def __init__(self):
        
        # Set dimensions of the output image
        self.img_rows = img_dimensions[0]
        self.img_cols = img_dimensions[1]
        self.channels = img_dimensions[2]
        self.img_shape = (self.img_rows, self.img_cols, self.channels)
        
        # Set dimensions of the input noise
        self.latent_dim = 512
        
        # Chose optimizer for the models
        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()
        generator = self.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
        valid = self.discriminator(img)

        # The combined model  (stacked generator and discriminator)
        # Trains the generator to fool the discriminator
        self.combined = Model(z, valid)
        self.combined.compile(loss='binary_crossentropy', optimizer=optimizer)

DCGAN sınıfına eklediğimiz ilk yöntem load_data() ‘dır. Bu, kullanıcının belirlediği yol olan data_path içindeki tüm görüntüleri önceden işleyecektir. Bu yöntem, eğitimden önce verileri yüklemek için train() yönteminin içinde çağrılır.

Bu, veri kümesinin PCA kullanılarak daha düşük boyutlu bir alana yansıtıldığı yerdir. Sklearn PCA yöntemi, aktarılan verilerin 2 boyutlu olmasını gerektirir, bu nedenle 64x64x3 resimleri 12288 vektör olacak şekilde sıkıştırıyoruz. Ayrıca verileri 0 ile 1 arasında olacak şekilde normalleştiriyoruz. RGB piksel değerleri 0 ile 255 arasında değişir, bu nedenle yeniden şekillendirilmiş vektörü 255’e böleriz.

Son olarak, iki diziyi döndürmeden önce train() veri kümelerini karıştırıyoruz. Veri kümesindeki modelleri sıralı olarak eğitmek için train() yöntemini yazdım, her yinelemede toplu iş boyutunu artırdım. Bu nedenle, veri kümesinin sıralı olarak sıralanma şekline ilişkin tuhaf önyargılar getirmemek için veri kümesini karıştırmak önemlidir.

Oluşturucu İnşa Etmek

 # Define Generator model. There are 5 convolutional filters, upsampling from (8x8x8) to (64x64x3)
    def build_generator(self):

        model = Sequential()
        
        # Input Layer
        model.add(Dense(8 * 8 * 8, input_dim=self.latent_dim))
        model.add(Reshape((8, 8, 8)))
        
        # 1st Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, padding="same"))
        model.add(LeakyReLU(alpha=0.2))
        
        # Upsample the data (8x8 to 16x16)
        model.add(UpSampling2D())
        
        # 2nd Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, padding="same"))
        model.add(LeakyReLU(alpha=0.2))
        
        # Upsample the data (16x16 to 32x32)
        model.add(UpSampling2D())

        # 3rd Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, padding="same"))
        model.add(LeakyReLU(alpha=0.2))
        
        # Upsample the data (32x32 to 64x64)
        model.add(UpSampling2D())

        # 4th Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, padding="same"))
        model.add(LeakyReLU(alpha=0.2))
        
        # 5th Convolutional Layer (Output Layer)
        model.add(Conv2D(3, kernel_size=kernel, padding="same"))
        model.add(LeakyReLU(alpha=0.2))
        model.summary()

        noise = Input(shape=(self.latent_dim,))
        img = model(noise)

        return Model(noise, img)

DCGAN sınıfına eklediğimiz ikinci yöntem build_generator()‘dır. Bu yöntem, sınıf ilk kez başlatıldığında çağrılır. Generator modelinin mimarisi burada tasarlanmıştır. Model özeti, bu modelde gerçekte neler olduğu konusunda size daha net bir fikir verecektir.

Generator modelinin girdisi 512 sayılık bir vektördür. Vektör daha sonra 8x8x8 tensöre yeniden şekillendirilir. Bu tensör daha sonra 16×16, 32×32 ve son olarak 64×64’e yükseltilir. Çıktı Evrişimli katmanı, RGB görüntüsünün sırasıyla Kırmızı, Yeşil ve Mavi kanallarını temsil eden 3 filtre içerir.

Ayrımcı (Discriminator) Oluşturun

    # Define Discriminator model. There are 5 convolutional filters, downsampling from (64x64x3) to (1) scalar prediction
    def build_discriminator(self):

        model = Sequential()

        # Input Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, input_shape=self.img_shape,activation = "relu", padding="same"))
        
        # Downsample the data (64x64 to 32x32)
        model.add(MaxPooling2D(pool_size=(2, 2)))
        
        # 1st Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, activation='relu', padding="same"))
        
        # Downsample the data (32x32 to 16x16)
        model.add(MaxPooling2D(pool_size=(2, 2)))
        
        # 2nd Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, activation='relu', padding="same"))
        
        # Downsample the data (16x16 to 8x8)
        model.add(MaxPooling2D(pool_size=(2, 2)))
        
        # 3rd Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, activation='relu', padding="same"))
        
        # 4th Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, activation='relu', padding="same"))
        
        # 5th Convolutional Layer
        model.add(Conv2D(conv_filters, kernel_size=kernel, activation='relu', padding="same"))
        
        model.add(Flatten())
        
        # Output Layer
        model.add(Dense(1, activation='sigmoid'))

        model.summary()

        img = Input(shape=self.img_shape)
        validity = model(img)

        return Model(img, validity)

DCGAN sınıfına eklediğimiz üçüncü yöntem build_discriminator() ‘dür. Bu yöntem, sınıf ilk kez başlatıldığında çağrılır. Discriminator modelinin mimarisi burada tasarlanmıştır. Model özeti, bu modelde gerçekte neler olduğu konusunda size daha net bir fikir verecektir.

Discriminator modelinin girdisi 64x64x3 tensördür. Tensör daha sonra 32×32, 16×16 ve 8×8’e alt örneklenir. Bu 8×8 tensör daha sonra düzleştirilir ve çıktı katmanına aktarılır. Son yoğun katman, ayırıcı modelin tahminini temsil eden tek bir skaler sayı verir. Bu tahmin, giriş görüntüsünün “gerçek” olup olmadığını belirlemede modelin güvenini temsil eder. 1 tahmini, modelin görüntünün orijinal veri kümesinden geldiğini düşündüğü anlamına gelir. 0 tahmini, modelin görüntünün Generator modeli tarafından oluşturulduğunu düşündüğü anlamına gelir.

Eğitmek

 # Train the Generative Adversarial Network
    def train(self, epochs, batch_size, save_interval):
        
        # Prevent script from crashing from bad user input
        if(epochs <= 0):
            epochs = 1
        
        if(batch_size <= 0):
            batch_size = 1

        # Load the dataset
        X_train, Y_train = self.load_data()
        
        # Normalizing data to be between 0 and 1
        Y_train = Y_train/255

        # Adversarial ground truths
        valid = np.ones((batch_size, 1))
        fake = np.zeros((batch_size, 1))
        
        # Placeholder arrays for Loss function values
        g_loss_epochs = np.zeros((epochs, 1))
        d_loss_epochs = np.zeros((epochs, 1))
        
        # Training the GAN
        for epoch in range(1, epochs + 1):
            
            # Initialize indexes for training data
            start = 0
            end = start + batch_size
            
            # Array to sum up all loss function values
            discriminator_loss_real = []
            discriminator_loss_fake = []
            generator_loss = []
            
            # Iterate through dataset training one batch at a time
            for i in range(int(len(X_train)/batch_size)):
                
                # Get batch of images
                imgs = Y_train[start:end]
                noise = X_train[start:end]

                # ---------------------
                #  Train Discriminator
                # ---------------------

                # Make predictions on current batch using generator
                gen_imgs = self.generator.predict(noise)

                # Train the discriminator (real classified as ones and generated as zero)
                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
                # ---------------------

                # Train the generator (wants discriminator to mistake images as real)
                g_loss = self.combined.train_on_batch(noise, valid)
                
                # Add loss for current batch to sum over entire epoch
                discriminator_loss_real.append(d_loss[0])
                discriminator_loss_fake.append(d_loss[1])
                generator_loss.append(g_loss)
                
                # Increment image indexes
                start = start + batch_size
                end = end + batch_size
             
            
            # Get average loss over the entire epoch
            loss_data = [np.average(discriminator_loss_real),np.average(discriminator_loss_fake),np.average(generator_loss)]
            
            #save loss history
            g_loss_epochs[epoch - 1] = loss_data[2]
            
            # Average loss of real data classification and fake data accuracy
            d_loss_epochs[epoch - 1] = (loss_data[0] + (1 - loss_data[1])) / 2
                
            # Print average loss over current epoch
            print ("%d [D loss: %f, acc.: %.2f%%] [G loss: %f]" % (epoch, loss_data[0], loss_data[1]*100, loss_data[2]))

            # If epoch is at intervale, save model and generate image samples
            if epoch % save_interval == 0:
                
                # Select 8 random indexes
                idx = np.random.randint(0, X_train.shape[0], 8)
                # Get batch of generated images and training images
                x_points = X_train[idx]
                y_points = Y_train[idx]
                
                # Plot the predictions next to the training imgaes
                self.save_imgs(epoch, self.generator.predict(x_points), y_points)
                
        return g_loss_epochs, d_loss_epochs
    
    # Save the model and generate prediction samples for a given epoch
    def save_imgs(self, epoch, gen_imgs, y_points):
        
        # Define number of columns and rows
        r, c = 4, 4
        
        # Placeholder array for MatPlotLib Figure Subplots
        subplots = []
        
        # Unnormalize data to be between 0 and 255 for RGB image
        gen_imgs = np.array(gen_imgs) * 255
        gen_imgs = gen_imgs.astype(int)
        y_points = np.array(y_points) * 255
        y_points = y_points.astype(int)
        
        # Create figure with title
        fig = plt.figure(figsize= (40, 40))
        fig.suptitle("Epoch: " + str(epoch), fontsize=65)
        
        # Initialize counters needed to track indexes across multiple arrays
        img_count = 0;
        index_count = 0;
        y_count = 0;
        
        # Loop through columns and rows of the figure
        for i in range(1, c+1):
            for j in range(1, r+1):
                # If row is even, plot the predictions
                if(j % 2 == 0):
                    img = gen_imgs[index_count]
                    index_count = index_count + 1
                # If row is odd, plot the training image
                else:
                    img = y_points[y_count]
                    y_count = y_count + 1
                # Add image to figure, add subplot to array
                subplots.append(fig.add_subplot(r, c, img_count + 1))
                plt.imshow(img)
                img_count = img_count + 1
        
        # Add title to columns of figure
        subplots[0].set_title("Training", fontsize=45)
        subplots[1].set_title("Predicted", fontsize=45)
        subplots[2].set_title("Training", fontsize=45)
        subplots[3].set_title("Predicted", fontsize=45)
                
        # Save figure to .png image in specified folder
        fig.savefig(model_path + "\\epoch_%d.png" % epoch)
        plt.close()
        
        # save model to .h5 file in specified folder
        self.generator.save(model_path + "\\generator" + str(epoch) + ".h5")

DCGAN sınıfına eklediğimiz dördüncü yöntem train(). Bu yöntem, ağı toplu iş boyutu tarafından belirtilen artışlarla belirtilen sayıda dönem için eğitecektir. Eğitim tamamlandığında, yöntem her dönem boyunca her iki modelin kayıp değerlerini temsil eden iki dizi döndürecektir. Kayıp değerleri Matplotlib kullanılarak çizilebilir.

Kayıp değerlerini takip etmeli ve çökmeye başlarsa ağı eğitmeyi bırakmalısınız. Modellerden biri 0 kaybına yaklaşırsa ağ çöker.

Generator 0 kaybına yaklaşırsa, bu, Generator’un her seferinde ayırıcıyı kandıracak bir görüntüyü nasıl oluşturacağını bulduğu anlamına gelir. Bu genellikle Generator’ün mod çökmesi olarak da bilinen tek bir görüntü türü üretmesine neden olur.

Discriminator, 0 kaybına yaklaşırsa, bu, Discriminator’ın eğitim verileri ile oluşturulan görüntüleri çok doğru bir şekilde nasıl ayırt edeceğini bulduğu anlamına gelir. Bu, Generator’ün, kaybolan gradyan problemi olarak da bilinen, ayırıcıdan öğrenmeye devam edememesine neden olacaktır.

Ağımız çöktüğünde ilerlememizi kaybetmemek için, modeli her birkaç dönemde bir kaydedeceğiz. Kullanıcı tanımlı parametre olan interval, modelin ne sıklıkla kaydedileceğini belirleyecektir. Geçerli dönem tanımlanan aralığa her geldiğinde, save_imgs() çağrılır. Yöntem, modelin o dönemde ne kadar iyi olduğuna dair bir anlık görüntü elde etmek için tahmin edilen bazı örneklerin bir görüntüsünü kaydedecektir.

Görüntüleri Kaydedin

    # Save the model and generate prediction samples for a given epoch
    def save_imgs(self, epoch, gen_imgs, y_points):
        
        # Define number of columns and rows
        r, c = 4, 4
        
        # Placeholder array for MatPlotLib Figure Subplots
        subplots = []
        
        # Unnormalize data to be between 0 and 255 for RGB image
        gen_imgs = np.array(gen_imgs) * 255
        gen_imgs = gen_imgs.astype(int)
        y_points = np.array(y_points) * 255
        y_points = y_points.astype(int)
        
        # Create figure with title
        fig = plt.figure(figsize= (40, 40))
        fig.suptitle("Epoch: " + str(epoch), fontsize=65)
        
        # Initialize counters needed to track indexes across multiple arrays
        img_count = 0;
        index_count = 0;
        y_count = 0;
        
        # Loop through columns and rows of the figure
        for i in range(1, c+1):
            for j in range(1, r+1):
                # If row is even, plot the predictions
                if(j % 2 == 0):
                    img = gen_imgs[index_count]
                    index_count = index_count + 1
                # If row is odd, plot the training image
                else:
                    img = y_points[y_count]
                    y_count = y_count + 1
                # Add image to figure, add subplot to array
                subplots.append(fig.add_subplot(r, c, img_count + 1))
                plt.imshow(img)
                img_count = img_count + 1
        
        # Add title to columns of figure
        subplots[0].set_title("Training", fontsize=45)
        subplots[1].set_title("Predicted", fontsize=45)
        subplots[2].set_title("Training", fontsize=45)
        subplots[3].set_title("Predicted", fontsize=45)
                
        # Save figure to .png image in specified folder
        fig.savefig(model_path + "\\epoch_%d.png" % epoch)
        plt.close()
        
        # save model to .h5 file in specified folder
        self.generator.save(model_path + "\\generator" + str(epoch) + ".h5")

DCGAN sınıfına eklediğimiz beşinci ve son yöntem, save_imgs() yöntemidir. Bu yöntem, modeli mevcut çağda kaydedecek ve tahmin edilen değerlerin yanı sıra 8 eğitim görüntüsünü çizecektir.

Bu yöntem şu anda her 5 çağda bir kaydedecek şekilde yapılandırılmıştır. Bu, aralık (interval) parametresi ile ayarlanabilir. Modelinizi sık sık kaydetmek, eğitim sürecinde ağınızın kaydettiği ilerlemeyi izlemenin iyi bir yoludur.

DCGAN Sınıfını Başlatma

Artık DCGAN sınıfını oluşturmayı bitirdik ve Generative Adversarial Network’ümüzü eğitmeye hazırız. Öncelikle, sınıfın bir örneğini oluşturmalı ve onu bir değişkene atamalıyız.

Girdi [4]:

dcgan = DCGAN()

Bu, Generator ve Discriminator modellerini başlatacak ve bunların özetlerini yazdıracaktır.

Üretken Çekişmeli Ağın Eğitimi

Artık DCGAN sınıf nesnemize sahip olduğumuza göre, eğitime başlamak için train() yöntemini çağırmamız gerekiyor. Bu komut dosyasıyla, genellikle eğitim için çok sayıda dönem seçmeli ve süreç boyunca kayıp değerlerini izlemelisiniz. Ağ çökmeye başlarsa eğitimi erken durdurun ve hangi modelin en iyi performans gösteren model olduğunu bulmak için oluşturulan örnekleri kontrol edin.

Train() yöntemi, eğitim boyunca iki modelin kayıp değerlerini içeren iki dizi döndürür. Bu değerleri g_loss ve d_loss’a atayacağız ve grafiğini çizeceğiz.

Girdi [5]:

g_loss, d_loss = dcgan.train(epochs=epoch, batch_size=batch, save_interval=interval)
1 [D loss: 0.680393, acc.: 61.54%] [G loss: 0.732704]
2 [D loss: 0.654482, acc.: 60.98%] [G loss: 0.835647]
3 [D loss: 0.680507, acc.: 59.27%] [G loss: 0.832127]
4 [D loss: 0.667612, acc.: 61.23%] [G loss: 0.890128]
5 [D loss: 0.678923, acc.: 57.80%] [G loss: 0.878026]
6 [D loss: 0.669563, acc.: 59.07%] [G loss: 0.857507]
7 [D loss: 0.674293, acc.: 59.85%] [G loss: 0.880131]
8 [D loss: 0.667477, acc.: 58.76%] [G loss: 0.876913]
9 [D loss: 0.663820, acc.: 59.30%] [G loss: 0.891338]
10 [D loss: 0.659955, acc.: 59.45%] [G loss: 0.909291]

Plot Kaybı

Girdi [6]:
plt.plot(g_loss)
plt.plot(d_loss)
plt.title('GAN Loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Generator', 'Discriminator'], loc='upper left')
plt.show()

Sonuç

Bu makale size Keras kullanarak bir Üretken Çekişmeli Ağı eğitmek için genel bir çerçeve sağlar. Bu komut dosyasını kullanarak kendi veri kümelerinizle kendi üretken modellerinizi oluşturabileceksiniz. Bu kodun tam sürümüne buradan ulaşabilirsiniz. Komut dosyası şu anda 64×64 görüntüler için yapılandırılmıştır. Farklı boyuttaki görüntülere sahip veri kümelerini kullanmak istiyorsanız, img_dimensions parametresini ayarlamanız ve buna göre UpSampling2D ve MaxPooling2D katmanlarını ayarlamanız gerekir.

Memnun olduğunuz bir modeli eğittikten sonra, çıktılar oluşturmak ve sonuçlarınızı analiz etmek için PCA GAN Çıkarım komut dosyasını kullanabilirsiniz. Bu komut dosyası ayrıca, makalenin başında sağlananlar gibi Generator modelinin gizli alanında yürüyen GIF’ler oluşturmak için kod sağlayacaktır.

Modeliniz bir tahmin yaptığında her evrişimli katmanda neler olup bittiğine bakmak için Model Görselleştirme komut dosyasını da kullanabilirsiniz.

Github

Veri kümesi

Jupyter Notebook

tr_TRTurkish