{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":63131,"sourceType":"datasetVersion","datasetId":40205},{"sourceId":7209110,"sourceType":"datasetVersion","datasetId":4166316}],"dockerImageVersionId":30626,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Setup**","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom keras import preprocessing\nfrom tensorflow.keras.preprocessing.image import img_to_array, load_img\nfrom sklearn.model_selection import train_test_split\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D,Dropout,Dense,Flatten,Conv2DTranspose,BatchNormalization,LeakyReLU,Reshape\nimport tensorflow as tf\nfrom tensorflow.keras.optimizers import Adam\n\nimport numpy as np \nimport pandas as pd \nimport os","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-20T16:01:21.045370Z","iopub.execute_input":"2023-12-20T16:01:21.046256Z","iopub.status.idle":"2023-12-20T16:01:21.052110Z","shell.execute_reply.started":"2023-12-20T16:01:21.046217Z","shell.execute_reply":"2023-12-20T16:01:21.051203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Import and Preprocess Data**","metadata":{}},{"cell_type":"code","source":"data_dir = '/kaggle/input/greyscale-64x64-pokemon-sprite-dataset/filtered_data_by_generation'\ndata_gen = 'filtered_datagen123'\n\nspecific_gen_path = os.path.join(data_dir, data_gen)\n\nimage_list = []\nfor image_name in os.listdir(specific_gen_path):\n    image_path = os.path.join(specific_gen_path, image_name)\n    image_list.append(image_path)","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:01:22.312856Z","iopub.execute_input":"2023-12-20T16:01:22.313202Z","iopub.status.idle":"2023-12-20T16:01:22.328073Z","shell.execute_reply.started":"2023-12-20T16:01:22.313176Z","shell.execute_reply":"2023-12-20T16:01:22.327322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to load and preprocess images\ndef load_and_preprocess_image(img_path):\n    img = load_img(img_path, target_size=(28, 28), color_mode='grayscale')\n    img_array = img_to_array(img)\n    \n    img_array /= 255.0\n    img_array = 2 * img_array - 1.0\n    \n    img_tensor = tf.convert_to_tensor(img_array)\n    \n    return img_tensor\n\nimage_tensors = [load_and_preprocess_image(img_path) for img_path in image_list]\n\nimage_batch = tf.stack(image_tensors)\n\n# Convert NumPy arrays to TensorFlow tensors\nimage_batch = tf.convert_to_tensor(image_batch)\n\n# Create indices for splitting\nindices = tf.range(image_batch.shape[0])\ntrain_indices, test_indices = train_test_split(indices.numpy(), test_size=0.2, random_state=10)\n\n# Split the data into training and testing sets using the indices\ntrain_images = tf.gather(image_batch, train_indices)\ntest_images = tf.gather(image_batch, test_indices)\n\n# Print the shapes of the resulting sets\nprint(\"Shape of train_images:\", train_images.shape)\nprint(\"Shape of test_images:\", test_images.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:01:25.440577Z","iopub.execute_input":"2023-12-20T16:01:25.441463Z","iopub.status.idle":"2023-12-20T16:01:31.766906Z","shell.execute_reply.started":"2023-12-20T16:01:25.441426Z","shell.execute_reply":"2023-12-20T16:01:31.765805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helper Functions","metadata":{}},{"cell_type":"code","source":"def plot_images(image_tensors, num_images=5):\n    # Ensure that the number of images to plot is not greater than the batch size\n    num_images = min(num_images, image_tensors.shape[0])\n\n    # Plot the images\n    plt.figure(figsize=(12, 3))\n    for i in range(num_images):\n        plt.subplot(1, num_images, i + 1)\n        image_array = np.squeeze(image_tensors[i])\n        plt.imshow(image_array, cmap='gray')\n        plt.axis('off')\n\n    plt.show()\n\nplot_images(train_images, num_images=5)\n\n    ","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:01:37.118208Z","iopub.execute_input":"2023-12-20T16:01:37.118571Z","iopub.status.idle":"2023-12-20T16:01:37.292229Z","shell.execute_reply.started":"2023-12-20T16:01:37.118540Z","shell.execute_reply":"2023-12-20T16:01:37.291236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_losses(d_loss_real_list, d_loss_fake_list, g_loss_list):\n\n    # Plotting the loss curves\n    plt.figure(figsize=(4, 2))\n\n    # Discriminator real loss\n    plt.plot(range(len(d_loss_real_list)), d_loss_real_list, label='Discriminator Real Loss', color='blue')\n    plt.plot(range(len(d_loss_real_list)), d_loss_fake_list, label='Discriminator Fake Loss', color='orange')\n    plt.plot(range(len(d_loss_real_list)), g_loss_list, label='Generator Loss', color='green')\n    plt.title('Discriminator and Generator Loss over Epochs')\n    plt.xlabel('Epochs')\n    plt.ylabel('Loss')\n    plt.legend()\n\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:04:20.187326Z","iopub.execute_input":"2023-12-20T16:04:20.187962Z","iopub.status.idle":"2023-12-20T16:04:20.194782Z","shell.execute_reply.started":"2023-12-20T16:04:20.187927Z","shell.execute_reply":"2023-12-20T16:04:20.193664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Simple GAN\nOnly run up till the DCGAN section then skip to the training section for evaluating the Simple GAN","metadata":{}},{"cell_type":"code","source":"noise_shape = 200\ngenerator = Sequential()\n\ngenerator.add(Dense(512, input_shape=[noise_shape]))\ngenerator.add(LeakyReLU(alpha=0.2))\ngenerator.add(BatchNormalization(momentum=0.9))\n\ngenerator.add(Dense(256))\ngenerator.add(LeakyReLU(alpha=0.2))\ngenerator.add(BatchNormalization(momentum=0.9))\n\ngenerator.add(Dense(128))\ngenerator.add(LeakyReLU(alpha=0.2))\ngenerator.add(BatchNormalization(momentum=0.9))\n\ngenerator.add(Dense(784, activation='tanh'))\ngenerator.add(Reshape([28, 28, 1]))\n\ngenerator.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:47:22.291303Z","iopub.execute_input":"2023-12-20T16:47:22.291739Z","iopub.status.idle":"2023-12-20T16:47:22.459424Z","shell.execute_reply.started":"2023-12-20T16:47:22.291696Z","shell.execute_reply":"2023-12-20T16:47:22.458406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"discriminator = Sequential()\ndiscriminator.add(Dense(1,input_shape=[28,28,1]))\ndiscriminator.add(Flatten())\ndiscriminator.add(Dense(256))\ndiscriminator.add(LeakyReLU(alpha=0.2))\ndiscriminator.add(Dropout(0.5))\ndiscriminator.add(Dense(128))\ndiscriminator.add(LeakyReLU(alpha=0.2))\ndiscriminator.add(Dropout(0.5))\ndiscriminator.add(Dense(64))\ndiscriminator.add(LeakyReLU(alpha=0.2))\ndiscriminator.add(Dropout(0.5))\ndiscriminator.add(Dense(1,activation='sigmoid'))\ndiscriminator.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:02:49.199037Z","iopub.execute_input":"2023-12-20T16:02:49.199402Z","iopub.status.idle":"2023-12-20T16:02:49.338505Z","shell.execute_reply.started":"2023-12-20T16:02:49.199375Z","shell.execute_reply":"2023-12-20T16:02:49.337519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"discriminator_optimizer = Adam(learning_rate=0.0005)\ngenerator_optimizer = Adam(learning_rate=0.0005)\n\nGAN =Sequential([generator,discriminator])\n\ndiscriminator.compile(optimizer=discriminator_optimizer,loss='binary_crossentropy')\ndiscriminator.trainable = False\n\nGAN.compile(optimizer=generator_optimizer,loss='binary_crossentropy')\nGAN.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:02:52.829270Z","iopub.execute_input":"2023-12-20T16:02:52.829957Z","iopub.status.idle":"2023-12-20T16:02:52.957690Z","shell.execute_reply.started":"2023-12-20T16:02:52.829925Z","shell.execute_reply":"2023-12-20T16:02:52.956957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DCGAN Definition\nRun this section to define a DCGAN tune hyperparameters as desired","metadata":{}},{"cell_type":"code","source":"# Hyperparameters: Tune accordingly\n# Generator\ngen_kern_size = 5  # originally 5 - must be an odd number\ngen_strides = 2\n\n# Discriminator\ndisc_leakyrelu_param = 0.3\ndisc_kern_size = 5  # originally 5 - must be an odd number\ndisc_strides = 2\ndisc_dropout = 0.1  # originally 0.5\n\nnoise_shape = 300  # originally 100\n","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:24:04.390645Z","iopub.execute_input":"2023-12-20T16:24:04.391391Z","iopub.status.idle":"2023-12-20T16:24:04.396250Z","shell.execute_reply.started":"2023-12-20T16:24:04.391353Z","shell.execute_reply":"2023-12-20T16:24:04.395205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 24x24\ngenerator = Sequential()\ngenerator.add(Dense(7 * 7 * 128, input_shape=[noise_shape]))\ngenerator.add(Reshape([7, 7, 128]))\ngenerator.add(BatchNormalization())\ngenerator.add(Conv2DTranspose(32, kernel_size=gen_kern_size, strides=1, padding=\"same\",\n                             activation=\"relu\"))\ngenerator.add(BatchNormalization())\ngenerator.add(Conv2DTranspose(64, kernel_size=gen_kern_size, strides=gen_strides, padding=\"same\",\n                             activation=\"relu\"))\ngenerator.add(BatchNormalization())\ngenerator.add(Conv2DTranspose(32, kernel_size=gen_kern_size, strides=1, padding=\"same\",\n                             activation=\"relu\"))\ngenerator.add(BatchNormalization())\ngenerator.add(Conv2DTranspose(1, kernel_size=gen_kern_size, strides=gen_strides, padding=\"same\",\n                             activation=\"tanh\"))\nprint(\"Generator Summary:\")\ngenerator.summary()\n\ndiscriminator = Sequential()\ndiscriminator.add(Conv2D(64, kernel_size=disc_kern_size, strides=disc_strides, padding=\"same\",\n                         activation=LeakyReLU(disc_leakyrelu_param),\n                         input_shape=[28, 28, 1]))\ndiscriminator.add(Dropout(disc_dropout))\ndiscriminator.add(Conv2D(128, kernel_size=disc_kern_size, strides=disc_strides, padding=\"same\",\n                         activation=LeakyReLU(disc_leakyrelu_param)))\ndiscriminator.add(Dropout(disc_dropout))\ndiscriminator.add(Flatten())\ndiscriminator.add(Dense(1, activation=\"sigmoid\"))\nprint(\"\\n\\nDiscriminator Summary:\")\ndiscriminator.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:24:39.298133Z","iopub.execute_input":"2023-12-20T16:24:39.298545Z","iopub.status.idle":"2023-12-20T16:24:39.603618Z","shell.execute_reply.started":"2023-12-20T16:24:39.298514Z","shell.execute_reply":"2023-12-20T16:24:39.602582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create GAN\nGAN = Sequential()\nGAN.add(generator)\nGAN.add(discriminator)\ndiscriminator.compile(optimizer='adam', loss='binary_crossentropy')\ndiscriminator.trainable = False\nGAN.compile(optimizer='adam',loss='binary_crossentropy')\nGAN.layers\nGAN.summary","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:24:45.843909Z","iopub.execute_input":"2023-12-20T16:24:45.844714Z","iopub.status.idle":"2023-12-20T16:24:45.974600Z","shell.execute_reply.started":"2023-12-20T16:24:45.844679Z","shell.execute_reply":"2023-12-20T16:24:45.973569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training the GAN","metadata":{}},{"cell_type":"code","source":"epochs = 500\nbatch_size = 64","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:24:47.927644Z","iopub.execute_input":"2023-12-20T16:24:47.928610Z","iopub.status.idle":"2023-12-20T16:24:47.933136Z","shell.execute_reply.started":"2023-12-20T16:24:47.928570Z","shell.execute_reply":"2023-12-20T16:24:47.931993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d_loss_fake_list = list()\nd_loss_real_list = list()\ng_loss_list = list()\n\nwith tf.device('/gpu:0'):    \n for epoch in range(epochs):\n    print(f\"Currently on Epoch {epoch+1}\")\n    \n    \n    for i in range(train_images.shape[0]//batch_size):\n        \n        if (i+1)%50 == 0:\n            print(f\"\\tCurrently on batch number {i+1} of {X_train.shape[0]//batch_size}\")\n            \n        noise=np.random.normal(size=[batch_size,noise_shape])\n       \n        gen_image = generator.predict_on_batch(noise)\n        \n        train_dataset = train_images[i*batch_size:(i+1)*batch_size]\n       \n        #training discriminator on real images\n        train_label=np.ones(shape=(batch_size,1))\n        discriminator.trainable = True\n        d_loss_real=discriminator.train_on_batch(train_dataset,train_label)\n        \n        #training discriminator on fake images\n        train_label=np.zeros(shape=(batch_size,1))\n        d_loss_fake=discriminator.train_on_batch(gen_image,train_label)\n        \n        \n        #training generator \n        noise=np.random.normal(size=[batch_size,noise_shape])\n        train_label=np.ones(shape=(batch_size,1))\n        discriminator.trainable = False #while training the generator as combined model,discriminator training should be turned off\n        \n        g_loss =GAN.train_on_batch(noise, train_label)\n        \n    d_loss_fake_list.append(d_loss_fake)\n    d_loss_real_list.append(d_loss_real)\n    g_loss_list.append(g_loss)\n       \n    #plotting generated images at the start and then after every 10 epoch\n    if epoch % 10 == 0:\n        samples = 10\n        x_fake = generator.predict(np.random.normal(loc=0, scale=1, size=(samples, noise_shape)))\n\n        for k in range(samples):\n            plt.subplot(2, 5, k+1)\n            plt.imshow(x_fake[k].reshape(28, 28), cmap='gray')\n            plt.xticks([])\n            plt.yticks([])\n\n        plt.tight_layout()\n        plt.show()\n        \n        plot_losses(d_loss_real_list, d_loss_fake_list, g_loss_list)\n\n        \nprint('Training is complete')","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:24:51.135845Z","iopub.execute_input":"2023-12-20T16:24:51.136714Z","iopub.status.idle":"2023-12-20T16:36:34.368611Z","shell.execute_reply.started":"2023-12-20T16:24:51.136666Z","shell.execute_reply":"2023-12-20T16:36:34.367376Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = 5\nx_fake = generator.predict(np.random.normal(loc=0, scale=1, size=(samples, noise_shape)))\nprint(type(x_fake))\n  \n    \nplot_images(x_fake, samples)","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:39:50.192186Z","iopub.execute_input":"2023-12-20T16:39:50.192567Z","iopub.status.idle":"2023-12-20T16:39:50.466476Z","shell.execute_reply.started":"2023-12-20T16:39:50.192538Z","shell.execute_reply":"2023-12-20T16:39:50.465068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"length = len(d_loss_fake_list)\n\n# Plotting the loss curves\nplt.figure(figsize=(12, 6))\n\n# Discriminator real loss\nplt.subplot(2, 1, 1)\nplt.plot(range(length), d_loss_real_list, label='Discriminator Real Loss', color='blue')\nplt.title('Discriminator Real Loss over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\n# Annotate the last point on the graph\nplt.annotate(f'Last Value: {d_loss_real_list[-1]:.3f}', xy=(length-1, d_loss_real_list[-1]),\n             xytext=(length+40, d_loss_real_list[-1]), color='blue',\n             arrowprops=dict(facecolor='black', arrowstyle='->'))\n\n# Discriminator fake loss and Generator loss\nplt.subplot(2, 1, 2)\nplt.plot(range(length), d_loss_fake_list, label='Discriminator Fake Loss', color='orange')\nplt.plot(range(length), g_loss_list, label='Generator Loss', color='green')\nplt.title('Discriminator Fake and Generator Loss over Epochs')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\n# Annotate the last points on the graphs\nplt.annotate(f'Last Value: {d_loss_fake_list[-1]:.3f}', xy=(length-1, d_loss_fake_list[-1]),\n             xytext=(epochs+40, d_loss_fake_list[-1]), color='orange',\n             arrowprops=dict(facecolor='orange', arrowstyle='->'))\n\nplt.annotate(f'Last Value: {g_loss_list[-1]:.3f}', xy=(length-1, g_loss_list[-1]),\n             xytext=(length+40, g_loss_list[-1]), color='green',\n             arrowprops=dict(facecolor='green', arrowstyle='->'))\n\nplt.tight_layout()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:39:48.697311Z","iopub.execute_input":"2023-12-20T16:39:48.697673Z","iopub.status.idle":"2023-12-20T16:39:49.346439Z","shell.execute_reply.started":"2023-12-20T16:39:48.697643Z","shell.execute_reply":"2023-12-20T16:39:49.345476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Test Descriminator Results","metadata":{}},{"cell_type":"code","source":"total_real_loss = 0\nnum_tests = 0\nfor i in range(test_images.shape[0]//batch_size):\n\n    if (i+1)%50 == 0:\n        print(f\"\\tCurrently on batch number {i+1} of {test_images.shape[0]//batch_size}\")\n\n    noise=np.random.normal(size=[batch_size,noise_shape])\n\n    gen_image = generator.predict_on_batch(noise)\n\n    test_dataset = test_images[i*batch_size:(i+1)*batch_size]\n\n    #training discriminator on real images\n    test_label=np.ones(shape=(batch_size,1))\n    discriminator.trainable = True\n    loss_real=discriminator.evaluate(test_dataset,test_label)\n    total_real_loss += loss_real\n    num_tests +=1\n        \nprint(f\"Avg Real Test Data: Loss={total_real_loss/num_tests}\")","metadata":{"execution":{"iopub.status.busy":"2023-12-20T16:39:56.766915Z","iopub.execute_input":"2023-12-20T16:39:56.767563Z","iopub.status.idle":"2023-12-20T16:39:57.400643Z","shell.execute_reply.started":"2023-12-20T16:39:56.767533Z","shell.execute_reply":"2023-12-20T16:39:57.399773Z"},"trusted":true},"execution_count":null,"outputs":[]}]}