Skip to content

Commit db5b02b

Browse files
authored
Merge Chapter12_Part5
Gans Code
2 parents b40c6a2 + 5e6b0fe commit db5b02b

File tree

1 file changed

+248
-0
lines changed

1 file changed

+248
-0
lines changed

Chapter12/Part_05/chapter_12.ipynb

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {
6+
"id": "QmRAEtvJ_6OT"
7+
},
8+
"source": [
9+
"# **Deep Learning With Python - CHAPTER 12**"
10+
]
11+
},
12+
{
13+
"cell_type": "markdown",
14+
"metadata": {
15+
"id": "8HE2uMKK_7Qp"
16+
},
17+
"source": [
18+
"- This code implements a **Generative Adversarial Network (GAN)** to generate realistic face images using the **CelebA dataset**.\n",
19+
"\n",
20+
"- It is structured into several classes for better modularity:\n",
21+
" \n",
22+
" `CelebAGANDataLoader` handles dataset downloading and preprocessing, `Discriminator` and `Generator` define the two neural networks, `GAN` encapsulates the training logic, and `GANMonitor` saves generated images during training.\n",
23+
"\n",
24+
"- The model is trained using **binary cross-entropy loss**, and the generator learns to create increasingly realistic images by competing with the discriminator. The training loop runs for **100 epochs**, generating images at the end of each epoch."
25+
]
26+
},
27+
{
28+
"cell_type": "code",
29+
"execution_count": 2,
30+
"metadata": {
31+
"id": "oqNg9frRCBgk"
32+
},
33+
"outputs": [],
34+
"source": [
35+
"import os\n",
36+
"import pathlib\n",
37+
"import random\n",
38+
"import tensorflow as tf\n",
39+
"from tensorflow import keras\n",
40+
"import matplotlib.pyplot as plt\n",
41+
"from tensorflow.keras import layers"
42+
]
43+
},
44+
{
45+
"cell_type": "code",
46+
"execution_count": 3,
47+
"metadata": {
48+
"id": "7HHCQEtlu8Pg"
49+
},
50+
"outputs": [],
51+
"source": [
52+
"class CelebAGANDataLoader:\n",
53+
" def __init__(self, dataset_path=\"celeba_gan\", image_size=(64, 64), batch_size=32):\n",
54+
" self.dataset_path = dataset_path\n",
55+
" self.image_size = image_size\n",
56+
" self.batch_size = batch_size\n",
57+
"\n",
58+
" def download_and_extract_data(self):\n",
59+
" os.makedirs(self.dataset_path, exist_ok=True)\n",
60+
" !gdown --id 1O7m1010EJjLE5QxLZiM9Fpjs7Oj6e684 -O {self.dataset_path}/data.zip\n",
61+
" !unzip -qq {self.dataset_path}/data.zip -d {self.dataset_path}\n",
62+
"\n",
63+
" def load_dataset(self):\n",
64+
" dataset = keras.utils.image_dataset_from_directory(\n",
65+
" self.dataset_path,\n",
66+
" label_mode=None,\n",
67+
" image_size=self.image_size,\n",
68+
" batch_size=self.batch_size,\n",
69+
" smart_resize=True\n",
70+
" )\n",
71+
" return dataset.map(lambda x: x / 255.0)"
72+
]
73+
},
74+
{
75+
"cell_type": "code",
76+
"source": [
77+
"class Discriminator(keras.Model):\n",
78+
" def __init__(self, input_shape=(64, 64, 3)):\n",
79+
" super().__init__()\n",
80+
" self.model = keras.Sequential([\n",
81+
" layers.Conv2D(64, kernel_size=4, strides=2, padding=\"same\"),\n",
82+
" layers.LeakyReLU(alpha=0.2),\n",
83+
" layers.Conv2D(128, kernel_size=4, strides=2, padding=\"same\"),\n",
84+
" layers.LeakyReLU(alpha=0.2),\n",
85+
" layers.Conv2D(128, kernel_size=4, strides=2, padding=\"same\"),\n",
86+
" layers.LeakyReLU(alpha=0.2),\n",
87+
" layers.Flatten(),\n",
88+
" layers.Dropout(0.2),\n",
89+
" layers.Dense(1, activation=\"sigmoid\"),\n",
90+
" ], name=\"discriminator\")\n",
91+
"\n",
92+
" def call(self, inputs):\n",
93+
" return self.model(inputs)"
94+
],
95+
"metadata": {
96+
"id": "6mitfoIAJY0r"
97+
},
98+
"execution_count": 4,
99+
"outputs": []
100+
},
101+
{
102+
"cell_type": "code",
103+
"source": [
104+
"class Generator(keras.Model):\n",
105+
" def __init__(self, latent_dim=128):\n",
106+
" super().__init__()\n",
107+
" self.model = keras.Sequential([\n",
108+
" layers.Dense(8 * 8 * 128, input_shape=(latent_dim,)),\n",
109+
" layers.Reshape((8, 8, 128)),\n",
110+
" layers.Conv2DTranspose(128, kernel_size=4, strides=2, padding=\"same\"),\n",
111+
" layers.LeakyReLU(alpha=0.2),\n",
112+
" layers.Conv2DTranspose(256, kernel_size=4, strides=2, padding=\"same\"),\n",
113+
" layers.LeakyReLU(alpha=0.2),\n",
114+
" layers.Conv2DTranspose(512, kernel_size=4, strides=2, padding=\"same\"),\n",
115+
" layers.LeakyReLU(alpha=0.2),\n",
116+
" layers.Conv2D(3, kernel_size=5, padding=\"same\", activation=\"sigmoid\"),\n",
117+
" ], name=\"generator\")\n",
118+
"\n",
119+
" def call(self, inputs):\n",
120+
" return self.model(inputs)"
121+
],
122+
"metadata": {
123+
"id": "qr8jz4GeLVbT"
124+
},
125+
"execution_count": 5,
126+
"outputs": []
127+
},
128+
{
129+
"cell_type": "code",
130+
"source": [
131+
"class GAN(keras.Model):\n",
132+
" def __init__(self, discriminator, generator, latent_dim):\n",
133+
" super().__init__()\n",
134+
" self.discriminator = discriminator\n",
135+
" self.generator = generator\n",
136+
" self.latent_dim = latent_dim\n",
137+
" self.d_loss_metric = keras.metrics.Mean(name=\"d_loss\")\n",
138+
" self.g_loss_metric = keras.metrics.Mean(name=\"g_loss\")\n",
139+
"\n",
140+
" def compile(self, d_optimizer, g_optimizer, loss_fn):\n",
141+
" super().compile()\n",
142+
" self.d_optimizer = d_optimizer\n",
143+
" self.g_optimizer = g_optimizer\n",
144+
" self.loss_fn = loss_fn\n",
145+
"\n",
146+
" @property\n",
147+
" def metrics(self):\n",
148+
" return [self.d_loss_metric, self.g_loss_metric]\n",
149+
"\n",
150+
" def train_step(self, real_images):\n",
151+
" batch_size = tf.shape(real_images)[0]\n",
152+
" random_latent_vectors = tf.random.normal(shape=(batch_size, self.latent_dim))\n",
153+
" generated_images = self.generator(random_latent_vectors)\n",
154+
" combined_images = tf.concat([generated_images, real_images], axis=0)\n",
155+
"\n",
156+
" labels = tf.concat([tf.ones((batch_size, 1)), tf.zeros((batch_size, 1))], axis=0)\n",
157+
" labels += 0.05 * tf.random.uniform(tf.shape(labels))\n",
158+
"\n",
159+
" with tf.GradientTape() as tape:\n",
160+
" predictions = self.discriminator(combined_images)\n",
161+
" d_loss = self.loss_fn(labels, predictions)\n",
162+
" grads = tape.gradient(d_loss, self.discriminator.trainable_weights)\n",
163+
" self.d_optimizer.apply_gradients(zip(grads, self.discriminator.trainable_weights))\n",
164+
"\n",
165+
" random_latent_vectors = tf.random.normal(shape=(batch_size, self.latent_dim))\n",
166+
" misleading_labels = tf.zeros((batch_size, 1))\n",
167+
"\n",
168+
" with tf.GradientTape() as tape:\n",
169+
" predictions = self.discriminator(self.generator(random_latent_vectors))\n",
170+
" g_loss = self.loss_fn(misleading_labels, predictions)\n",
171+
" grads = tape.gradient(g_loss, self.generator.trainable_weights)\n",
172+
" self.g_optimizer.apply_gradients(zip(grads, self.generator.trainable_weights))\n",
173+
"\n",
174+
" self.d_loss_metric.update_state(d_loss)\n",
175+
" self.g_loss_metric.update_state(g_loss)\n",
176+
" return {\"d_loss\": self.d_loss_metric.result(), \"g_loss\": self.g_loss_metric.result()}"
177+
],
178+
"metadata": {
179+
"id": "5KU0n2MpLXsb"
180+
},
181+
"execution_count": 6,
182+
"outputs": []
183+
},
184+
{
185+
"cell_type": "code",
186+
"source": [
187+
"class GANMonitor(keras.callbacks.Callback):\n",
188+
" def __init__(self, num_img=3, latent_dim=128):\n",
189+
" self.num_img = num_img\n",
190+
" self.latent_dim = latent_dim\n",
191+
"\n",
192+
" def on_epoch_end(self, epoch, logs=None):\n",
193+
" random_latent_vectors = tf.random.normal(shape=(self.num_img, self.latent_dim))\n",
194+
" generated_images = self.model.generator(random_latent_vectors)\n",
195+
" generated_images *= 255\n",
196+
" generated_images = generated_images.numpy()\n",
197+
"\n",
198+
" for i in range(self.num_img):\n",
199+
" img = keras.utils.array_to_img(generated_images[i])\n",
200+
" img.save(f\"generated_img_{epoch:03d}_{i}.png\")"
201+
],
202+
"metadata": {
203+
"id": "DkfZR6EULaJ6"
204+
},
205+
"execution_count": 7,
206+
"outputs": []
207+
},
208+
{
209+
"cell_type": "code",
210+
"source": [
211+
"if __name__ == \"__main__\":\n",
212+
" data_loader = CelebAGANDataLoader()\n",
213+
" dataset = data_loader.load_dataset()\n",
214+
"\n",
215+
" discriminator = Discriminator()\n",
216+
" generator = Generator(latent_dim=128)\n",
217+
"\n",
218+
" gan = GAN(discriminator=discriminator, generator=generator, latent_dim=128)\n",
219+
" gan.compile(\n",
220+
" d_optimizer=keras.optimizers.Adam(learning_rate=0.0001),\n",
221+
" g_optimizer=keras.optimizers.Adam(learning_rate=0.0001),\n",
222+
" loss_fn=keras.losses.BinaryCrossentropy(),\n",
223+
" )\n",
224+
"\n",
225+
" gan.fit(dataset, epochs=100, callbacks=[GANMonitor(num_img=10, latent_dim=128)])"
226+
],
227+
"metadata": {
228+
"id": "8J0DSS30O0uZ"
229+
},
230+
"execution_count": null,
231+
"outputs": []
232+
}
233+
],
234+
"metadata": {
235+
"colab": {
236+
"provenance": []
237+
},
238+
"kernelspec": {
239+
"display_name": "Python 3",
240+
"name": "python3"
241+
},
242+
"language_info": {
243+
"name": "python"
244+
}
245+
},
246+
"nbformat": 4,
247+
"nbformat_minor": 0
248+
}

0 commit comments

Comments
 (0)