diff --git a/.gitignore b/.gitignore
index feaca95..a41985f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.ipynb_checkpoints
.vscode
+data
diff --git a/01. Introduction/.gitignore b/01. Introduction/.gitignore
deleted file mode 100644
index 1269488..0000000
--- a/01. Introduction/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-data
diff --git a/01. Introduction/MNIST_GAN.ipynb b/01. Introduction/MNIST_GAN.ipynb
index 9b015bf..2ed8761 100644
--- a/01. Introduction/MNIST_GAN.ipynb
+++ b/01. Introduction/MNIST_GAN.ipynb
@@ -45,7 +45,7 @@
"transform = transforms.ToTensor()\n",
"\n",
"# MNIST dataset\n",
- "mnist = datasets.MNIST(root='./data/',\n",
+ "mnist = datasets.MNIST(root='../data/',\n",
" train=True,\n",
" transform=transform,\n",
" download=True,)\n",
@@ -295,4 +295,4 @@
},
"nbformat": 4,
"nbformat_minor": 1
-}
+}
\ No newline at end of file
diff --git a/02. DCGAN/DCGAN.ipynb b/02. DCGAN/DCGAN.ipynb
index 5451e21..0f0b2d2 100644
--- a/02. DCGAN/DCGAN.ipynb
+++ b/02. DCGAN/DCGAN.ipynb
@@ -71,7 +71,7 @@
"transform = transforms.ToTensor()\n",
"\n",
"# MNIST dataset\n",
- "mnist = datasets.MNIST(root='./data/',\n",
+ "mnist = datasets.MNIST(root='../data/',\n",
" train=True,\n",
" transform=transform,\n",
" download=True,)\n",
diff --git a/03. Conditional GAN/README.md b/03. Conditional GAN/README.md
new file mode 100644
index 0000000..db5cd89
--- /dev/null
+++ b/03. Conditional GAN/README.md
@@ -0,0 +1,25 @@
+# Conditional GAN
+
+Gan được ứng dụng vào bài toán sinh số viết tay trong 2 bài trước, [GAN](../01.%20Introduction/README.md) và [DCGAN](../02.%20DCGAN/README.md). Kết quả thu được cũng khá khả quan :smile:
+
+Tuy nhiên có 1 vấn đề nhỏ của ảnh được sinh ra: chúng ta không biết ảnh sinh ra là số gì, chỉ biết rằng đó là số. Vậy làm thế nào để có thể nói cho mô hình biết rằng hãy sinh ra số 1, số 2 đi? Conditional GAN sinh ra để giải quyết vấn đề đó.
+
+## Kiến trúc cGAN
+
+Conditional GAN được giới thiệu ngay sau khi GAN được ra mắt ([bài báo](https://arxiv.org/abs/1411.1784)) với ý tưởng khá đơn giản: nối thêm vector label vào input của cả bộ Generator và Discriminator.
+
+![cGAN](images/cgan.png)
+
+> Kiến trúc cGAN (ảnh lấy từ bài báo gốc)
+
+Cúng không có quá nhiều để nói về mô hình này. Bắt tay triển khai thử thôi :muscle:
+
+## Triển khai và kết quả
+
+Mình sẽ sử dụng lại gần như [toàn bộ code của bài GAN](../01.%20Introduction/MNIST_GAN.ipynb) với 1 chút thay đổi nhỏ:
+
+### Bộ Discriminator
+
+### Bộ Generator
+
+### Kết quả
diff --git a/03. Conditional GAN/cGAN.ipynb b/03. Conditional GAN/cGAN.ipynb
new file mode 100644
index 0000000..05689e6
--- /dev/null
+++ b/03. Conditional GAN/cGAN.ipynb
@@ -0,0 +1,1544 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "accelerator": "GPU",
+ "colab": {
+ "name": "Untitled0.ipynb",
+ "provenance": [],
+ "collapsed_sections": [],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "display_name": "Python 3",
+ "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.8.5"
+ },
+ "widgets": {
+ "application/vnd.jupyter.widget-state+json": {
+ "7852865bf1c347debef9e09770ab1130": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HBoxModel",
+ "state": {
+ "_view_name": "HBoxView",
+ "_dom_classes": [],
+ "_model_name": "HBoxModel",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "box_style": "",
+ "layout": "IPY_MODEL_c4d91d6707e4414784b6bba22c604ec9",
+ "_model_module": "@jupyter-widgets/controls",
+ "children": [
+ "IPY_MODEL_97799fa5b652408684e659116b875a73",
+ "IPY_MODEL_1b563eda8ea140e885ed5dd0e7928ab2"
+ ]
+ }
+ },
+ "c4d91d6707e4414784b6bba22c604ec9": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "97799fa5b652408684e659116b875a73": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "FloatProgressModel",
+ "state": {
+ "_view_name": "ProgressView",
+ "style": "IPY_MODEL_262401a52a6447669dc72856ad1463ff",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "FloatProgressModel",
+ "bar_style": "success",
+ "max": 9912422,
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": 9912422,
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "orientation": "horizontal",
+ "min": 0,
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_78e03c92e78b44b9998f50cd62ebc4cd"
+ }
+ },
+ "1b563eda8ea140e885ed5dd0e7928ab2": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HTMLModel",
+ "state": {
+ "_view_name": "HTMLView",
+ "style": "IPY_MODEL_4fe1ab86f34f421d912ab3ba7fb6ca9c",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "HTMLModel",
+ "placeholder": "",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": " 9913344/? [07:09<00:00, 23087.39it/s]",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_b13b88b0f1b9498881dd2c0f36fc3052"
+ }
+ },
+ "262401a52a6447669dc72856ad1463ff": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "ProgressStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "ProgressStyleModel",
+ "description_width": "initial",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "bar_color": null,
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "78e03c92e78b44b9998f50cd62ebc4cd": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "4fe1ab86f34f421d912ab3ba7fb6ca9c": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "DescriptionStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "DescriptionStyleModel",
+ "description_width": "",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "b13b88b0f1b9498881dd2c0f36fc3052": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "8f77425bd2d3422aa86a6104f21d57a5": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HBoxModel",
+ "state": {
+ "_view_name": "HBoxView",
+ "_dom_classes": [],
+ "_model_name": "HBoxModel",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "box_style": "",
+ "layout": "IPY_MODEL_41888726d40b40a68ae98c174cf7eda0",
+ "_model_module": "@jupyter-widgets/controls",
+ "children": [
+ "IPY_MODEL_8463317a408e41708e17702ef1f2c8df",
+ "IPY_MODEL_69284303eb4d43f2be4c17a84f694d68"
+ ]
+ }
+ },
+ "41888726d40b40a68ae98c174cf7eda0": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "8463317a408e41708e17702ef1f2c8df": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "FloatProgressModel",
+ "state": {
+ "_view_name": "ProgressView",
+ "style": "IPY_MODEL_b8018a87a5144750af0bee0b0262f4f1",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "FloatProgressModel",
+ "bar_style": "success",
+ "max": 28881,
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": 28881,
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "orientation": "horizontal",
+ "min": 0,
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_1c5d42cc6c334c7687e9f3ae2fdcb61f"
+ }
+ },
+ "69284303eb4d43f2be4c17a84f694d68": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HTMLModel",
+ "state": {
+ "_view_name": "HTMLView",
+ "style": "IPY_MODEL_77277c0fbfbd42ceb3fcab8934bad29a",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "HTMLModel",
+ "placeholder": "",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": " 29696/? [00:01<00:00, 27213.38it/s]",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_f33701338c3f420a985af78bc99e1b26"
+ }
+ },
+ "b8018a87a5144750af0bee0b0262f4f1": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "ProgressStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "ProgressStyleModel",
+ "description_width": "initial",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "bar_color": null,
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "1c5d42cc6c334c7687e9f3ae2fdcb61f": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "77277c0fbfbd42ceb3fcab8934bad29a": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "DescriptionStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "DescriptionStyleModel",
+ "description_width": "",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "f33701338c3f420a985af78bc99e1b26": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "33782ea5d5be4084a9c0d2128fdcd9c9": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HBoxModel",
+ "state": {
+ "_view_name": "HBoxView",
+ "_dom_classes": [],
+ "_model_name": "HBoxModel",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "box_style": "",
+ "layout": "IPY_MODEL_1cb4651f7f58413b8b14640e8eab53c3",
+ "_model_module": "@jupyter-widgets/controls",
+ "children": [
+ "IPY_MODEL_d319ddd23e5b4b7ab0b39732245d9dd8",
+ "IPY_MODEL_7a33dbd0855b4307becfe2033ac9263e"
+ ]
+ }
+ },
+ "1cb4651f7f58413b8b14640e8eab53c3": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "d319ddd23e5b4b7ab0b39732245d9dd8": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "FloatProgressModel",
+ "state": {
+ "_view_name": "ProgressView",
+ "style": "IPY_MODEL_1c28a2e0529848858db8f5e87c06fdd5",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "FloatProgressModel",
+ "bar_style": "success",
+ "max": 1648877,
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": 1648877,
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "orientation": "horizontal",
+ "min": 0,
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_842a2820f60d4a9280a0a978ca56a706"
+ }
+ },
+ "7a33dbd0855b4307becfe2033ac9263e": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HTMLModel",
+ "state": {
+ "_view_name": "HTMLView",
+ "style": "IPY_MODEL_d251d2b92134444d853c3bc8309d6288",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "HTMLModel",
+ "placeholder": "",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": " 1649664/? [07:06<00:00, 3868.08it/s]",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_4f75b7bf77c841868384d733234fadef"
+ }
+ },
+ "1c28a2e0529848858db8f5e87c06fdd5": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "ProgressStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "ProgressStyleModel",
+ "description_width": "initial",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "bar_color": null,
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "842a2820f60d4a9280a0a978ca56a706": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "d251d2b92134444d853c3bc8309d6288": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "DescriptionStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "DescriptionStyleModel",
+ "description_width": "",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "4f75b7bf77c841868384d733234fadef": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "1818af2ea04444378c71ca23130c9bd2": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HBoxModel",
+ "state": {
+ "_view_name": "HBoxView",
+ "_dom_classes": [],
+ "_model_name": "HBoxModel",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "box_style": "",
+ "layout": "IPY_MODEL_f2c4924e07a448d0b993b8b924aaa62a",
+ "_model_module": "@jupyter-widgets/controls",
+ "children": [
+ "IPY_MODEL_2f45f5df3a2b4244877927031aff2b05",
+ "IPY_MODEL_7388289568f041a2861c1858dfb90abb"
+ ]
+ }
+ },
+ "f2c4924e07a448d0b993b8b924aaa62a": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "2f45f5df3a2b4244877927031aff2b05": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "FloatProgressModel",
+ "state": {
+ "_view_name": "ProgressView",
+ "style": "IPY_MODEL_e96eb472c67c4f7f8cabef30d30240e3",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "FloatProgressModel",
+ "bar_style": "success",
+ "max": 4542,
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": 4542,
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "orientation": "horizontal",
+ "min": 0,
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_a0e92cab73db4dc6916c8a048eb83be1"
+ }
+ },
+ "7388289568f041a2861c1858dfb90abb": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "HTMLModel",
+ "state": {
+ "_view_name": "HTMLView",
+ "style": "IPY_MODEL_e7c31a095d0b4fe5b762bff439bdcc93",
+ "_dom_classes": [],
+ "description": "",
+ "_model_name": "HTMLModel",
+ "placeholder": "",
+ "_view_module": "@jupyter-widgets/controls",
+ "_model_module_version": "1.5.0",
+ "value": " 5120/? [00:15<00:00, 336.88it/s]",
+ "_view_count": null,
+ "_view_module_version": "1.5.0",
+ "description_tooltip": null,
+ "_model_module": "@jupyter-widgets/controls",
+ "layout": "IPY_MODEL_f9b833376de04208a2af95dbebb33285"
+ }
+ },
+ "e96eb472c67c4f7f8cabef30d30240e3": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "ProgressStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "ProgressStyleModel",
+ "description_width": "initial",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "bar_color": null,
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "a0e92cab73db4dc6916c8a048eb83be1": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ },
+ "e7c31a095d0b4fe5b762bff439bdcc93": {
+ "model_module": "@jupyter-widgets/controls",
+ "model_name": "DescriptionStyleModel",
+ "state": {
+ "_view_name": "StyleView",
+ "_model_name": "DescriptionStyleModel",
+ "description_width": "",
+ "_view_module": "@jupyter-widgets/base",
+ "_model_module_version": "1.5.0",
+ "_view_count": null,
+ "_view_module_version": "1.2.0",
+ "_model_module": "@jupyter-widgets/controls"
+ }
+ },
+ "f9b833376de04208a2af95dbebb33285": {
+ "model_module": "@jupyter-widgets/base",
+ "model_name": "LayoutModel",
+ "state": {
+ "_view_name": "LayoutView",
+ "grid_template_rows": null,
+ "right": null,
+ "justify_content": null,
+ "_view_module": "@jupyter-widgets/base",
+ "overflow": null,
+ "_model_module_version": "1.2.0",
+ "_view_count": null,
+ "flex_flow": null,
+ "width": null,
+ "min_width": null,
+ "border": null,
+ "align_items": null,
+ "bottom": null,
+ "_model_module": "@jupyter-widgets/base",
+ "top": null,
+ "grid_column": null,
+ "overflow_y": null,
+ "overflow_x": null,
+ "grid_auto_flow": null,
+ "grid_area": null,
+ "grid_template_columns": null,
+ "flex": null,
+ "_model_name": "LayoutModel",
+ "justify_items": null,
+ "grid_row": null,
+ "max_height": null,
+ "align_content": null,
+ "visibility": null,
+ "align_self": null,
+ "height": null,
+ "min_height": null,
+ "padding": null,
+ "grid_auto_rows": null,
+ "grid_gap": null,
+ "max_width": null,
+ "order": null,
+ "_view_module_version": "1.2.0",
+ "grid_template_areas": null,
+ "object_position": null,
+ "object_fit": null,
+ "grid_auto_columns": null,
+ "margin": null,
+ "display": null,
+ "left": null
+ }
+ }
+ }
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Xi-TdaMuyRrm"
+ },
+ "source": [
+ "import numpy as np\n",
+ "import random\n",
+ "\n",
+ "import torchvision.transforms as transforms\n",
+ "from torch.utils.data import DataLoader\n",
+ "from torchvision import datasets\n",
+ "from torch.autograd import Variable\n",
+ "\n",
+ "import torch.nn as nn\n",
+ "import torch.nn.functional as F\n",
+ "import torch\n",
+ "\n",
+ "import matplotlib.pyplot as plt"
+ ],
+ "execution_count": 1,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Pl4ugfeGymyZ",
+ "outputId": "2524499d-ade7-458b-d599-13e569b285ea",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 808,
+ "referenced_widgets": [
+ "7852865bf1c347debef9e09770ab1130",
+ "c4d91d6707e4414784b6bba22c604ec9",
+ "97799fa5b652408684e659116b875a73",
+ "1b563eda8ea140e885ed5dd0e7928ab2",
+ "262401a52a6447669dc72856ad1463ff",
+ "78e03c92e78b44b9998f50cd62ebc4cd",
+ "4fe1ab86f34f421d912ab3ba7fb6ca9c",
+ "b13b88b0f1b9498881dd2c0f36fc3052",
+ "8f77425bd2d3422aa86a6104f21d57a5",
+ "41888726d40b40a68ae98c174cf7eda0",
+ "8463317a408e41708e17702ef1f2c8df",
+ "69284303eb4d43f2be4c17a84f694d68",
+ "b8018a87a5144750af0bee0b0262f4f1",
+ "1c5d42cc6c334c7687e9f3ae2fdcb61f",
+ "77277c0fbfbd42ceb3fcab8934bad29a",
+ "f33701338c3f420a985af78bc99e1b26",
+ "33782ea5d5be4084a9c0d2128fdcd9c9",
+ "1cb4651f7f58413b8b14640e8eab53c3",
+ "d319ddd23e5b4b7ab0b39732245d9dd8",
+ "7a33dbd0855b4307becfe2033ac9263e",
+ "1c28a2e0529848858db8f5e87c06fdd5",
+ "842a2820f60d4a9280a0a978ca56a706",
+ "d251d2b92134444d853c3bc8309d6288",
+ "4f75b7bf77c841868384d733234fadef",
+ "1818af2ea04444378c71ca23130c9bd2",
+ "f2c4924e07a448d0b993b8b924aaa62a",
+ "2f45f5df3a2b4244877927031aff2b05",
+ "7388289568f041a2861c1858dfb90abb",
+ "e96eb472c67c4f7f8cabef30d30240e3",
+ "a0e92cab73db4dc6916c8a048eb83be1",
+ "e7c31a095d0b4fe5b762bff439bdcc93",
+ "f9b833376de04208a2af95dbebb33285"
+ ]
+ }
+ },
+ "source": [
+ "# Image processing\n",
+ "transform = transforms.ToTensor()\n",
+ "\n",
+ "# MNIST dataset\n",
+ "mnist = datasets.MNIST(root='../data/',\n",
+ " train=True,\n",
+ " transform=transform,\n",
+ " download=True,)\n",
+ "\n",
+ "# Data loader\n",
+ "dataloader = DataLoader(dataset=mnist,\n",
+ " batch_size=32, \n",
+ " shuffle=True)"
+ ],
+ "execution_count": 2,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n",
+ "Failed to download (trying next):\n",
+ "HTTP Error 503: Service Unavailable\n",
+ "\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz to ../data/MNIST/raw/train-images-idx3-ubyte.gz\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "7852865bf1c347debef9e09770ab1130",
+ "version_minor": 0,
+ "version_major": 2
+ },
+ "text/plain": [
+ "HBox(children=(FloatProgress(value=0.0, max=9912422.0), HTML(value='')))"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Extracting ../data/MNIST/raw/train-images-idx3-ubyte.gz to ../data/MNIST/raw\n",
+ "\n",
+ "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n",
+ "Failed to download (trying next):\n",
+ "HTTP Error 503: Service Unavailable\n",
+ "\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz to ../data/MNIST/raw/train-labels-idx1-ubyte.gz\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "8f77425bd2d3422aa86a6104f21d57a5",
+ "version_minor": 0,
+ "version_major": 2
+ },
+ "text/plain": [
+ "HBox(children=(FloatProgress(value=0.0, max=28881.0), HTML(value='')))"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Extracting ../data/MNIST/raw/train-labels-idx1-ubyte.gz to ../data/MNIST/raw\n",
+ "\n",
+ "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n",
+ "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz to ../data/MNIST/raw/t10k-images-idx3-ubyte.gz\n",
+ "Failed to download (trying next):\n",
+ "HTTP Error 503: Service Unavailable\n",
+ "\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz\n",
+ "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz to ../data/MNIST/raw/t10k-images-idx3-ubyte.gz\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "33782ea5d5be4084a9c0d2128fdcd9c9",
+ "version_minor": 0,
+ "version_major": 2
+ },
+ "text/plain": [
+ "HBox(children=(FloatProgress(value=0.0, max=1648877.0), HTML(value='')))"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Extracting ../data/MNIST/raw/t10k-images-idx3-ubyte.gz to ../data/MNIST/raw\n",
+ "\n",
+ "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n",
+ "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ../data/MNIST/raw/t10k-labels-idx1-ubyte.gz\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "1818af2ea04444378c71ca23130c9bd2",
+ "version_minor": 0,
+ "version_major": 2
+ },
+ "text/plain": [
+ "HBox(children=(FloatProgress(value=0.0, max=4542.0), HTML(value='')))"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ }
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Extracting ../data/MNIST/raw/t10k-labels-idx1-ubyte.gz to ../data/MNIST/raw\n",
+ "\n",
+ "Processing...\n",
+ "Done!\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "/usr/local/lib/python3.7/dist-packages/torchvision/datasets/mnist.py:502: UserWarning: The given NumPy array is not writeable, and PyTorch does not support non-writeable tensors. This means you can write to the underlying (supposedly non-writeable) NumPy array using the tensor. You may want to copy the array to protect its data or make it writeable before converting it to a tensor. This type of warning will be suppressed for the rest of this program. (Triggered internally at /pytorch/torch/csrc/utils/tensor_numpy.cpp:143.)\n",
+ " return torch.from_numpy(parsed.astype(m[2], copy=False)).view(*s)\n"
+ ],
+ "name": "stderr"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "oXh5tGrQ3W3n"
+ },
+ "source": [
+ "img_shape = (1, 28, 28)\n",
+ "latent_dim = 100\n",
+ "\n",
+ "num_classes = 10"
+ ],
+ "execution_count": 3,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "eBkFRSMeyuLW"
+ },
+ "source": [
+ "class Generator(nn.Module):\n",
+ " def __init__(self):\n",
+ " super(Generator, self).__init__()\n",
+ "\n",
+ " self.label_emb = nn.Embedding(num_classes, num_classes)\n",
+ "\n",
+ " self.model = nn.Sequential(\n",
+ " nn.Linear(latent_dim + num_classes, 128),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(128, 256),\n",
+ " nn.BatchNorm1d(256),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(256, 512),\n",
+ " nn.BatchNorm1d(512),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(512, 1024),\n",
+ " nn.BatchNorm1d(1024),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(1024, int(np.prod(img_shape))),\n",
+ " nn.Tanh()\n",
+ " )\n",
+ "\n",
+ " def forward(self, z, labels):\n",
+ " z = torch.cat((self.label_emb(labels), z), -1)\n",
+ "\n",
+ " img = self.model(z)\n",
+ " img = img.view(img.size(0), *img_shape)\n",
+ " return img"
+ ],
+ "execution_count": 26,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xQmBl3JHz_3J"
+ },
+ "source": [
+ "class Discriminator(nn.Module):\n",
+ " def __init__(self):\n",
+ " super(Discriminator, self).__init__()\n",
+ "\n",
+ " self.label_emb = nn.Embedding(num_classes, num_classes)\n",
+ "\n",
+ " self.model = nn.Sequential(\n",
+ " nn.Linear(int(np.prod(img_shape)) + num_classes, 512),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(512, 256),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(256, 128),\n",
+ " nn.LeakyReLU(0.2, True),\n",
+ "\n",
+ " nn.Linear(128, 1),\n",
+ " nn.Sigmoid()\n",
+ " )\n",
+ "\n",
+ " def forward(self, img, labels):\n",
+ " img_flat = img.view(img.size(0), -1)\n",
+ " data_in = torch.cat((self.label_emb(labels), img_flat), -1)\n",
+ " validity = self.model(data_in)\n",
+ "\n",
+ " return validity"
+ ],
+ "execution_count": 27,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "dCzmMX4Etdbr"
+ },
+ "source": [
+ "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")"
+ ],
+ "execution_count": 28,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "LcrCOUZj0Bwv"
+ },
+ "source": [
+ "# Loss function\n",
+ "adversarial_loss = torch.nn.BCELoss()\n",
+ "\n",
+ "# Initialize generator and discriminator\n",
+ "generator = Generator().to(device)\n",
+ "discriminator = Discriminator().to(device)\n",
+ "\n",
+ "# Optimizers\n",
+ "optimizer_G = torch.optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))\n",
+ "optimizer_D = torch.optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))\n",
+ "\n",
+ "# Epoch\n",
+ "num_epoch = 20"
+ ],
+ "execution_count": 29,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "1Sw2cMFj3nCa"
+ },
+ "source": [
+ "d_loss_arr = []\n",
+ "g_loss_arr = []\n",
+ "\n",
+ "for epoch in range(num_epoch):\n",
+ " for i, (imgs, labels) in enumerate(dataloader):\n",
+ "\n",
+ " # Adversarial ground truths\n",
+ " valid = Variable(torch.FloatTensor(imgs.size(0), 1).fill_(0.9), requires_grad=False).to(device)\n",
+ " fake = Variable(torch.FloatTensor(imgs.size(0), 1).fill_(0.0), requires_grad=False).to(device)\n",
+ "\n",
+ " # Configure input\n",
+ " real_imgs = Variable(imgs.type(torch.FloatTensor)).to(device)\n",
+ " labels = labels.to(device)\n",
+ "\n",
+ " # Train Generator\n",
+ " optimizer_G.zero_grad()\n",
+ "\n",
+ " # Sample noise as generator input\n",
+ " z = Variable(torch.FloatTensor(np.random.normal(0, 1, (imgs.shape[0], latent_dim)))).to(device)\n",
+ " gen_labels = Variable(torch.LongTensor(np.random.randint(0, num_classes, imgs.shape[0]))).to(device)\n",
+ "\n",
+ " # Generate a batch of images\n",
+ " gen_imgs = generator(z, gen_labels)\n",
+ "\n",
+ " # Loss measures generator's ability to fool the discriminator\n",
+ " g_loss = adversarial_loss(discriminator(gen_imgs, gen_labels), valid)\n",
+ "\n",
+ " g_loss.backward()\n",
+ " optimizer_G.step()\n",
+ "\n",
+ " # Train Discriminator\n",
+ " optimizer_D.zero_grad()\n",
+ "\n",
+ " # Measure discriminator's ability to classify real from generated samples\n",
+ " real_loss = adversarial_loss(discriminator(real_imgs, labels), valid)\n",
+ " fake_loss = adversarial_loss(discriminator(gen_imgs.detach(), gen_labels), fake)\n",
+ " d_loss = (real_loss + fake_loss) / 2\n",
+ "\n",
+ " d_loss.backward()\n",
+ " optimizer_D.step()\n",
+ "\n",
+ " # Save loss\n",
+ " d_loss_arr.append(d_loss.item())\n",
+ " g_loss_arr.append(g_loss.item())"
+ ],
+ "execution_count": 30,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "ckHzupyoHbPx",
+ "outputId": "7d98c6e9-df0b-47e8-f7bf-4a6dc6bfb307",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 265
+ }
+ },
+ "source": [
+ "# Plot loss of Generator and Discriminator\n",
+ "\n",
+ "plt.plot(d_loss_arr, label=\"D loss\")\n",
+ "plt.plot(g_loss_arr, label=\"G loss\")\n",
+ "\n",
+ "plt.legend()\n",
+ "plt.show()"
+ ],
+ "execution_count": 31,
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ "