Üretici Çekişmeli Ağlar (Generative Adversarial Networks) ile Yeni Yüz Görüntüleri Üretme

Son zamanlarda çok iyi ve ümit vadeden sonuçlar ile karşımıza çıkan ve kısaca GAN olarak bilinen Üretici Çekişmeli Ağlar (Generative Adversarial Networks) görsel olarak gerçekçi görüntüler üretmektedir. Bu yazıda 200.000’den fazla görüntü içeren The CelebFaces Attributes Dataset (CelebA)  veri seti kullanılarak, gerçek yüz görüntülerinin nasıl elde edildiğini inceleyeceğiz [1] .

CelebA veri setinden ilk 25 görüntü:

%matplotlib inline
import os
from glob import glob
from matplotlib import pyplot

mnist_images = helper.get_batch(glob(os.path.join(data_dir, 'mnist/*.jpg'))[:25], 28, 28, 'L')
pyplot.imshow(helper.images_square_grid(mnist_images, 'L'), cmap='gray')

Derin Evrişimsel GAN Model (Deep Convolutional GAN Model- DCGAN)

DCGAN mimarisi 2015 yılında keşfedildi ve  yeni görüntüler üretmede etkiliyeci sonuçlar verdi. Orjinal makaleye buradan ulaşabilirsiniz.  DCGAN mimarisi generator ve discriminator olmak üzere iki bölümden oluşmaktadır:

Generator: Girdi olarak rastgele bir vektör (z) alır ve bir sahte görüntü üretir. Ürettiği yeni görüntüler ile Discriminator sınıflandırıcıyı yanıltmak için çabalar.

Discriminator: Bir evrişimsel sınıflandırıcıdır ve gelen görüntüleri sahte ya da gerçek olarak sınıflandırır.

Discriminator Ağının Oluşturulması:

Discriminator, görüntülerin gerçek mi sahte mi olduğunu ayırt eden bir sinir ağıdır. Basit bir evrişimsel sınıflandırıcıdır. Discriminator için görüntüler 28×28 boyuttadır. İlk evrişimsel katman ve son tam bağlantılı katman hariç her katmanda tf.layers.batch_normalization ile batch normalization kullanılır.

def discriminator(images, reuse=False):

    alpha=0.2
    with tf.variable_scope('discriminator', reuse=reuse):
        x1=tf.layers.conv2d(images, 64, 5, strides=2, padding='same')
        relu1=tf.maximum(alpha*x1,x1)
        
        x2=tf.layers.conv2d(relu1, 128, 5, strides=2, padding='same')
        bn2=tf.layers.batch_normalization(x2, training=True)
        relu2=tf.maximum(alpha*bn2,bn2)
    
        x3=tf.layers.conv2d(relu2, 256, 5,strides=2, padding='same')
        bn3=tf.layers.batch_normalization(x3, training=True)
        relu3=tf.maximum(alpha*bn3,bn3)
        
        flat=tf.reshape(relu3, (-1, 4*4*256))
        logits = tf.layers.dense(flat, 1)
        output = tf.sigmoid(logits)

    return output, logits

Generator Ağının Oluşturulması:

Generator Ağı, girdi olarak daha önce bahsettiğimiz z vektörünü alır. Yeni görüntü oluşturmak için ise evrişimsel katmanlar kullanır.  İlk katman tam bağlantılı katmandır. Daha sonra batch normalization ve ReLU kullanılır.

def generator(z, out_channel_dim, is_train=True):
   
    alpha=0.2
    with tf.variable_scope('generator', reuse=not is_train):
        x1 = tf.layers.dense(z, 4*4*512)
        
        x1 = tf.reshape(x1, (-1, 4,4,512))
        x1 = tf.layers.batch_normalization(x1, training=is_train)
        x1 = tf.maximum(alpha*x1, x1)
        
        x2 = tf.layers.conv2d_transpose(x1, 256, 4, strides=1, padding='valid')
        x2 = tf.layers.batch_normalization(x2, training=is_train)
        x2 = tf.maximum(alpha*x2, x2)
        
        x3 = tf.layers.conv2d_transpose(x2, 128, 4, strides=2, padding='same')
        x3 = tf.layers.batch_normalization(x3, training=is_train)
        x3 = tf.maximum(alpha*x3, x3)
        
        logits = tf.layers.conv2d_transpose(x3, out_channel_dim, 5, strides=2, padding='same')
        out = tf.tanh(logits)
        
    return out

Ağ Çıktıları:

Loss hesaplamaları ve loss değerlerini minimize etmek için yapılan optimizasyon işlemlerinden sonra gerçekleştirilen ağ eğitiminin sonuçları şu şekildedir:

Tam koda buradan ulaşabilirsiniz.