{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30698,"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\npd.set_option('display.max_columns', None)\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":"a72748f5-c8c5-4f28-904a-fe7b2e601b34","_cell_guid":"138c41e3-c328-4287-a181-168b6213f20f","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:40.604168Z","iopub.execute_input":"2024-05-09T10:51:40.604980Z","iopub.status.idle":"2024-05-09T10:51:40.620110Z","shell.execute_reply.started":"2024-05-09T10:51:40.604934Z","shell.execute_reply":"2024-05-09T10:51:40.618834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n<font style=\"font-size:18px;color:blue;font-style: italic;\" > \n<ul>\n<li>The MNIST dataset was created by Yann LeCun, Corinna Cortes, and Christopher J.C. Burges for evaluating machine learning models on the specific task of recognizing handwritten digits. \n    \n<li>Content: The dataset contains grayscale images of handwritten digits (from 0 to 9). \n<li>Image Size: Each image is 28 x 28 pixels, typically represented in a flattened form as a 784-dimensional vector of pixel intensity values.\n<li>Labeling: Each image is labeled with the digit it represents.\n</ul>\n</font>","metadata":{}},{"cell_type":"code","source":"df_train = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ndf_train.head()","metadata":{"_uuid":"8cd6a5b9-da29-492c-a865-63f5b8adf343","_cell_guid":"b8274fc0-9ccb-400b-924e-fd82557f2537","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:40.621871Z","iopub.execute_input":"2024-05-09T10:51:40.622799Z","iopub.status.idle":"2024-05-09T10:51:43.658601Z","shell.execute_reply.started":"2024-05-09T10:51:40.622756Z","shell.execute_reply":"2024-05-09T10:51:43.657453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape","metadata":{"_uuid":"a70c5647-6bcd-4c30-8739-be0813675281","_cell_guid":"26a8d226-91fc-41f3-abeb-8fe73339eec4","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:43.659960Z","iopub.execute_input":"2024-05-09T10:51:43.660289Z","iopub.status.idle":"2024-05-09T10:51:43.667004Z","shell.execute_reply.started":"2024-05-09T10:51:43.660262Z","shell.execute_reply":"2024-05-09T10:51:43.665878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_matrix = np.array(df_train.loc[:, df_train.columns != 'label'])\ndata_matrix = data_matrix.astype(np.float64)","metadata":{"_uuid":"4945a2e1-5bf9-4942-8875-c8c88ac9d766","_cell_guid":"9b6413ef-fb08-4cbd-ae79-b212cd4e174d","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:43.668744Z","iopub.execute_input":"2024-05-09T10:51:43.669295Z","iopub.status.idle":"2024-05-09T10:51:44.031822Z","shell.execute_reply.started":"2024-05-09T10:51:43.669266Z","shell.execute_reply":"2024-05-09T10:51:44.030696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<font style=\"font-size:18px;color:blue;font-style: italic;\" > \nA look into the Dataset\n</font>","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\n\ndef display_images_grid(data_matrix, indices, rows, cols):\n    if any(i >= data_matrix.shape[0] or i < 0 for i in indices):\n        print(\"One or more indices are out of range.\")\n        return\n\n    fig, axes = plt.subplots(rows, cols, figsize=(cols * 2, rows * 2))\n    fig.subplots_adjust(hspace=0.5, wspace=0.1)\n\n    for ax, index in zip(axes.flatten(), indices):\n        # Check if the current index exists in the indices list\n        if index < len(indices):\n            # Reshape the 1D array (row of the data matrix) back to 2D (assuming 100x100)\n            image = data_matrix[index].reshape(28,28)\n            ax.imshow(image, cmap='gray')\n            ax.set_title(f\"Image at index {index}\")\n            ax.axis('off')  # Turn off axis numbers and ticks\n        else:\n            ax.axis('off')  # Hide empty subplots\n    \n    plt.show()\n\n# Example usage\n# Assuming `data_matrix` is already loaded with image data\n# Display the first 10 images in a 2x5 grid\nindices_to_display = list(range(20))  # You can specify any range of indices here\ndisplay_images_grid(data_matrix, indices_to_display, 4, 5)","metadata":{"_uuid":"042939d0-9978-49a7-b53c-6f774d42fc27","_cell_guid":"cfb3f257-15de-4ee6-880c-6ce9f04b7230","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:44.033521Z","iopub.execute_input":"2024-05-09T10:51:44.033880Z","iopub.status.idle":"2024-05-09T10:51:45.236897Z","shell.execute_reply.started":"2024-05-09T10:51:44.033852Z","shell.execute_reply":"2024-05-09T10:51:45.235727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<font style=\"font-size:18px;color:blue;font-style: italic;\" > \n<ul>\n\n<li> In every iteration, both the discriminator and generator are trained alternately, freezing the weights of the other.\n    \n<li>In the first part of the iteration, the discriminator learns to classify between real and fake images. \n\n<li>In the second part of the iteration, the generator learns to modify the fake image in a way that makes it tough for the discriminator to classify. \n\n<li>This is repeated for many iterations.\n\n\n<li>Here we have implemented simple ANN-based discriminator and generator components of GAN frameworks.\n</ul>\n    \n</font>","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras import layers, models, optimizers, Model\n\n# Setting up pandas to display all columns\npd.set_option('display.max_columns', None)\n\n# Load dataset\ndef load_data():\n    df_train = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n    data_matrix = df_train.drop('label', axis=1).values\n    data_matrix = ((data_matrix.astype(np.float32) / 255.0) * 2 - 1.0)\n    return data_matrix, df_train['label']\n\ndata_matrix, labels = load_data()\n\n\n\n# Define the generator\ndef build_generator(input_noise_dim=100, output_dim=784):\n    model = models.Sequential([\n        layers.Dense(100, use_bias=False, input_shape=(input_noise_dim,)),\n        layers.BatchNormalization(),\n        layers.LeakyReLU(),\n        layers.Dense(100),\n        layers.BatchNormalization(),\n        layers.LeakyReLU(),\n        layers.Dense(output_dim, activation='tanh')\n    ])\n    return model\n\n# Define the discriminator\ndef build_discriminator(input_dim=784):\n    model = models.Sequential([\n        layers.Dense(512, input_shape=(input_dim,)),\n        layers.LeakyReLU(0.01),\n        layers.Dropout(0.3),\n        layers.Dense(256),\n        layers.LeakyReLU(0.01),\n        layers.Dropout(0.3),\n        layers.Dense(1, activation='sigmoid')\n    ])\n    model.compile(loss='binary_crossentropy', optimizer=optimizers.Adam(0.005, 0.5), metrics=['accuracy'])\n    return model\n\n# Define the GAN\ndef build_gan(generator, discriminator):\n    discriminator.trainable = False\n    model = models.Sequential([generator, discriminator])\n    model.compile(loss='binary_crossentropy', optimizer=optimizers.Adam(0.005, 0.5), metrics=['accuracy'])\n    return model\n\n# Instantiate the models\ngenerator = build_generator()\ndiscriminator = build_discriminator()\ngan = build_gan(generator, discriminator)\n\n# Display models\ngenerator.summary()\ndiscriminator.summary()\ngan.summary()\n\n# Training function\ndef train_gan(generator, discriminator, gan, data_matrix, iterations=20, batch_size=128):\n    for iteration in range(iterations):\n        idx = np.random.randint(0, data_matrix.shape[0], batch_size)\n        real_images = data_matrix[idx]\n        \n        noise = np.random.normal(0, 1, (batch_size, 100))\n        generated_images = generator.predict(noise)\n        \n        # Train Discriminator\n        discriminator.trainable = True\n        d_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))\n        d_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((batch_size, 1)))\n        d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)\n        \n        # Train Generator\n        discriminator.trainable = False\n        noise = np.random.normal(0, 1, (batch_size, 100))\n        g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))\n\n        # Print progress\n        print(f\"Iteration {iteration + 1}/{iterations} - D Loss: {d_loss[0]}, D Accuracy: {d_loss[1]}, G Loss: {g_loss[0]}, G Accuracy: {g_loss[1]}\")\n        if iteration % 20 == 0:\n            display_generated_images(generator)\n        \n\n# Display generated images\ndef display_generated_images(generator, num_examples=10):\n    noise = np.random.normal(0, 1, (num_examples, 100))\n    generated_images = generator.predict(noise)\n    plt.figure(figsize=(10, 1))\n    for i in range(num_examples):\n        plt.subplot(1, 10, i+1)\n        plt.imshow(generated_images[i].reshape(28, 28), cmap='gray')\n        plt.axis('off')\n    plt.show()\n\n# Training the GAN\ntrain_gan(generator, discriminator, gan, data_matrix, iterations=800, batch_size=128)\n\n# Displaying generated images\ndisplay_generated_images(generator)\n","metadata":{"_uuid":"7d221225-b338-4806-8b97-fc3aff5fa7e7","_cell_guid":"5e6c6c0e-b92c-4a08-b1fd-a618290da1c0","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-05-09T10:51:45.238384Z","iopub.execute_input":"2024-05-09T10:51:45.238744Z","iopub.status.idle":"2024-05-09T10:52:56.930412Z","shell.execute_reply.started":"2024-05-09T10:51:45.238715Z","shell.execute_reply":"2024-05-09T10:52:56.928647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<font style=\"font-size:18px;color:blue;font-style: italic;\" > \n\nTaking noise as input, the generator has started creating images that look like digits, which is confusing the discriminator in classifying between true digits and generated digits.\n    \n</font>","metadata":{}}]}