{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:00.492764Z","iopub.execute_input":"2024-12-18T04:16:00.493093Z","iopub.status.idle":"2024-12-18T04:16:05.160682Z","shell.execute_reply.started":"2024-12-18T04:16:00.493053Z","shell.execute_reply":"2024-12-18T04:16:05.159429Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Import libraries\nimport os\nimport numpy as np\nimport time\nimport gc\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras import layers, models\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom PIL import Image\nimport zipfile\nfrom glob import glob\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:26.060417Z","iopub.execute_input":"2024-12-18T04:16:26.061242Z","iopub.status.idle":"2024-12-18T04:16:26.067502Z","shell.execute_reply.started":"2024-12-18T04:16:26.061188Z","shell.execute_reply":"2024-12-18T04:16:26.066428Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Load Dataset\ndef load_dataset(image_paths, target_size=(128, 128)):\n    \"\"\"\n    Load and preprocess images from given paths.\n    \n    Parameters:\n        image_paths (list): List of paths to the image files.\n        target_size (tuple): Desired size for the images (default is (128, 128)).\n    \n    Returns:\n        np.ndarray: Array of preprocessed images, normalized to [-1, 1].\n    \"\"\"\n    images = []\n    for img_path in image_paths:\n        try:\n            img = load_img(img_path, target_size=target_size)  # Load image\n            img_array = img_to_array(img)  # Convert image to array\n            img_array = (img_array - 127.5) / 127.5  # Normalize to [-1, 1]\n            images.append(img_array)\n        except Exception as e:\n            print(f\"Error processing image {img_path}: {e}\")\n    \n    images = np.array(images, dtype='float32')\n    print(f\"Loaded {len(images)} images.\")\n    return images\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:26.068835Z","iopub.execute_input":"2024-12-18T04:16:26.069181Z","iopub.status.idle":"2024-12-18T04:16:26.114358Z","shell.execute_reply.started":"2024-12-18T04:16:26.06915Z","shell.execute_reply":"2024-12-18T04:16:26.113061Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_generator(latent_dim, kernel_size=5, strides=2, output_channels=3):\n    \"\"\"\n    Build the generator model to map noise (latent_dim) to generated images.\n    \n    Parameters:\n        latent_dim (int): Dimensionality of the input noise vector.\n        kernel_size (int): Size of the kernel for transposed convolutions (default is 5).\n        strides (int): Stride for transposed convolutions (default is 2).\n        output_channels (int): Number of output channels in the image (default is 3 for RGB).\n    \n    Returns:\n        tf.keras.Model: The generator model.\n    \"\"\"\n    generator = Sequential()\n\n    # Fully connected layer + Reshape\n    generator.add(Dense(8 * 8 * 512, input_dim=latent_dim, use_bias=False))\n    generator.add(BatchNormalization())\n    generator.add(ReLU())\n    generator.add(Reshape((8, 8, 512)))  # Output shape: (8, 8, 512)\n\n    # Transposed convolution layers\n    generator.add(Conv2DTranspose(256, kernel_size=kernel_size, strides=strides, padding='same', use_bias=False))\n    generator.add(BatchNormalization())\n    generator.add(ReLU())\n\n    generator.add(Conv2DTranspose(128, kernel_size=kernel_size, strides=strides, padding='same', use_bias=False))\n    generator.add(BatchNormalization())\n    generator.add(ReLU())\n\n    generator.add(Conv2DTranspose(64, kernel_size=kernel_size, strides=strides, padding='same', use_bias=False))\n    generator.add(BatchNormalization())\n    generator.add(ReLU())\n\n    generator.add(Conv2DTranspose(32, kernel_size=kernel_size, strides=strides, padding='same', use_bias=False))\n    generator.add(BatchNormalization())\n    generator.add(ReLU())\n\n    # Output layer\n    generator.add(Conv2DTranspose(output_channels, kernel_size=kernel_size, strides=1, padding='same', activation='tanh'))\n\n    return generator\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:26.116722Z","iopub.execute_input":"2024-12-18T04:16:26.117181Z","iopub.status.idle":"2024-12-18T04:16:26.135309Z","shell.execute_reply.started":"2024-12-18T04:16:26.117146Z","shell.execute_reply":"2024-12-18T04:16:26.134267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def create_discriminator(input_shape, dropout_rate=0.3, kernel_size=4, strides=2):\n    \"\"\"\n    Build the discriminator model to classify real and generated images.\n    \n    Parameters:\n        input_shape (tuple): Shape of the input image (height, width, channels).\n        dropout_rate (float): Dropout rate (default is 0.3).\n        kernel_size (int): Kernel size for Conv2D (default is 4).\n        strides (int): Stride for Conv2D (default is 2).\n    \n    Returns:\n        tf.keras.Model: The discriminator model.\n    \"\"\"\n    discriminator = Sequential()\n\n    # Layer 1: Conv2D + ReLU + Dropout\n    discriminator.add(Conv2D(64, kernel_size=kernel_size, strides=strides, padding='same', input_shape=input_shape))\n    discriminator.add(ReLU())\n    discriminator.add(Dropout(dropout_rate))\n\n    # Layer 2: Conv2D + BatchNormalization + ReLU + Dropout\n    discriminator.add(Conv2D(128, kernel_size=kernel_size, strides=strides, padding='same'))\n    discriminator.add(BatchNormalization())\n    discriminator.add(ReLU())\n    discriminator.add(Dropout(dropout_rate))\n\n    # Layer 3: Conv2D + BatchNormalization + ReLU + Dropout\n    discriminator.add(Conv2D(256, kernel_size=kernel_size, strides=strides, padding='same'))\n    discriminator.add(BatchNormalization())\n    discriminator.add(ReLU())\n    discriminator.add(Dropout(dropout_rate))\n\n    # Layer 4: Conv2D + BatchNormalization + ReLU + Dropout\n    discriminator.add(Conv2D(512, kernel_size=kernel_size, strides=strides, padding='same'))\n    discriminator.add(BatchNormalization())\n    discriminator.add(ReLU())\n    discriminator.add(Dropout(dropout_rate))\n\n    # Output Layer: Flatten + Dense (Sigmoid)\n    discriminator.add(Flatten())\n    discriminator.add(Dense(1, activation='sigmoid'))\n\n    return discriminator\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:29.769577Z","iopub.execute_input":"2024-12-18T04:16:29.769974Z","iopub.status.idle":"2024-12-18T04:16:29.779237Z","shell.execute_reply.started":"2024-12-18T04:16:29.769938Z","shell.execute_reply":"2024-12-18T04:16:29.778127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import time\nimport gc\n\ndef train_gan(generator, discriminator, gan, dataset, epochs, batch_size, latent_dim):\n    \"\"\"\n    Train the GAN model (generator and discriminator).\n\n    Parameters:\n        generator (Model): The generator model.\n        discriminator (Model): The discriminator model.\n        gan (Model): Combined GAN model.\n        dataset (np.ndarray): Array of real images.\n        epochs (int): Number of training epochs.\n        batch_size (int): Size of the batch for each iteration.\n        latent_dim (int): Dimensionality of the input noise vector.\n    \n    Returns:\n        tuple: Lists of discriminator losses and generator losses.\n    \"\"\"\n    half_batch = batch_size // 2  # Half batch size for real and fake images\n    d_losses, g_losses = [], []  # Lists to store loss history\n\n    for epoch in range(epochs):\n        start_time = time.time()  # Start time for tracking epoch duration\n\n        d_loss_epoch, g_loss_epoch = [], []\n\n        # Iterate through the dataset in batches\n        num_batches = dataset.shape[0] // batch_size\n        for _ in range(num_batches):\n            # Train Discriminator\n            # Select random real images\n            real_idx = np.random.choice(dataset.shape[0], half_batch, replace=False)\n            real_images = dataset[real_idx]\n\n            # Generate fake images\n            noise = np.random.normal(0, 1, (half_batch, latent_dim))\n            fake_images = generator.predict(noise, verbose=0)\n\n            # Train on real and fake images\n            d_loss_real = discriminator.train_on_batch(real_images, np.ones((half_batch, 1)) * 0.9)  # Label smoothing for real\n            d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((half_batch, 1)))\n            d_loss = 0.5 * (d_loss_real + d_loss_fake)\n            d_loss_epoch.append(d_loss)\n\n            # Train Generator via GAN\n            noise = np.random.normal(0, 1, (batch_size, latent_dim))\n            g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))  # Train generator to fool discriminator\n            g_loss_epoch.append(g_loss)\n\n        # Record average losses for the epoch\n        d_losses.append(np.mean(d_loss_epoch))\n        g_losses.append(np.mean(g_loss_epoch))\n\n        # Print progress\n        elapsed_time = time.time() - start_time\n        print(f\"Epoch {epoch+1}/{epochs} | Discriminator Loss: {d_losses[-1]:.4f} | Generator Loss: {g_losses[-1]:.4f} | Time: {elapsed_time:.2f}s\")\n\n        # Save generated images at intervals (every 10 epochs)\n        if (epoch + 1) % 10 == 0:\n            save_generated_images(generator, epoch + 1, latent_dim)\n\n    # Return the loss history\n    return d_losses, g_losses\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:37.459853Z","iopub.execute_input":"2024-12-18T04:16:37.460257Z","iopub.status.idle":"2024-12-18T04:16:37.471463Z","shell.execute_reply.started":"2024-12-18T04:16:37.460222Z","shell.execute_reply":"2024-12-18T04:16:37.470288Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nfrom PIL import Image\n\ndef save_generated_images(generator, latent_dim, total_images, output_dir=\"generated_images\", image_format=\"png\"):\n    \"\"\"\n    Generate and save images from the generator model.\n    \n    Parameters:\n        generator (Model): The trained generator model.\n        latent_dim (int): Dimensionality of the input noise vector.\n        total_images (int): Total number of images to generate.\n        output_dir (str): Directory to save the generated images (default is \"generated_images\").\n        image_format (str): Format to save images, default is \"png\" (options: \"jpg\", \"png\").\n    \"\"\"\n    # Validasi input\n    if not isinstance(latent_dim, int) or latent_dim <= 0:\n        raise ValueError(\"latent_dim should be a positive integer.\")\n    if not isinstance(total_images, int) or total_images <= 0:\n        raise ValueError(\"total_images should be a positive integer.\")\n    \n    # Buat direktori jika belum ada\n    os.makedirs(output_dir, exist_ok=True)\n    \n    # Generate and save images\n    for i in range(1, total_images + 1):\n        # Generate random noise as input\n        noise = np.random.normal(0, 1, (1, latent_dim))\n\n        # Generate image using the generator\n        generated_image = generator.predict(noise, verbose=0)[0]\n        \n        # Rescale image to [0, 255] and convert to uint8\n        generated_image = (generated_image * 127.5 + 127.5).astype(np.uint8)\n\n        # Save the image\n        image_path = os.path.join(output_dir, f\"image_{i}.{image_format}\")\n        try:\n            Image.fromarray(generated_image).save(image_path)\n            if i % 100 == 0:  # Log progress every 100 images\n                print(f\"Saved {i}/{total_images} images.\")\n        except Exception as e:\n            print(f\"Error saving image {i}: {e}\")\n\n    print(f\"Generated {total_images} images. Saved to '{output_dir}' in {image_format} format.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:43.168225Z","iopub.execute_input":"2024-12-18T04:16:43.168664Z","iopub.status.idle":"2024-12-18T04:16:43.178402Z","shell.execute_reply.started":"2024-12-18T04:16:43.168627Z","shell.execute_reply":"2024-12-18T04:16:43.176937Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, Model\n\ndef build_gan(generator, discriminator):\n    \"\"\"\n    Build the combined GAN model by connecting the generator and the discriminator.\n    \n    Parameters:\n        generator (Model): The generator model.\n        discriminator (Model): The discriminator model.\n    \n    Returns:\n        tf.keras.Model: The combined GAN model.\n    \"\"\"\n    # Make the discriminator non-trainable when training the GAN\n    discriminator.trainable = False\n    \n    # GAN input is the noise vector fed into the generator\n    gan_input = layers.Input(shape=(generator.input_shape[1],))  # Latent vector (noise)\n    \n    # Generate an image from the input noise\n    generated_image = generator(gan_input)\n    \n    # Discriminator classifies the generated image as real or fake\n    gan_output = discriminator(generated_image)\n    \n    # Create the GAN model\n    gan = Model(gan_input, gan_output)\n    \n    return gan\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:16:56.477421Z","iopub.execute_input":"2024-12-18T04:16:56.477859Z","iopub.status.idle":"2024-12-18T04:16:56.484613Z","shell.execute_reply.started":"2024-12-18T04:16:56.477817Z","shell.execute_reply":"2024-12-18T04:16:56.483496Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\nfrom tensorflow.keras.optimizers import Adam\n\n# Parameter Latent Dimension\nlatent_dim = 100  # Dimensi vektor noise (input ke generator)\n\n# Fungsi untuk Membuat Generator\ndef create_generator(latent_dim):\n    model = models.Sequential()\n    model.add(layers.Dense(128 * 16 * 16, activation=\"relu\", input_dim=latent_dim))\n    model.add(layers.Reshape((16, 16, 128)))  # Bentuk awal: (16, 16, 128)\n    model.add(layers.Conv2DTranspose(128, (4, 4), strides=(2, 2), padding=\"same\", activation=\"relu\"))\n    model.add(layers.Conv2DTranspose(64, (4, 4), strides=(2, 2), padding=\"same\", activation=\"relu\"))\n    model.add(layers.Conv2D(3, (7, 7), activation=\"tanh\", padding=\"same\"))  # Output RGB (256x256x3)\n    return model\n\n# Fungsi untuk Membuat Discriminator\ndef create_discriminator(input_shape=(256, 256, 3)):\n    model = models.Sequential()\n    model.add(layers.Conv2D(64, (4, 4), strides=(2, 2), padding=\"same\", input_shape=input_shape))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Conv2D(128, (4, 4), strides=(2, 2), padding=\"same\"))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Flatten())\n    model.add(layers.Dense(1, activation=\"sigmoid\"))  # Output 1 neuron (Real/Fake)\n    return model\n\n# Inisialisasi Model Generator dan Discriminator\ngenerator = create_generator(latent_dim)\ndiscriminator = create_discriminator()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:21:27.280516Z","iopub.execute_input":"2024-12-18T04:21:27.281025Z","iopub.status.idle":"2024-12-18T04:21:27.415284Z","shell.execute_reply.started":"2024-12-18T04:21:27.280966Z","shell.execute_reply":"2024-12-18T04:21:27.414031Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.applications import vgg19  # or other pre-trained models if needed\nfrom PIL import Image\n\ndef load_dataset(image_paths, target_size=(128, 128)):\n    \"\"\"\n    Load images from the given paths and resize them to the target size.\n    \n    Parameters:\n        image_paths (list): List of paths to the image files or directories.\n        target_size (tuple): The size to which each image should be resized (default is 128x128).\n    \n    Returns:\n        np.ndarray: Array of image data, normalized to [-1, 1] for GAN training.\n    \"\"\"\n    images = []\n\n    # Loop through all the image paths\n    for path in image_paths:\n        # Check if path is a directory\n        if os.path.isdir(path):\n            # Get all image files in the directory\n            files = [f for f in os.listdir(path) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]\n            for file in files:\n                img_path = os.path.join(path, file)\n                img = image.load_img(img_path, target_size=target_size)  # Load and resize the image\n                img = image.img_to_array(img)  # Convert to numpy array\n                img = (img / 127.5) - 1.0  # Normalize image to range [-1, 1]\n                images.append(img)\n    \n    # Convert list of images to a numpy array\n    dataset = np.array(images)\n    return dataset\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:21:31.110352Z","iopub.execute_input":"2024-12-18T04:21:31.110782Z","iopub.status.idle":"2024-12-18T04:21:31.122709Z","shell.execute_reply.started":"2024-12-18T04:21:31.110745Z","shell.execute_reply":"2024-12-18T04:21:31.121502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\ndef create_discriminator(input_shape=(128, 128, 3)):\n    \"\"\"\n    Creates the discriminator model.\n    \n    Parameters:\n        input_shape (tuple): The shape of the input image (height, width, channels).\n    \n    Returns:\n        tf.keras.Model: The discriminator model.\n    \"\"\"\n    model = models.Sequential()\n\n    # First convolutional layer (with padding to keep spatial dimensions)\n    model.add(layers.Conv2D(64, kernel_size=3, strides=2, padding='same', input_shape=input_shape))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Dropout(0.4))\n\n    # Second convolutional layer\n    model.add(layers.Conv2D(128, kernel_size=3, strides=2, padding='same'))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Dropout(0.4))\n\n    # Third convolutional layer\n    model.add(layers.Conv2D(256, kernel_size=3, strides=2, padding='same'))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Dropout(0.4))\n\n    # Fourth convolutional layer\n    model.add(layers.Conv2D(512, kernel_size=3, strides=2, padding='same'))\n    model.add(layers.LeakyReLU(alpha=0.2))\n    model.add(layers.Dropout(0.4))\n\n    # Flatten the output of the convolutional layers\n    model.add(layers.Flatten())\n    \n    # Dense layer with 1 output (real/fake classification)\n    model.add(layers.Dense(1, activation='sigmoid'))\n    \n    # Compile the model\n    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n\n    return model\n\n# Example usage:\ndiscriminator = create_discriminator(input_shape=(128, 128, 3))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-18T04:21:34.625384Z","iopub.execute_input":"2024-12-18T04:21:34.626365Z","iopub.status.idle":"2024-12-18T04:21:34.78796Z","shell.execute_reply.started":"2024-12-18T04:21:34.626322Z","shell.execute_reply":"2024-12-18T04:21:34.787011Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras import layers, models\n\ndef build_gan(generator, discriminator):\n    \"\"\"\n    Build the combined GAN model by connecting the generator and the discriminator.\n    \n    Parameters:\n        generator (Model): The generator model.\n        discriminator (Model): The discriminator model.\n    \n    Returns:\n        tf.keras.Model: The combined GAN model.\n    \"\"\"\n    # Make the discriminator non-trainable when training the GAN\n    discriminator.trainable = False\n    \n    # GAN input is the noise vector fed into the generator\n    gan_input = layers.Input(shape=(generator.input_shape[1],))  # Latent vector (noise)\n    \n    # Generate an image from the input noise\n    generated_image = generator(gan_input)\n    \n    # Discriminator classifies the generated image as real or fake\n    gan_output = discriminator(generated_image)\n    \n    # Create the GAN model\n    gan = models.Model(gan_input, gan_output)\n    \n    # Compile the model (only the generator is trained)\n    gan.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n    \n    return gan\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom PIL import Image\nimport os\n\ndef generate_and_save_images(generator, latent_dim, total_images=100, output_dir=\"generated_images\", image_format=\"png\"):\n    \"\"\"\n    Generate and save images from the trained generator model.\n    \n    Parameters:\n        generator (Model): The trained generator model.\n        latent_dim (int): Dimensionality of the input noise vector.\n        total_images (int): Total number of images to generate.\n        output_dir (str): Directory to save the generated images.\n        image_format (str): Format to save images (default is \"png\").\n    \"\"\"\n    # Validate input\n    if not isinstance(latent_dim, int) or latent_dim <= 0:\n        raise ValueError(\"latent_dim should be a positive integer.\")\n    if not isinstance(total_images, int) or total_images <= 0:\n        raise ValueError(\"total_images should be a positive integer.\")\n    \n    # Create the output directory if it doesn't exist\n    os.makedirs(output_dir, exist_ok=True)\n    \n    # Generate and save images\n    for i in range(1, total_images + 1):\n        # Generate random noise as input\n        noise = np.random.normal(0, 1, (1, latent_dim))\n\n        # Generate an image using the trained generator\n        generated_image = generator.predict(noise, verbose=0)[0]\n        \n        # Rescale the image to the range [0, 255] and convert to uint8\n        generated_image = (generated_image * 127.5 + 127.5).astype(np.uint8)\n\n        # Save the generated image to the output directory\n        image_path = os.path.join(output_dir, f\"image_{i}.{image_format}\")\n        try:\n            Image.fromarray(generated_image).save(image_path)\n            if i % 100 == 0:  # Log progress every 100 images\n                print(f\"Saved {i}/{total_images} images.\")\n        except Exception as e:\n            print(f\"Error saving image {i}: {e}\")\n\n    print(f\"Generated {total_images} images. Saved to '{output_dir}' in {image_format} format.\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Latent dimension for the generator\nlatent_dim = 100  # Latent space dimensionality\n\n# Create the generator and discriminator models\ngenerator = create_generator(latent_dim)\ndiscriminator = create_discriminator(input_shape=(128, 128, 3))  # Assuming 128x128 RGB images\n\n# Create the combined GAN model\ngan = build_gan(generator, discriminator)\n\n# Load your dataset (provide the correct paths)\nimage_paths = [\"path/to/your/images\"]  # Replace with the actual path to your images\ndataset = load_dataset(image_paths)  # Load dataset from the provided paths\n\n# Now you can proceed with training\nepochs, batch_size = 10, 4\nd_losses, g_losses = train_gan(generator, discriminator, gan, dataset, epochs, batch_size, latent_dim)\n\n# Plot Discriminator and Generator Losses\nplt.plot(d_losses, label='Discriminator Loss')\nplt.plot(g_losses, label='Generator Loss')\nplt.legend()\nplt.title(\"Loss Over Epochs\")\nplt.show()\n\n# Generate and Save 7000 Images\ngenerate_and_save_images(generator, latent_dim, total_images=7000, output_dir=\"generated_images\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generate and Save 7000 Images as a Zip File\ngenerate_and_save_images(generator, latent_dim, total_images=7000, output_dir=\"generated_images\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\noutput_dir = \"generated_images\"\nos.makedirs(output_dir, exist_ok=True)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import zipfile\nimport os\n\n# Define the directory containing the generated images\noutput_dir = \"generated_images\"\n\n# Create a Zip file\nwith zipfile.ZipFile(\"images.zip\", 'w', zipfile.ZIP_DEFLATED) as zf:\n    # Walk through the directory and add files to the zip archive\n    for root, dirs, files in os.walk(output_dir):\n        for file in files:\n            file_path = os.path.join(root, file)\n            # Write the file to the zip archive with a relative path\n            zf.write(file_path, os.path.relpath(file_path, output_dir))\n\nprint(\"Images zipped successfully.\")\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}