بناء نموذج GAN لتوليد الصور باستخدام Keras: خطوة بخطوة

Amine
05/09/2024

1. مقدمة حول الـ GANs

الشبكات التوليدية التنافسية (Generative Adversarial Networks – GANs) هي نوع من الشبكات العصبية التي تتكون من نموذجين يتنافسان مع بعضهما البعض: مولد (Generator) ومميز (Discriminator). الهدف من المولد هو توليد بيانات تبدو كأنها حقيقية، بينما يحاول المميز اكتشاف إذا كانت البيانات التي يستقبلها حقيقية أم مولدة.

في هذا الدليل، سنستخدم GAN لتوليد صور جديدة بناءً على بيانات عشوائية. المولد سيقوم بإنشاء الصور، بينما سيقوم المميز بتحديد ما إذا كانت الصورة حقيقية أو مزيفة.

2. إعداد بيئة العمل

أولاً، نحتاج إلى إعداد بيئة العمل وتثبيت مكتبة Keras وTensorFlow. يمكنك تثبيتها باستخدام الأمر التالي:

pip install tensorflow keras numpy matplotlib

3. بناء المولد (Generator)

المولد (Generator) هو الشبكة التي تأخذ ضوضاء عشوائية كمدخلات وتولد منها صورة. نستخدم طبقات متتالية من **Dense** و**LeakyReLU** و**BatchNormalization** لتحويل الضوضاء إلى صورة.

from keras.models import Sequential
from keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape

def build_generator():
    model = Sequential()
    
    # إدخال الضوضاء العشوائية
    model.add(Dense(128, input_dim=100))
    model.add(LeakyReLU(0.2))
    model.add(BatchNormalization(momentum=0.8))
    
    # تحويل الضوضاء إلى صورة
    model.add(Dense(256))
    model.add(LeakyReLU(0.2))
    model.add(BatchNormalization(momentum=0.8))
    
    model.add(Dense(512))
    model.add(LeakyReLU(0.2))
    model.add(BatchNormalization(momentum=0.8))
    
    model.add(Dense(1024))
    model.add(LeakyReLU(0.2))
    
    # إنتاج صورة 28x28x1 (لصور MNIST)
    model.add(Dense(28 * 28 * 1, activation='tanh'))
    model.add(Reshape((28, 28, 1)))
    
    return model

4. بناء المميز (Discriminator)

المميز (Discriminator) هو النموذج الذي يحدد إذا كانت الصورة حقيقية أو مولدة بواسطة المولد. في هذا الجزء، نستخدم عدة طبقات **Dense** و **LeakyReLU** لتحليل الصورة واتخاذ القرار.

from keras.layers import Flatten

def build_discriminator():
    model = Sequential()
    
    # إدخال الصورة
    model.add(Flatten(input_shape=(28, 28, 1)))
    model.add(Dense(512))
    model.add(LeakyReLU(0.2))
    
    model.add(Dense(256))
    model.add(LeakyReLU(0.2))
    
    # إخراج احتمال أن تكون الصورة حقيقية أو مزيفة
    model.add(Dense(1, activation='sigmoid'))
    
    return model

5. تجميع GAN

نقوم الآن بتجميع GAN. في البداية نقوم بتجميع المميز بشكل مستقل. بعد ذلك، نثبت أوزان المميز عند تدريب المولد لكي لا يتم تحديثها، ونجمع المولد مع المميز.

from keras.models import Model
from keras.optimizers import Adam

# إعداد المولد والمميز
generator = build_generator()
discriminator = build_discriminator()

# تجميع المميز
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5), metrics=['accuracy'])

# تجميع المولد
discriminator.trainable = False  # تثبيت المميز أثناء تدريب المولد
gan_input = Input(shape=(100,))
generated_image = generator(gan_input)
gan_output = discriminator(generated_image)
gan = Model(gan_input, gan_output)

gan.compile(loss='binary_crossentropy', optimizer=Adam(0.0002, 0.5))

6. تدريب GAN

لتدريب GAN، سنقوم بما يلي في كل خطوة تدريب:

  1. إنشاء دفعة من الصور المزيفة باستخدام المولد.
  2. تدريب المميز على تمييز الصور الحقيقية من المزيفة.
  3. تحديث المولد بناءً على مدى نجاحه في خداع المميز.
import numpy as np
from keras.datasets import mnist

# تحميل بيانات صور MNIST
(X_train, _), (_, _) = mnist.load_data()
X_train = (X_train.astype(np.float32) - 127.5) / 127.5  # تطبيع البيانات
X_train = np.expand_dims(X_train, axis=3)

# إعداد المتغيرات
batch_size = 64
half_batch = batch_size // 2
epochs = 10000

# حلقة التدريب
for epoch in range(epochs):
    
    # تدريب المميز
    idx = np.random.randint(0, X_train.shape[0], half_batch)
    real_images = X_train[idx]
    
    noise = np.random.normal(0, 1, (half_batch, 100))
    fake_images = generator.predict(noise)
    
    d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)))
    d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((half_batch, 1)))
    d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
    
    # تدريب المولد
    noise = np.random.normal(0, 1, (batch_size, 100))
    valid_y = np.ones((batch_size, 1))
    
    g_loss = gan.train_on_batch(noise, valid_y)
    
    # عرض النتائج كل 1000 تكرار
    if epoch % 1000 == 0:
        print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100 * d_loss[1]}] [G loss: {g_loss}]")

7. توليد الصور

بعد التدريب، يمكننا استخدام المولد لتوليد صور جديدة بناءً على الضوضاء العشوائية.

import matplotlib.pyplot as plt

def generate_and_save_images(epoch, generator):
    noise = np.random.normal(0, 1, (25, 100))
    generated_images = generator.predict(noise)
    
    generated_images = 0.5 * generated_images + 0.5  # إرجاع الصور إلى النطاق [0, 1]
    
    fig, axs = plt.subplots(5, 5)
    count = 0
    for i in range(5):
        for j in range(5):
            axs[i, j].imshow(generated_images[count, :, :, 0], cmap='gray')
            axs[i, j].axis('off')
            count += 1
    plt.show()

# توليد صور جديدة بعد التدريب
generate_and_save_images(epochs, generator)

الخاتمة

في هذا الدليل، تعلمنا كيفية بناء وتدريب نموذج Generative Adversarial Network (GAN) باستخدام Keras. لقد قمنا ببناء المولد (Generator) والمميز (Discriminator) وتدريبهم باستخدام بيانات صور MNIST. يمكننا استخدام هذا النوع من النماذج لتوليد صور جديدة تعتمد على بيانات الضوضاء العشوائية. يمكنك تحسين النموذج وتوسيعه باستخدام مجموعات بيانات أكبر أو باستخدام تقنيات مثل تحسين البيانات (Data Augmentation).

التعليقات

اترك تعليقاً