mirror of
https://github.com/ml-explore/mlx-examples.git
synced 2025-06-26 02:33:23 +08:00
539 lines
100 KiB
Plaintext
539 lines
100 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Import Library"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 369,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import mnist"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 370,
|
|
"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": 371,
|
|
"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, 0.8),\n",
|
|
" nn.LeakyReLU(0.2)\n",
|
|
" )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 393,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class Generator(nn.Module):\n",
|
|
"\n",
|
|
" def __init__(self, z_dim:int = 10, im_dim:int = 784, hidden_dim: int = 256):\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",
|
|
" )\n",
|
|
" \n",
|
|
" def __call__(self, noise):\n",
|
|
" x = self.gen(noise)\n",
|
|
" return mx.tanh(x)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 394,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Generator(\n",
|
|
" (gen): Sequential(\n",
|
|
" (layers.0): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=100, output_dims=256, bias=True)\n",
|
|
" (layers.1): BatchNorm(256, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)\n",
|
|
" (layers.2): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.1): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=256, output_dims=512, bias=True)\n",
|
|
" (layers.1): BatchNorm(512, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)\n",
|
|
" (layers.2): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.2): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=512, output_dims=1024, bias=True)\n",
|
|
" (layers.1): BatchNorm(1024, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)\n",
|
|
" (layers.2): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.3): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=1024, output_dims=2048, bias=True)\n",
|
|
" (layers.1): BatchNorm(2048, eps=0.8, momentum=0.1, affine=True, track_running_stats=True)\n",
|
|
" (layers.2): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.4): Linear(input_dims=2048, output_dims=784, bias=True)\n",
|
|
" )\n",
|
|
")"
|
|
]
|
|
},
|
|
"execution_count": 394,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"gen = Generator(100)\n",
|
|
"gen"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 374,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# make 2D noise with shape n_samples x z_dim\n",
|
|
"def get_noise(n_samples:list[int], z_dim:int)->list[int]:\n",
|
|
" return mx.random.normal(shape=(n_samples, z_dim))"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 375,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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d955x25SrkF++ctftpudO3fajSRlecj3U8aOHWs3U6dOtZuUi51FRUV2I0mtra12s2bNGrt59dVX7aalpcVuFi1aZDeS1NjYaDcvvPCC3RQXF9tNbm7W/6R+Ssp16JTrwdngSQEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAACEnEyW18ZSDqD19PTYzY033mg3klRRUWE3Z8+etZu8vDy7STnyd/78ebuRpA8++MBu5syZYzcffvih3aQcqZOkuXPn2s0//vEPu5kyZYrdtLW12c0PfvADu5HS/k5dXV12U1BQYDeDg4N2U1ZWZjeSNHLkSLuprq62m46ODrt544037EaSFi9ebDcpByYff/zxIV/DkwIAIDAKAIDAKAAAAqMAAAiMAgAgMAoAgMAoAAACowAACIwCACAwCgCAwCgAAAKjAAAIWR/EW758uf3m9913n928/vrrdiNJx48ft5ucnBy7eeedd+xm1qxZdnPs2DG7kaQRI0bYzfTp0+2mvLzcblKOs0nSiRMn7CblANrAwIDdpByP2717t91I0sWLF+1m2rRpdnP69Gm72b59u93U1tbajSRVVVXZTXNzs92UlpbaTUNDg91I0vr16+2mvr7ebh566KEhX8OTAgAgMAoAgMAoAAACowAACIwCACAwCgCAwCgAAAKjAAAIjAIAIDAKAIDAKAAAAqMAAAhZH8Rbs2aN/eYlJSV2093dbTeStH//fru59tpr7aampsZuNm/ebDeVlZV2I6UdBhwcHLSbbdu22c2dd95pN5I0adIku2lqarKbpUuX2s2ZM2fspq+vz24kqa2tzW7mzp1rN1u2bLGbVatW2c2OHTvsRpI+//nP203Kvyv5+fl2k+U/p/9Lyt+ps7PTblavXj3ka3hSAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAYBQAACE32xeWlpbabz4wMGA35eXldiOlHZBrbm62mzlz5tjN7bffbjcXLlywG0kaM2aM3RQWFtpNyvepqKjIbqS0A3IpR/Ta29vtZsGCBXaTcthOkg4fPmw33//+9+0m5fv0zDPP2E1eXp7dSNJjjz1mN62trXbz0EMP2U1FRYXdSGnf29TjoUPhSQEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAAAERgEAELK+kppyOfGll16ym/7+fruRpEuXLtnNxYsX7Wb79u12c++999pNytdOkjo6Ouzmtddes5uf/vSndrN37167kaRvfvObdvPyyy/bzZe+9CW7Sfl56OzstBtJGjt2rN28+OKLdnPFFVfYzfnz5+0m9WruqlWr7Obvf/+73ZSVldnNn/70J7uRpIULF9pNY2Nj0mcNhScFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAAAERgEAELI+iHfgwAH7zVOO29XW1tqNJI0YMcJuMpmM3WzatMluWltb7SY3N+tvzafcdddddlNdXW03Dz74oN2kHLaTpHXr1tnNsmXL7ObUqVN2k3II7jvf+Y7dSGlHEk+fPm03dXV1dpNy9HHlypV2I0njxo2zm7feestuUg4X5uXl2Y0klZaW2k13d3fSZw2FJwUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQsr66tnXrVvvNFy9ebDcPP/yw3UjS/fffbzfPP/+83RQXF9tNWVmZ3RQWFtqNJB06dMhujh49ajc33HCD3bS3t9uNlPY137Bhg92kHGPcvHmz3RQUFNiNlHYk8bM6+nj27Fm7STlSJ0mNjY12M2yY///f+vp6u3nkkUfsRkr783V1dSV91lB4UgAABEYBABAYBQBAYBQAAIFRAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAAAhJ5Plxaxf/OIX9puPGzfObrq7u+0mVcqRv4aGBrv56KOP7KakpMRuJGnixIl2k3KYbPny5Xazc+dOu5GkG2+80W5ycnLspq2tzW7y8/PtJuXnTpKuuuoqu0k5XJhylHLNmjV2c/DgQbuRpOHDh9tNyu9gSjNhwgS7kdIO4qV8/Zqamob+s9jvCgD4r8UoAAACowAACIwCACAwCgCAwCgAAAKjAAAIjAIAIDAKAIDAKAAAAqMAAAiMAgAg5Gb7wpSjaRUVFXZz22232Y0kNTc32011dbXdDAwM2E1NTY3d7N69224k6f3337ebRYsW2U3KIbgxY8bYjSSdOHHCblKOx40ePdpurrjiCrtJPZq2ePFiu0k5HpfyOR988IHd9PX12Y0k7dmzx24eeOABu/n1r39tNyk/q5JUVlZmN9ddd13SZw2FJwUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQMj6Suq3v/1t+827u7vt5umnn7YbSfrqV79qN8ePH7ebjz76yG727dtnNyUlJXYjSdOnT7ebmTNn2s3GjRvtZtSoUXYjSV1dXXZz9dVX282hQ4fsJuUa6ze+8Q27kaRt27bZzZYtW+ymoaHBbtavX283qV+HFStW2E17e7vdpPzeLly40G4kacSIEXaTyWSSPmsoPCkAAAKjAAAIjAIAIDAKAIDAKAAAAqMAAAiMAgAgMAoAgMAoAAACowAACIwCACAwCgCAkPVBvL/85S/2m8+YMcNuioqK7EaSiouL7SblyN+tt95qN3V1dXazbt06u5GkyspKu+no6LCbU6dO2U1eXp7dSFJZWZnd9PX12c2ePXvs5o477rCbzZs3240kHTlyxG5SfvaGDx9uNytXrrSblpYWu5Gk5uZmu6moqLCbxsZGu0k5bCdJg4ODdpPye5ENnhQAAIFRAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAyPog3pw5c+w3z8/Pt5vXXnvNbiTpe9/7nt08+OCDdpNyWKu0tNRuent77UZK+5qnHECbPHmy3aQeC3vllVfsprW11W5SjtulHBNMOdYnSStWrLCbf//733aT8ud78cUX7aaqqspuJOn666+3m2HD/P//Hjp0yG4uXbpkN5J0+fJlu/nkk0+SPmsoPCkAAAKjAAAIjAIAIDAKAIDAKAAAAqMAAAiMAgAgMAoAgMAoAAACowAACIwCACAwCgCAkPVBvHnz5tlv/txzz9lNUVGR3UjSo48+ajd//vOf7ebo0aN2k3K4qra21m6ktGNmjY2NdnP48GG7uXDhgt1I0re+9S272bFjh93k5mb96xCef/55u1m2bJndSNK6devs5o9//KPdpByKbGhosJuU75EkTZo0yW7Ky8vt5sCBA3Zz00032Y0kHTlyxG5SDysOhScFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAABEYBABAYBQBAYBQAAIFRAAAERgEAEBgFAEDI+izk66+/br95yiXNd999126ktIuGhYWFdvO73/3Obqqqquwm5aqjJO3fv99upk6dajcpf74VK1bYjSS9/fbbdvOvf/3Lbq6++mq7GRwctJtrrrnGbiRp9erVdrNkyRK72bBhg93ccsstdpP6daisrLSbxx57zG5mz55tN3V1dXYjSb29vXaza9eupM8aCk8KAIDAKAAAAqMAAAiMAgAgMAoAgMAoAAACowAACIwCACAwCgCAwCgAAAKjAAAIjAIAIORkMplMNi9cu3at/ebjxo2zm46ODruRpP7+frs5cuSI3YwePdpuVq5caTdjx461G0l6/PHH7Sbl75RyRG/kyJF2I6UdFKyoqLCb3//+93bz9NNP203KkTpJKigosJuTJ0/aTU1Njd2kHJf8wx/+YDeSVFpaajcpX4d77rnHbrZu3Wo3knTw4EG7Sfk5WrVq1ZCv4UkBABAYBQBAYBQAAIFRAAAERgEAEBgFAEBgFAAAgVEAAARGAQAQGAUAQGAUAACBUQAAhKwP4gEA/vvxpAAACIwCACAwCgCAwCgAAAKjAAAIjAIAIDAKAIDAKAAAAqMAAAj/AyUT0oK8p4s5AAAAAElFTkSuQmCC",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"img = get_noise(28,28)\n",
|
|
"plt.imshow(img, cmap='gray')\n",
|
|
"plt.axis('off')\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Discriminator 🕵🏻♂️"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 376,
|
|
"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": 377,
|
|
"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",
|
|
" DisBlock(im_dim, hidden_dim * 2),\n",
|
|
" DisBlock(hidden_dim * 2, hidden_dim),\n",
|
|
"\n",
|
|
" nn.Linear(hidden_dim,1),\n",
|
|
" nn.Sigmoid()\n",
|
|
" )\n",
|
|
" \n",
|
|
" def __call__(self, noise):\n",
|
|
" return self.disc(noise)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 378,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"Discriminator(\n",
|
|
" (disc): Sequential(\n",
|
|
" (layers.0): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=784, output_dims=256, bias=True)\n",
|
|
" (layers.1): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.1): Sequential(\n",
|
|
" (layers.0): Linear(input_dims=256, output_dims=128, bias=True)\n",
|
|
" (layers.1): LeakyReLU()\n",
|
|
" )\n",
|
|
" (layers.2): Linear(input_dims=128, output_dims=1, bias=True)\n",
|
|
" (layers.3): Sigmoid()\n",
|
|
" )\n",
|
|
")"
|
|
]
|
|
},
|
|
"execution_count": 378,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"disc = Discriminator()\n",
|
|
"disc"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Model Training 🏋🏻♂️"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Losses"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Discriminator Loss"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 379,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def disc_loss(gen, disc, real, num_images, z_dim):\n",
|
|
" \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",
|
|
" \n",
|
|
" fake_loss = nn.losses.binary_cross_entropy(fake_disc,fake_labels)\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)\n",
|
|
"\n",
|
|
" disc_loss = (fake_loss + real_loss) / 2\n",
|
|
"\n",
|
|
" return disc_loss"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"#### Generator Loss"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 380,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def gen_loss(gen, disc, num_images, z_dim):\n",
|
|
"\n",
|
|
" noise = mx.array(get_noise(num_images, z_dim))\n",
|
|
" \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)\n",
|
|
"\n",
|
|
" return gen_loss"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 381,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Get only the training images\n",
|
|
"train_images,*_ = map(np.array, mnist.mnist())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 382,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# Normalize the images to fall between -1,1\n",
|
|
"train_images = train_images * 2.0 - 1.0"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 383,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"<matplotlib.image.AxesImage at 0x157b0bb80>"
|
|
]
|
|
},
|
|
"execution_count": 383,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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WqRt27Zpz549cT/6pbudD992HG4nXc+HjIhQ7969NXLkSFVVVcU9XlVVpaKiIqNV2Wtra9OXX36pcDhsvRQzhYWFCoVCcefGtWvXVFNT063PDUlqbm5WfX19lzo/nHNauHChtmzZot27d6uwsDDu+e5yPtztONxO2p4Phl8U4cknn3zievXq5f7whz+4EydOuMWLF7t+/fq5M2fOWC/tgXnttddcdXW1O336tNu/f797/vnnXSAQ6PLHoKWlxR05csQdOXLESXJr1qxxR44ccf/5z3+cc86tXLnSBYNBt2XLFnfs2DE3Z84cFw6HXTQaNV55ct3pOLS0tLjXXnvN1dbWurq6Ordnzx43btw49+ijj3ap4/CLX/zCBYNBV11d7RoaGmLb5cuXY/t0h/Phbschk86HjImQc869//77rqCgwPXu3ds99dRTcV+O2B3Mnj3bhcNh16tXL5eXl+dmzpzpjh8/br2slNuzZ4+T1GkrLS11zt34stzly5e7UCjk/H6/mzBhgjt27JjtolPgTsfh8uXLrri42A0YMMD16tXLDRo0yJWWlrqzZ89aLzupbvfnl+QqKytj+3SH8+FuxyGTzgd+lAMAwExGvCcEAOiaiBAAwAwRAgCYIUIAADNECABghggBAMwQIQCAGSIEADBDhAAAZogQAMAMEQIAmCFCAAAz/wdVbyhNmNF0pQAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"plt.imshow(train_images[0].reshape(28,28),cmap='gray')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 384,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def batch_iterate(batch_size: int, ipt: list[int])-> list[int]:\n",
|
|
" perm = np.random.permutation(len(ipt))\n",
|
|
" for s in range(0, len(ipt), batch_size):\n",
|
|
" ids = perm[s : s + batch_size]\n",
|
|
" yield ipt[ids]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 385,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"def show_images(imgs:list[int],num_imgs:int = 25):\n",
|
|
" if (imgs.shape[0] > 0): \n",
|
|
" fig,axes = plt.subplots(5, 5, figsize=(5, 5))\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": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### show first batch of images"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 386,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 500x500 with 25 Axes>"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"X = batch_iterate(25, train_images)\n",
|
|
"for x in X: \n",
|
|
" show_images(x)\n",
|
|
" break"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Training Cycle"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 391,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"lr = 0.002\n",
|
|
"z_dim = 100\n",
|
|
"\n",
|
|
"gen = Generator(z_dim)\n",
|
|
"mx.eval(gen.parameters())\n",
|
|
"gen_opt = optim.Adam(learning_rate=lr,betas=[0.5, 0.999])\n",
|
|
"\n",
|
|
"disc = Discriminator()\n",
|
|
"mx.eval(disc.parameters())\n",
|
|
"disc_opt = optim.Adam(learning_rate=lr,betas=[0.5, 0.999])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 395,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" 4%|▍ | 9/200 [00:59<21:10, 6.65s/it]"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Set your parameters\n",
|
|
"n_epochs = 200\n",
|
|
"display_step = 5000\n",
|
|
"cur_step = 0\n",
|
|
"\n",
|
|
"batch_size = 128\n",
|
|
"\n",
|
|
"D_loss_grad = nn.value_and_grad(disc, disc_loss)\n",
|
|
"G_loss_grad = nn.value_and_grad(gen, gen_loss)\n",
|
|
"\n",
|
|
"\n",
|
|
"for epoch in tqdm(range(n_epochs)):\n",
|
|
"\n",
|
|
" for real in batch_iterate(batch_size, train_images):\n",
|
|
" \n",
|
|
" # TODO Train Discriminator\n",
|
|
" D_loss,D_grads = D_loss_grad(gen, disc,mx.array(real), batch_size, z_dim)\n",
|
|
"\n",
|
|
" # Update optimizer\n",
|
|
" disc_opt.update(disc, D_grads)\n",
|
|
" \n",
|
|
" # Update gradients\n",
|
|
" mx.eval(disc.parameters(), disc_opt.state)\n",
|
|
"\n",
|
|
" # TODO Train Generator\n",
|
|
" G_loss,G_grads = G_loss_grad(gen, disc, batch_size, z_dim)\n",
|
|
" \n",
|
|
" # Update optimizer\n",
|
|
" gen_opt.update(gen, G_grads)\n",
|
|
" \n",
|
|
" # Update gradients\n",
|
|
" mx.eval(gen.parameters(), gen_opt.state)\n",
|
|
" \n",
|
|
" \n",
|
|
" if (cur_step + 1) % display_step == 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
|
|
}
|