{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Import Library" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "import mnist" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "import mlx.core as mx\n", "import mlx.nn as nn\n", "import mlx.optimizers as optim\n", "\n", "from tqdm import tqdm\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# GAN Architecture" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generator 👨🏻‍🎨" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "def GenBlock(in_dim:int,out_dim:int):\n", " \n", " return nn.Sequential(\n", " nn.Linear(in_dim,out_dim),\n", " nn.BatchNorm(out_dim),\n", " nn.ReLU()\n", " )" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "class Generator(nn.Module):\n", "\n", " def __init__(self, z_dim:int = 10, im_dim:int = 784, hidden_dim: int =128):\n", " super(Generator, self).__init__()\n", " # Build the neural network\n", " self.gen = nn.Sequential(\n", " GenBlock(z_dim, hidden_dim),\n", " GenBlock(hidden_dim, hidden_dim * 2),\n", " GenBlock(hidden_dim * 2, hidden_dim * 4),\n", " GenBlock(hidden_dim * 4, hidden_dim * 8),\n", "\n", "\n", " nn.Linear(hidden_dim * 8,im_dim),\n", " nn.Sigmoid()\n", " )\n", " \n", " def __call__(self, noise):\n", "\n", " return self.gen(noise)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Generator(\n", " (gen): Sequential(\n", " (layers.0): Sequential(\n", " (layers.0): Linear(input_dims=100, output_dims=128, bias=True)\n", " (layers.1): BatchNorm(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (layers.2): ReLU()\n", " )\n", " (layers.1): Sequential(\n", " (layers.0): Linear(input_dims=128, output_dims=256, bias=True)\n", " (layers.1): BatchNorm(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (layers.2): ReLU()\n", " )\n", " (layers.2): Sequential(\n", " (layers.0): Linear(input_dims=256, output_dims=512, bias=True)\n", " (layers.1): BatchNorm(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (layers.2): ReLU()\n", " )\n", " (layers.3): Sequential(\n", " (layers.0): Linear(input_dims=512, output_dims=1024, bias=True)\n", " (layers.1): BatchNorm(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (layers.2): ReLU()\n", " )\n", " (layers.4): Linear(input_dims=1024, output_dims=784, bias=True)\n", " (layers.5): Sigmoid()\n", " )\n", ")" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "gen = Generator(100)\n", "gen" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "def get_noise(n_samples, z_dim):\n", " return np.random.randn(n_samples,z_dim)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Discriminator 🕵🏻‍♂️" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "def DisBlock(in_dim:int,out_dim:int):\n", " return nn.Sequential(\n", " nn.Linear(in_dim,out_dim),\n", " nn.LeakyReLU(negative_slope=0.2)\n", " )" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [], "source": [ "class Discriminator(nn.Module):\n", "\n", " def __init__(self,im_dim:int = 784, hidden_dim:int = 128):\n", " super(Discriminator, self).__init__()\n", "\n", " self.disc = nn.Sequential(\n", " DisBlock(im_dim, hidden_dim * 4),\n", " DisBlock(hidden_dim * 4, hidden_dim * 2),\n", " DisBlock(hidden_dim * 2, hidden_dim),\n", "\n", " nn.Linear(hidden_dim,1),\n", " )\n", " \n", " def __call__(self, noise):\n", "\n", " return self.disc(noise)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Discriminator(\n", " (disc): Sequential(\n", " (layers.0): Sequential(\n", " (layers.0): Linear(input_dims=784, output_dims=512, bias=True)\n", " (layers.1): LeakyReLU()\n", " )\n", " (layers.1): Sequential(\n", " (layers.0): Linear(input_dims=512, output_dims=256, bias=True)\n", " (layers.1): LeakyReLU()\n", " )\n", " (layers.2): Sequential(\n", " (layers.0): Linear(input_dims=256, output_dims=128, bias=True)\n", " (layers.1): LeakyReLU()\n", " )\n", " (layers.3): Linear(input_dims=128, output_dims=1, bias=True)\n", " )\n", ")" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "disc = Discriminator()\n", "disc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Model Training 🏋🏻‍♂️" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# Set your parameters\n", "criterion = nn.losses.binary_cross_entropy\n", "n_epochs = 200\n", "z_dim = 64\n", "display_step = 500\n", "batch_size = 128\n", "lr = 0.00001" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "gen = Generator(z_dim)\n", "mx.eval(gen.parameters())\n", "gen_opt = optim.Adam(learning_rate=lr)\n", "\n", "disc = Discriminator()\n", "mx.eval(disc.parameters())\n", "disc_opt = optim.Adam(learning_rate=lr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Losses" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "def disc_loss(gen, disc, real, num_images, z_dim):\n", " noise = mx.array(get_noise(num_images, z_dim))\n", " fake_images = gen(noise)\n", " \n", " fake_disc = disc(fake_images)\n", " \n", " fake_labels = mx.zeros((fake_images.shape[0],1))\n", " fake_loss = nn.losses.binary_cross_entropy(fake_disc,fake_labels,with_logits=True)\n", " \n", " real_disc = disc(real)\n", " real_labels = mx.ones((real.shape[0],1))\n", "\n", " real_loss = nn.losses.binary_cross_entropy(real_disc,real_labels,with_logits=True)\n", "\n", " disc_loss = (fake_loss + real_loss) / 2\n", "\n", " return disc_loss" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "def gen_loss(gen, disc, num_images, z_dim):\n", "\n", " noise = mx.array(get_noise(num_images, z_dim))\n", " fake_images = gen(noise)\n", " fake_disc = disc(fake_images)\n", "\n", " fake_labels = mx.ones((fake_images.shape[0],1))\n", " \n", " gen_loss = nn.losses.binary_cross_entropy(fake_disc,fake_labels,with_logits=True)\n", "\n", " return gen_loss" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "train_images, _, test_images, _ = map(\n", " mx.array, getattr(mnist, 'mnist')()\n", ")" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "def batch_iterate(batch_size:int, ipt:list):\n", " perm = mx.array(np.random.permutation(len(ipt)))\n", " for s in range(0, ipt.size, batch_size):\n", " ids = perm[s : s + batch_size]\n", " yield ipt[ids]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### show batch of images" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for X in batch_iterate(16, train_images):\n", " fig,axes = plt.subplots(4, 4, figsize=(4, 4))\n", "\n", " for i, ax in enumerate(axes.flat):\n", " img = mx.array(X[i]).reshape(28,28)\n", " ax.imshow(img,cmap='gray')\n", " ax.axis('off')\n", " break" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": [ "def show_images(imgs:list[int],num_imgs:int = 25):\n", " fig,axes = plt.subplots(5, 5, figsize=(4, 4))\n", " \n", " for i, ax in enumerate(axes.flat):\n", " img = mx.array(imgs[i]).reshape(28,28)\n", " ax.imshow(img,cmap='gray')\n", " ax.axis('off')\n", " plt.show()" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(0.675341, dtype=float32)" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z_dim = 64\n", "gen = Generator(z_dim)\n", "mx.eval(gen.parameters())\n", "gen_opt = optim.Adam(learning_rate=lr)\n", "\n", "disc = Discriminator()\n", "mx.eval(disc.parameters())\n", "disc_opt = optim.Adam(learning_rate=lr)\n", "\n", "g_loss = gen_loss(gen, disc, 8, z_dim)\n", "g_loss\n" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "60000" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(train_images)" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " 0%| | 0/200 [00:00 0:\n", " print(f\"Step {epoch}: Generator loss: {G_loss}, discriminator loss: {D_loss}\")\n", " fake_noise = mx.array(get_noise(batch_size, z_dim))\n", " fake = gen(fake_noise)\n", " show_images(fake)\n", " show_images(real)\n", " cur_step += 1" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 2 }