├── 0_Deep_Learning's_Hello_World.ipynb
├── 10_RNN_Network.ipynb
├── 11_Text_Classification.ipynb
├── 12_Machine_Translation_From_Scratch_Part_1.ipynb
├── 13_Machine_Translation_From_Scratch_Part_2.ipynb
├── 14_Vanilla_GAN.ipynb
├── 15_DCGAN.ipynb
├── 16_Conditional_DCGAN.ipynb
├── 17_Pix2Pix_GAN.ipynb
├── 18_Cycle_GAN.ipynb
├── 19_Arbitrary_Style_Transfer_(AdaIN).ipynb
├── 1_Fashion_MNIST_and_CIFAR10.ipynb
├── 20_VAE.ipynb
├── 21_Diffusion_Model.ipynb
├── 22_Open_Source_NLU_models.ipynb
├── 23_Value_functions_and_policy_iteration.ipynb
├── 24_Double_Deep_Q_Learning_1_gym_intro.ipynb
├── 25_Double_Deep_Q_Learning_2.ipynb
├── 2_horse_or_human_workshop.ipynb
├── 3_VGG16_keras_applicarions.ipynb
├── 4_Residual_Networks.ipynb
├── 5_Pytorch_Introdution.ipynb
├── 6_CIFAR10_pytorch.ipynb
├── 7_Neural_Style_Transfer_.ipynb
├── 8_Siamese_Networks.ipynb
├── 9_Unet_and_Segmentation.ipynb
└── README.md
/13_Machine_Translation_From_Scratch_Part_2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "authorship_tag": "ABX9TyMMzEZjTDTJxfI3u0MIefDO",
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | "
"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 35,
32 | "metadata": {
33 | "id": "cezeGfesoylg"
34 | },
35 | "outputs": [],
36 | "source": [
37 | "import torch\n",
38 | "import torch.nn as nn\n",
39 | "import torch.nn.functional as F\n",
40 | "import torch.optim as optim"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "source": [
46 | "DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'"
47 | ],
48 | "metadata": {
49 | "id": "RCpeVTNlvgxg"
50 | },
51 | "execution_count": 36,
52 | "outputs": []
53 | },
54 | {
55 | "cell_type": "code",
56 | "source": [
57 | "class Encoder(nn.Module):\n",
58 | " def __init__(self, num_tokens, embedding_dim, latent_dim):\n",
59 | " super().__init__()\n",
60 | "\n",
61 | " self.embedding = nn.Embedding(num_embeddings=num_tokens, embedding_dim=embedding_dim)\n",
62 | " self.rnn = nn.GRU(input_size=embedding_dim, hidden_size=latent_dim, num_layers=1, batch_first=True, bidirectional=True)\n",
63 | "\n",
64 | " self.latent_dim = latent_dim\n",
65 | "\n",
66 | " def forward(self, x):\n",
67 | " x = self.embedding(x)\n",
68 | " batch_size, _, _ = x.size()\n",
69 | " h_0 = torch.zeros(2, batch_size, self.latent_dim).to(DEVICE)\n",
70 | " outputs, context_vector = self.rnn(x, h_0)\n",
71 | "\n",
72 | " return context_vector, outputs"
73 | ],
74 | "metadata": {
75 | "id": "l6drzN3TvYEP"
76 | },
77 | "execution_count": 37,
78 | "outputs": []
79 | },
80 | {
81 | "cell_type": "code",
82 | "source": [
83 | "encoder = Encoder(num_tokens=100, embedding_dim=16, latent_dim=64).to(DEVICE)"
84 | ],
85 | "metadata": {
86 | "id": "uEfD71WEvcs0"
87 | },
88 | "execution_count": 38,
89 | "outputs": []
90 | },
91 | {
92 | "cell_type": "code",
93 | "source": [
94 | "batch_size = 10\n",
95 | "seq_length = 30\n",
96 | "\n",
97 | "test_input = torch.zeros(batch_size, seq_length, dtype=torch.int64)\n",
98 | "test_output, _ = encoder(test_input)\n",
99 | "\n",
100 | "test_output.shape"
101 | ],
102 | "metadata": {
103 | "colab": {
104 | "base_uri": "https://localhost:8080/"
105 | },
106 | "id": "nKKSzpd_voel",
107 | "outputId": "ed6adfc9-9c52-4b02-a511-8fff8f3988de"
108 | },
109 | "execution_count": 39,
110 | "outputs": [
111 | {
112 | "output_type": "execute_result",
113 | "data": {
114 | "text/plain": [
115 | "torch.Size([2, 10, 64])"
116 | ]
117 | },
118 | "metadata": {},
119 | "execution_count": 39
120 | }
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "source": [
126 | "class AttentionBlock(nn.Module):\n",
127 | " def __init__(self, hidden_dim):\n",
128 | " super().__init__()\n",
129 | " self.W = nn.Linear(hidden_dim, hidden_dim, bias=False)\n",
130 | " self.U = nn.Linear(hidden_dim, hidden_dim, bias=False)\n",
131 | " self.V = nn.Linear(hidden_dim, 1, bias=False)\n",
132 | "\n",
133 | " def forward(self, query, keys):\n",
134 | " QK = self.W(query).unsqueeze(1) + self.U(keys)\n",
135 | " QK = torch.tanh(QK)\n",
136 | " scores = self.V(QK)\n",
137 | "\n",
138 | " scores = scores.squeeze(2).unsqueeze(1)\n",
139 | " weigths = F.softmax(scores, dim=-1)\n",
140 | "\n",
141 | " context = torch.bmm(weigths, keys)\n",
142 | "\n",
143 | " return context, weigths"
144 | ],
145 | "metadata": {
146 | "id": "QoAL81lzwBtT"
147 | },
148 | "execution_count": 40,
149 | "outputs": []
150 | },
151 | {
152 | "cell_type": "code",
153 | "source": [
154 | "class AttentionGRU(nn.Module):\n",
155 | " def __init__(self, input_size, latent_dim):\n",
156 | " super().__init__()\n",
157 | " self.attention = AttentionBlock(2 * latent_dim)\n",
158 | " self.rnn = nn.GRU(input_size=input_size, hidden_size=2 * latent_dim)\n",
159 | " self.latent_dim = latent_dim\n",
160 | "\n",
161 | " def forward(self, predicted_label, encoder_outputs):\n",
162 | " batch_size, _, _ = predicted_label.size()\n",
163 | " h = torch.zeros(batch_size, 2 * self.latent_dim)\n",
164 | " predicted_label = predicted_label.permute(1, 0, 2)\n",
165 | " for token in predicted_label:\n",
166 | " context, weights = self.attention(h, encoder_outputs)\n",
167 | " context = context.permute(1, 0, 2)\n",
168 | " token = token.unsqueeze(1).permute(1, 0, 2)\n",
169 | " output, h = self.rnn(token, context)\n",
170 | " h = h.squeeze()\n",
171 | "\n",
172 | " return output, h"
173 | ],
174 | "metadata": {
175 | "id": "FHt-pZmz40N1"
176 | },
177 | "execution_count": 41,
178 | "outputs": []
179 | },
180 | {
181 | "cell_type": "code",
182 | "source": [
183 | "class Decoder(nn.Module):\n",
184 | " def __init__(self, num_tokens, embedding_dim, latent_dim):\n",
185 | " super().__init__()\n",
186 | "\n",
187 | " self.embedding = nn.Embedding(num_embeddings=num_tokens, embedding_dim=embedding_dim)\n",
188 | " self.rnn = AttentionGRU(embedding_dim, latent_dim)\n",
189 | " self.fc = nn.Linear(in_features=2 * latent_dim, out_features=num_tokens)\n",
190 | " self.softmax = nn.LogSoftmax(dim=1)\n",
191 | "\n",
192 | " def forward(self, encoder_outputs, predicted_label):\n",
193 | " x = self.embedding(predicted_label)\n",
194 | " x, _ = self.rnn(x, encoder_outputs)\n",
195 | " x = self.fc(x)\n",
196 | " x = self.softmax(x)\n",
197 | "\n",
198 | " return x"
199 | ],
200 | "metadata": {
201 | "id": "nfrRgkJF62bE"
202 | },
203 | "execution_count": 42,
204 | "outputs": []
205 | },
206 | {
207 | "cell_type": "code",
208 | "source": [
209 | "encoder = Encoder(num_tokens=100, embedding_dim=8, latent_dim=16)\n",
210 | "decoder = Decoder(num_tokens=100, embedding_dim=8, latent_dim=16)"
211 | ],
212 | "metadata": {
213 | "id": "lrVicVYv7LBr"
214 | },
215 | "execution_count": 43,
216 | "outputs": []
217 | },
218 | {
219 | "cell_type": "code",
220 | "source": [
221 | "batch_size = 50\n",
222 | "seq_length = 20\n",
223 | "predicted_labels_count = 10\n",
224 | "test_input = torch.zeros(batch_size, seq_length, dtype=torch.int64)\n",
225 | "predicted_labels = torch.zeros(batch_size, predicted_labels_count, dtype=torch.int64)\n",
226 | "\n",
227 | "_, encoder_output = encoder(test_input)\n",
228 | "new_token = decoder(encoder_output, predicted_labels)\n",
229 | "new_token.size()"
230 | ],
231 | "metadata": {
232 | "colab": {
233 | "base_uri": "https://localhost:8080/"
234 | },
235 | "id": "L-glyCsm7T29",
236 | "outputId": "4e784ab3-7cef-4924-ecb7-3d0ee3b7b8e5"
237 | },
238 | "execution_count": 44,
239 | "outputs": [
240 | {
241 | "output_type": "execute_result",
242 | "data": {
243 | "text/plain": [
244 | "torch.Size([1, 50, 100])"
245 | ]
246 | },
247 | "metadata": {},
248 | "execution_count": 44
249 | }
250 | ]
251 | },
252 | {
253 | "cell_type": "code",
254 | "source": [],
255 | "metadata": {
256 | "id": "ncvEzVsD79Zh"
257 | },
258 | "execution_count": 44,
259 | "outputs": []
260 | }
261 | ]
262 | }
--------------------------------------------------------------------------------
/21_Diffusion_Model.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "gpuType": "T4",
8 | "authorship_tag": "ABX9TyPp+28MPcewUc/8K+ah+M4u",
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | },
15 | "language_info": {
16 | "name": "python"
17 | },
18 | "accelerator": "GPU",
19 | "widgets": {
20 | "application/vnd.jupyter.widget-state+json": {
21 | "b0fa66fc56e34465bb2a59f9ce916b71": {
22 | "model_module": "@jupyter-widgets/controls",
23 | "model_name": "HBoxModel",
24 | "model_module_version": "1.5.0",
25 | "state": {
26 | "_dom_classes": [],
27 | "_model_module": "@jupyter-widgets/controls",
28 | "_model_module_version": "1.5.0",
29 | "_model_name": "HBoxModel",
30 | "_view_count": null,
31 | "_view_module": "@jupyter-widgets/controls",
32 | "_view_module_version": "1.5.0",
33 | "_view_name": "HBoxView",
34 | "box_style": "",
35 | "children": [
36 | "IPY_MODEL_14019560a279458cb775634b162b2407",
37 | "IPY_MODEL_4db4b93e47bd4c859b1d6685ed8cf76e",
38 | "IPY_MODEL_2ef34af8de2c4c7eab85fd3c83a5e1c5"
39 | ],
40 | "layout": "IPY_MODEL_1638fe599f2c409c8d75396bbad174b7"
41 | }
42 | },
43 | "14019560a279458cb775634b162b2407": {
44 | "model_module": "@jupyter-widgets/controls",
45 | "model_name": "HTMLModel",
46 | "model_module_version": "1.5.0",
47 | "state": {
48 | "_dom_classes": [],
49 | "_model_module": "@jupyter-widgets/controls",
50 | "_model_module_version": "1.5.0",
51 | "_model_name": "HTMLModel",
52 | "_view_count": null,
53 | "_view_module": "@jupyter-widgets/controls",
54 | "_view_module_version": "1.5.0",
55 | "_view_name": "HTMLView",
56 | "description": "",
57 | "description_tooltip": null,
58 | "layout": "IPY_MODEL_0a2010f11ba345a385997b328168127a",
59 | "placeholder": "",
60 | "style": "IPY_MODEL_5a39152a73cb4a87bd5bdf6f5a6888cc",
61 | "value": "100%"
62 | }
63 | },
64 | "4db4b93e47bd4c859b1d6685ed8cf76e": {
65 | "model_module": "@jupyter-widgets/controls",
66 | "model_name": "FloatProgressModel",
67 | "model_module_version": "1.5.0",
68 | "state": {
69 | "_dom_classes": [],
70 | "_model_module": "@jupyter-widgets/controls",
71 | "_model_module_version": "1.5.0",
72 | "_model_name": "FloatProgressModel",
73 | "_view_count": null,
74 | "_view_module": "@jupyter-widgets/controls",
75 | "_view_module_version": "1.5.0",
76 | "_view_name": "ProgressView",
77 | "bar_style": "success",
78 | "description": "",
79 | "description_tooltip": null,
80 | "layout": "IPY_MODEL_b72fab00156243478d0619f3f8a56a1a",
81 | "max": 938,
82 | "min": 0,
83 | "orientation": "horizontal",
84 | "style": "IPY_MODEL_38548a20e7744f098a9118b82ff13f95",
85 | "value": 938
86 | }
87 | },
88 | "2ef34af8de2c4c7eab85fd3c83a5e1c5": {
89 | "model_module": "@jupyter-widgets/controls",
90 | "model_name": "HTMLModel",
91 | "model_module_version": "1.5.0",
92 | "state": {
93 | "_dom_classes": [],
94 | "_model_module": "@jupyter-widgets/controls",
95 | "_model_module_version": "1.5.0",
96 | "_model_name": "HTMLModel",
97 | "_view_count": null,
98 | "_view_module": "@jupyter-widgets/controls",
99 | "_view_module_version": "1.5.0",
100 | "_view_name": "HTMLView",
101 | "description": "",
102 | "description_tooltip": null,
103 | "layout": "IPY_MODEL_47d16d89d79543ab8b893ccae490d2f0",
104 | "placeholder": "",
105 | "style": "IPY_MODEL_05f22484b66641818d3288792ead2efa",
106 | "value": " 938/938 [03:40<00:00, 4.89it/s]"
107 | }
108 | },
109 | "1638fe599f2c409c8d75396bbad174b7": {
110 | "model_module": "@jupyter-widgets/base",
111 | "model_name": "LayoutModel",
112 | "model_module_version": "1.2.0",
113 | "state": {
114 | "_model_module": "@jupyter-widgets/base",
115 | "_model_module_version": "1.2.0",
116 | "_model_name": "LayoutModel",
117 | "_view_count": null,
118 | "_view_module": "@jupyter-widgets/base",
119 | "_view_module_version": "1.2.0",
120 | "_view_name": "LayoutView",
121 | "align_content": null,
122 | "align_items": null,
123 | "align_self": null,
124 | "border": null,
125 | "bottom": null,
126 | "display": null,
127 | "flex": null,
128 | "flex_flow": null,
129 | "grid_area": null,
130 | "grid_auto_columns": null,
131 | "grid_auto_flow": null,
132 | "grid_auto_rows": null,
133 | "grid_column": null,
134 | "grid_gap": null,
135 | "grid_row": null,
136 | "grid_template_areas": null,
137 | "grid_template_columns": null,
138 | "grid_template_rows": null,
139 | "height": null,
140 | "justify_content": null,
141 | "justify_items": null,
142 | "left": null,
143 | "margin": null,
144 | "max_height": null,
145 | "max_width": null,
146 | "min_height": null,
147 | "min_width": null,
148 | "object_fit": null,
149 | "object_position": null,
150 | "order": null,
151 | "overflow": null,
152 | "overflow_x": null,
153 | "overflow_y": null,
154 | "padding": null,
155 | "right": null,
156 | "top": null,
157 | "visibility": null,
158 | "width": null
159 | }
160 | },
161 | "0a2010f11ba345a385997b328168127a": {
162 | "model_module": "@jupyter-widgets/base",
163 | "model_name": "LayoutModel",
164 | "model_module_version": "1.2.0",
165 | "state": {
166 | "_model_module": "@jupyter-widgets/base",
167 | "_model_module_version": "1.2.0",
168 | "_model_name": "LayoutModel",
169 | "_view_count": null,
170 | "_view_module": "@jupyter-widgets/base",
171 | "_view_module_version": "1.2.0",
172 | "_view_name": "LayoutView",
173 | "align_content": null,
174 | "align_items": null,
175 | "align_self": null,
176 | "border": null,
177 | "bottom": null,
178 | "display": null,
179 | "flex": null,
180 | "flex_flow": null,
181 | "grid_area": null,
182 | "grid_auto_columns": null,
183 | "grid_auto_flow": null,
184 | "grid_auto_rows": null,
185 | "grid_column": null,
186 | "grid_gap": null,
187 | "grid_row": null,
188 | "grid_template_areas": null,
189 | "grid_template_columns": null,
190 | "grid_template_rows": null,
191 | "height": null,
192 | "justify_content": null,
193 | "justify_items": null,
194 | "left": null,
195 | "margin": null,
196 | "max_height": null,
197 | "max_width": null,
198 | "min_height": null,
199 | "min_width": null,
200 | "object_fit": null,
201 | "object_position": null,
202 | "order": null,
203 | "overflow": null,
204 | "overflow_x": null,
205 | "overflow_y": null,
206 | "padding": null,
207 | "right": null,
208 | "top": null,
209 | "visibility": null,
210 | "width": null
211 | }
212 | },
213 | "5a39152a73cb4a87bd5bdf6f5a6888cc": {
214 | "model_module": "@jupyter-widgets/controls",
215 | "model_name": "DescriptionStyleModel",
216 | "model_module_version": "1.5.0",
217 | "state": {
218 | "_model_module": "@jupyter-widgets/controls",
219 | "_model_module_version": "1.5.0",
220 | "_model_name": "DescriptionStyleModel",
221 | "_view_count": null,
222 | "_view_module": "@jupyter-widgets/base",
223 | "_view_module_version": "1.2.0",
224 | "_view_name": "StyleView",
225 | "description_width": ""
226 | }
227 | },
228 | "b72fab00156243478d0619f3f8a56a1a": {
229 | "model_module": "@jupyter-widgets/base",
230 | "model_name": "LayoutModel",
231 | "model_module_version": "1.2.0",
232 | "state": {
233 | "_model_module": "@jupyter-widgets/base",
234 | "_model_module_version": "1.2.0",
235 | "_model_name": "LayoutModel",
236 | "_view_count": null,
237 | "_view_module": "@jupyter-widgets/base",
238 | "_view_module_version": "1.2.0",
239 | "_view_name": "LayoutView",
240 | "align_content": null,
241 | "align_items": null,
242 | "align_self": null,
243 | "border": null,
244 | "bottom": null,
245 | "display": null,
246 | "flex": null,
247 | "flex_flow": null,
248 | "grid_area": null,
249 | "grid_auto_columns": null,
250 | "grid_auto_flow": null,
251 | "grid_auto_rows": null,
252 | "grid_column": null,
253 | "grid_gap": null,
254 | "grid_row": null,
255 | "grid_template_areas": null,
256 | "grid_template_columns": null,
257 | "grid_template_rows": null,
258 | "height": null,
259 | "justify_content": null,
260 | "justify_items": null,
261 | "left": null,
262 | "margin": null,
263 | "max_height": null,
264 | "max_width": null,
265 | "min_height": null,
266 | "min_width": null,
267 | "object_fit": null,
268 | "object_position": null,
269 | "order": null,
270 | "overflow": null,
271 | "overflow_x": null,
272 | "overflow_y": null,
273 | "padding": null,
274 | "right": null,
275 | "top": null,
276 | "visibility": null,
277 | "width": null
278 | }
279 | },
280 | "38548a20e7744f098a9118b82ff13f95": {
281 | "model_module": "@jupyter-widgets/controls",
282 | "model_name": "ProgressStyleModel",
283 | "model_module_version": "1.5.0",
284 | "state": {
285 | "_model_module": "@jupyter-widgets/controls",
286 | "_model_module_version": "1.5.0",
287 | "_model_name": "ProgressStyleModel",
288 | "_view_count": null,
289 | "_view_module": "@jupyter-widgets/base",
290 | "_view_module_version": "1.2.0",
291 | "_view_name": "StyleView",
292 | "bar_color": null,
293 | "description_width": ""
294 | }
295 | },
296 | "47d16d89d79543ab8b893ccae490d2f0": {
297 | "model_module": "@jupyter-widgets/base",
298 | "model_name": "LayoutModel",
299 | "model_module_version": "1.2.0",
300 | "state": {
301 | "_model_module": "@jupyter-widgets/base",
302 | "_model_module_version": "1.2.0",
303 | "_model_name": "LayoutModel",
304 | "_view_count": null,
305 | "_view_module": "@jupyter-widgets/base",
306 | "_view_module_version": "1.2.0",
307 | "_view_name": "LayoutView",
308 | "align_content": null,
309 | "align_items": null,
310 | "align_self": null,
311 | "border": null,
312 | "bottom": null,
313 | "display": null,
314 | "flex": null,
315 | "flex_flow": null,
316 | "grid_area": null,
317 | "grid_auto_columns": null,
318 | "grid_auto_flow": null,
319 | "grid_auto_rows": null,
320 | "grid_column": null,
321 | "grid_gap": null,
322 | "grid_row": null,
323 | "grid_template_areas": null,
324 | "grid_template_columns": null,
325 | "grid_template_rows": null,
326 | "height": null,
327 | "justify_content": null,
328 | "justify_items": null,
329 | "left": null,
330 | "margin": null,
331 | "max_height": null,
332 | "max_width": null,
333 | "min_height": null,
334 | "min_width": null,
335 | "object_fit": null,
336 | "object_position": null,
337 | "order": null,
338 | "overflow": null,
339 | "overflow_x": null,
340 | "overflow_y": null,
341 | "padding": null,
342 | "right": null,
343 | "top": null,
344 | "visibility": null,
345 | "width": null
346 | }
347 | },
348 | "05f22484b66641818d3288792ead2efa": {
349 | "model_module": "@jupyter-widgets/controls",
350 | "model_name": "DescriptionStyleModel",
351 | "model_module_version": "1.5.0",
352 | "state": {
353 | "_model_module": "@jupyter-widgets/controls",
354 | "_model_module_version": "1.5.0",
355 | "_model_name": "DescriptionStyleModel",
356 | "_view_count": null,
357 | "_view_module": "@jupyter-widgets/base",
358 | "_view_module_version": "1.2.0",
359 | "_view_name": "StyleView",
360 | "description_width": ""
361 | }
362 | },
363 | "7c76076cccf04326a82ec69c5b33c9af": {
364 | "model_module": "@jupyter-widgets/controls",
365 | "model_name": "HBoxModel",
366 | "model_module_version": "1.5.0",
367 | "state": {
368 | "_dom_classes": [],
369 | "_model_module": "@jupyter-widgets/controls",
370 | "_model_module_version": "1.5.0",
371 | "_model_name": "HBoxModel",
372 | "_view_count": null,
373 | "_view_module": "@jupyter-widgets/controls",
374 | "_view_module_version": "1.5.0",
375 | "_view_name": "HBoxView",
376 | "box_style": "",
377 | "children": [
378 | "IPY_MODEL_326f80a6a9364bc4a37fd727649c5599",
379 | "IPY_MODEL_cd209532893744078f13583bc2765ef5",
380 | "IPY_MODEL_9933cef2fd0c44c2a308f24e5de0b1ea"
381 | ],
382 | "layout": "IPY_MODEL_9d07802c82da4382966ee2bc58bff4e2"
383 | }
384 | },
385 | "326f80a6a9364bc4a37fd727649c5599": {
386 | "model_module": "@jupyter-widgets/controls",
387 | "model_name": "HTMLModel",
388 | "model_module_version": "1.5.0",
389 | "state": {
390 | "_dom_classes": [],
391 | "_model_module": "@jupyter-widgets/controls",
392 | "_model_module_version": "1.5.0",
393 | "_model_name": "HTMLModel",
394 | "_view_count": null,
395 | "_view_module": "@jupyter-widgets/controls",
396 | "_view_module_version": "1.5.0",
397 | "_view_name": "HTMLView",
398 | "description": "",
399 | "description_tooltip": null,
400 | "layout": "IPY_MODEL_7c62a32ae5944b7584b0026533d3bea9",
401 | "placeholder": "",
402 | "style": "IPY_MODEL_7d6defe1998a4083bbf9f4fdb4e5d599",
403 | "value": "100%"
404 | }
405 | },
406 | "cd209532893744078f13583bc2765ef5": {
407 | "model_module": "@jupyter-widgets/controls",
408 | "model_name": "FloatProgressModel",
409 | "model_module_version": "1.5.0",
410 | "state": {
411 | "_dom_classes": [],
412 | "_model_module": "@jupyter-widgets/controls",
413 | "_model_module_version": "1.5.0",
414 | "_model_name": "FloatProgressModel",
415 | "_view_count": null,
416 | "_view_module": "@jupyter-widgets/controls",
417 | "_view_module_version": "1.5.0",
418 | "_view_name": "ProgressView",
419 | "bar_style": "success",
420 | "description": "",
421 | "description_tooltip": null,
422 | "layout": "IPY_MODEL_5a2ad31325dc45d0b795eb88daf147df",
423 | "max": 938,
424 | "min": 0,
425 | "orientation": "horizontal",
426 | "style": "IPY_MODEL_c981017d7c39426dbaf566505c817bf4",
427 | "value": 938
428 | }
429 | },
430 | "9933cef2fd0c44c2a308f24e5de0b1ea": {
431 | "model_module": "@jupyter-widgets/controls",
432 | "model_name": "HTMLModel",
433 | "model_module_version": "1.5.0",
434 | "state": {
435 | "_dom_classes": [],
436 | "_model_module": "@jupyter-widgets/controls",
437 | "_model_module_version": "1.5.0",
438 | "_model_name": "HTMLModel",
439 | "_view_count": null,
440 | "_view_module": "@jupyter-widgets/controls",
441 | "_view_module_version": "1.5.0",
442 | "_view_name": "HTMLView",
443 | "description": "",
444 | "description_tooltip": null,
445 | "layout": "IPY_MODEL_2ca3d70b283a4eaba7c683d03a53da07",
446 | "placeholder": "",
447 | "style": "IPY_MODEL_51922432c661481da1ebe8192367c4dd",
448 | "value": " 938/938 [03:39<00:00, 4.95it/s]"
449 | }
450 | },
451 | "9d07802c82da4382966ee2bc58bff4e2": {
452 | "model_module": "@jupyter-widgets/base",
453 | "model_name": "LayoutModel",
454 | "model_module_version": "1.2.0",
455 | "state": {
456 | "_model_module": "@jupyter-widgets/base",
457 | "_model_module_version": "1.2.0",
458 | "_model_name": "LayoutModel",
459 | "_view_count": null,
460 | "_view_module": "@jupyter-widgets/base",
461 | "_view_module_version": "1.2.0",
462 | "_view_name": "LayoutView",
463 | "align_content": null,
464 | "align_items": null,
465 | "align_self": null,
466 | "border": null,
467 | "bottom": null,
468 | "display": null,
469 | "flex": null,
470 | "flex_flow": null,
471 | "grid_area": null,
472 | "grid_auto_columns": null,
473 | "grid_auto_flow": null,
474 | "grid_auto_rows": null,
475 | "grid_column": null,
476 | "grid_gap": null,
477 | "grid_row": null,
478 | "grid_template_areas": null,
479 | "grid_template_columns": null,
480 | "grid_template_rows": null,
481 | "height": null,
482 | "justify_content": null,
483 | "justify_items": null,
484 | "left": null,
485 | "margin": null,
486 | "max_height": null,
487 | "max_width": null,
488 | "min_height": null,
489 | "min_width": null,
490 | "object_fit": null,
491 | "object_position": null,
492 | "order": null,
493 | "overflow": null,
494 | "overflow_x": null,
495 | "overflow_y": null,
496 | "padding": null,
497 | "right": null,
498 | "top": null,
499 | "visibility": null,
500 | "width": null
501 | }
502 | },
503 | "7c62a32ae5944b7584b0026533d3bea9": {
504 | "model_module": "@jupyter-widgets/base",
505 | "model_name": "LayoutModel",
506 | "model_module_version": "1.2.0",
507 | "state": {
508 | "_model_module": "@jupyter-widgets/base",
509 | "_model_module_version": "1.2.0",
510 | "_model_name": "LayoutModel",
511 | "_view_count": null,
512 | "_view_module": "@jupyter-widgets/base",
513 | "_view_module_version": "1.2.0",
514 | "_view_name": "LayoutView",
515 | "align_content": null,
516 | "align_items": null,
517 | "align_self": null,
518 | "border": null,
519 | "bottom": null,
520 | "display": null,
521 | "flex": null,
522 | "flex_flow": null,
523 | "grid_area": null,
524 | "grid_auto_columns": null,
525 | "grid_auto_flow": null,
526 | "grid_auto_rows": null,
527 | "grid_column": null,
528 | "grid_gap": null,
529 | "grid_row": null,
530 | "grid_template_areas": null,
531 | "grid_template_columns": null,
532 | "grid_template_rows": null,
533 | "height": null,
534 | "justify_content": null,
535 | "justify_items": null,
536 | "left": null,
537 | "margin": null,
538 | "max_height": null,
539 | "max_width": null,
540 | "min_height": null,
541 | "min_width": null,
542 | "object_fit": null,
543 | "object_position": null,
544 | "order": null,
545 | "overflow": null,
546 | "overflow_x": null,
547 | "overflow_y": null,
548 | "padding": null,
549 | "right": null,
550 | "top": null,
551 | "visibility": null,
552 | "width": null
553 | }
554 | },
555 | "7d6defe1998a4083bbf9f4fdb4e5d599": {
556 | "model_module": "@jupyter-widgets/controls",
557 | "model_name": "DescriptionStyleModel",
558 | "model_module_version": "1.5.0",
559 | "state": {
560 | "_model_module": "@jupyter-widgets/controls",
561 | "_model_module_version": "1.5.0",
562 | "_model_name": "DescriptionStyleModel",
563 | "_view_count": null,
564 | "_view_module": "@jupyter-widgets/base",
565 | "_view_module_version": "1.2.0",
566 | "_view_name": "StyleView",
567 | "description_width": ""
568 | }
569 | },
570 | "5a2ad31325dc45d0b795eb88daf147df": {
571 | "model_module": "@jupyter-widgets/base",
572 | "model_name": "LayoutModel",
573 | "model_module_version": "1.2.0",
574 | "state": {
575 | "_model_module": "@jupyter-widgets/base",
576 | "_model_module_version": "1.2.0",
577 | "_model_name": "LayoutModel",
578 | "_view_count": null,
579 | "_view_module": "@jupyter-widgets/base",
580 | "_view_module_version": "1.2.0",
581 | "_view_name": "LayoutView",
582 | "align_content": null,
583 | "align_items": null,
584 | "align_self": null,
585 | "border": null,
586 | "bottom": null,
587 | "display": null,
588 | "flex": null,
589 | "flex_flow": null,
590 | "grid_area": null,
591 | "grid_auto_columns": null,
592 | "grid_auto_flow": null,
593 | "grid_auto_rows": null,
594 | "grid_column": null,
595 | "grid_gap": null,
596 | "grid_row": null,
597 | "grid_template_areas": null,
598 | "grid_template_columns": null,
599 | "grid_template_rows": null,
600 | "height": null,
601 | "justify_content": null,
602 | "justify_items": null,
603 | "left": null,
604 | "margin": null,
605 | "max_height": null,
606 | "max_width": null,
607 | "min_height": null,
608 | "min_width": null,
609 | "object_fit": null,
610 | "object_position": null,
611 | "order": null,
612 | "overflow": null,
613 | "overflow_x": null,
614 | "overflow_y": null,
615 | "padding": null,
616 | "right": null,
617 | "top": null,
618 | "visibility": null,
619 | "width": null
620 | }
621 | },
622 | "c981017d7c39426dbaf566505c817bf4": {
623 | "model_module": "@jupyter-widgets/controls",
624 | "model_name": "ProgressStyleModel",
625 | "model_module_version": "1.5.0",
626 | "state": {
627 | "_model_module": "@jupyter-widgets/controls",
628 | "_model_module_version": "1.5.0",
629 | "_model_name": "ProgressStyleModel",
630 | "_view_count": null,
631 | "_view_module": "@jupyter-widgets/base",
632 | "_view_module_version": "1.2.0",
633 | "_view_name": "StyleView",
634 | "bar_color": null,
635 | "description_width": ""
636 | }
637 | },
638 | "2ca3d70b283a4eaba7c683d03a53da07": {
639 | "model_module": "@jupyter-widgets/base",
640 | "model_name": "LayoutModel",
641 | "model_module_version": "1.2.0",
642 | "state": {
643 | "_model_module": "@jupyter-widgets/base",
644 | "_model_module_version": "1.2.0",
645 | "_model_name": "LayoutModel",
646 | "_view_count": null,
647 | "_view_module": "@jupyter-widgets/base",
648 | "_view_module_version": "1.2.0",
649 | "_view_name": "LayoutView",
650 | "align_content": null,
651 | "align_items": null,
652 | "align_self": null,
653 | "border": null,
654 | "bottom": null,
655 | "display": null,
656 | "flex": null,
657 | "flex_flow": null,
658 | "grid_area": null,
659 | "grid_auto_columns": null,
660 | "grid_auto_flow": null,
661 | "grid_auto_rows": null,
662 | "grid_column": null,
663 | "grid_gap": null,
664 | "grid_row": null,
665 | "grid_template_areas": null,
666 | "grid_template_columns": null,
667 | "grid_template_rows": null,
668 | "height": null,
669 | "justify_content": null,
670 | "justify_items": null,
671 | "left": null,
672 | "margin": null,
673 | "max_height": null,
674 | "max_width": null,
675 | "min_height": null,
676 | "min_width": null,
677 | "object_fit": null,
678 | "object_position": null,
679 | "order": null,
680 | "overflow": null,
681 | "overflow_x": null,
682 | "overflow_y": null,
683 | "padding": null,
684 | "right": null,
685 | "top": null,
686 | "visibility": null,
687 | "width": null
688 | }
689 | },
690 | "51922432c661481da1ebe8192367c4dd": {
691 | "model_module": "@jupyter-widgets/controls",
692 | "model_name": "DescriptionStyleModel",
693 | "model_module_version": "1.5.0",
694 | "state": {
695 | "_model_module": "@jupyter-widgets/controls",
696 | "_model_module_version": "1.5.0",
697 | "_model_name": "DescriptionStyleModel",
698 | "_view_count": null,
699 | "_view_module": "@jupyter-widgets/base",
700 | "_view_module_version": "1.2.0",
701 | "_view_name": "StyleView",
702 | "description_width": ""
703 | }
704 | },
705 | "61d30891744b4dcda25e8eeb71b54aad": {
706 | "model_module": "@jupyter-widgets/controls",
707 | "model_name": "HBoxModel",
708 | "model_module_version": "1.5.0",
709 | "state": {
710 | "_dom_classes": [],
711 | "_model_module": "@jupyter-widgets/controls",
712 | "_model_module_version": "1.5.0",
713 | "_model_name": "HBoxModel",
714 | "_view_count": null,
715 | "_view_module": "@jupyter-widgets/controls",
716 | "_view_module_version": "1.5.0",
717 | "_view_name": "HBoxView",
718 | "box_style": "",
719 | "children": [
720 | "IPY_MODEL_718e38085b3b4f5eab8c481913bad4fb",
721 | "IPY_MODEL_3346c18e5aae424a9705689c62854830",
722 | "IPY_MODEL_1a782ba0602d4f7ebb0659295f7497f0"
723 | ],
724 | "layout": "IPY_MODEL_80ad93a8096a41f6ba7035bb483ee461"
725 | }
726 | },
727 | "718e38085b3b4f5eab8c481913bad4fb": {
728 | "model_module": "@jupyter-widgets/controls",
729 | "model_name": "HTMLModel",
730 | "model_module_version": "1.5.0",
731 | "state": {
732 | "_dom_classes": [],
733 | "_model_module": "@jupyter-widgets/controls",
734 | "_model_module_version": "1.5.0",
735 | "_model_name": "HTMLModel",
736 | "_view_count": null,
737 | "_view_module": "@jupyter-widgets/controls",
738 | "_view_module_version": "1.5.0",
739 | "_view_name": "HTMLView",
740 | "description": "",
741 | "description_tooltip": null,
742 | "layout": "IPY_MODEL_bf1b70fc39db4494aee42122b14a0c8a",
743 | "placeholder": "",
744 | "style": "IPY_MODEL_9cfbaf78195a4409aa3c751fef6377e1",
745 | "value": "100%"
746 | }
747 | },
748 | "3346c18e5aae424a9705689c62854830": {
749 | "model_module": "@jupyter-widgets/controls",
750 | "model_name": "FloatProgressModel",
751 | "model_module_version": "1.5.0",
752 | "state": {
753 | "_dom_classes": [],
754 | "_model_module": "@jupyter-widgets/controls",
755 | "_model_module_version": "1.5.0",
756 | "_model_name": "FloatProgressModel",
757 | "_view_count": null,
758 | "_view_module": "@jupyter-widgets/controls",
759 | "_view_module_version": "1.5.0",
760 | "_view_name": "ProgressView",
761 | "bar_style": "success",
762 | "description": "",
763 | "description_tooltip": null,
764 | "layout": "IPY_MODEL_c8379e3f85c74bb9889bf49229de82b3",
765 | "max": 938,
766 | "min": 0,
767 | "orientation": "horizontal",
768 | "style": "IPY_MODEL_75125bd2901045ffa9c9b7d3583ee94c",
769 | "value": 938
770 | }
771 | },
772 | "1a782ba0602d4f7ebb0659295f7497f0": {
773 | "model_module": "@jupyter-widgets/controls",
774 | "model_name": "HTMLModel",
775 | "model_module_version": "1.5.0",
776 | "state": {
777 | "_dom_classes": [],
778 | "_model_module": "@jupyter-widgets/controls",
779 | "_model_module_version": "1.5.0",
780 | "_model_name": "HTMLModel",
781 | "_view_count": null,
782 | "_view_module": "@jupyter-widgets/controls",
783 | "_view_module_version": "1.5.0",
784 | "_view_name": "HTMLView",
785 | "description": "",
786 | "description_tooltip": null,
787 | "layout": "IPY_MODEL_78a5fa8234ac4ff182f882908461559a",
788 | "placeholder": "",
789 | "style": "IPY_MODEL_28abc7c5f1914aa0a97fd7d280d75ee0",
790 | "value": " 938/938 [03:40<00:00, 4.95it/s]"
791 | }
792 | },
793 | "80ad93a8096a41f6ba7035bb483ee461": {
794 | "model_module": "@jupyter-widgets/base",
795 | "model_name": "LayoutModel",
796 | "model_module_version": "1.2.0",
797 | "state": {
798 | "_model_module": "@jupyter-widgets/base",
799 | "_model_module_version": "1.2.0",
800 | "_model_name": "LayoutModel",
801 | "_view_count": null,
802 | "_view_module": "@jupyter-widgets/base",
803 | "_view_module_version": "1.2.0",
804 | "_view_name": "LayoutView",
805 | "align_content": null,
806 | "align_items": null,
807 | "align_self": null,
808 | "border": null,
809 | "bottom": null,
810 | "display": null,
811 | "flex": null,
812 | "flex_flow": null,
813 | "grid_area": null,
814 | "grid_auto_columns": null,
815 | "grid_auto_flow": null,
816 | "grid_auto_rows": null,
817 | "grid_column": null,
818 | "grid_gap": null,
819 | "grid_row": null,
820 | "grid_template_areas": null,
821 | "grid_template_columns": null,
822 | "grid_template_rows": null,
823 | "height": null,
824 | "justify_content": null,
825 | "justify_items": null,
826 | "left": null,
827 | "margin": null,
828 | "max_height": null,
829 | "max_width": null,
830 | "min_height": null,
831 | "min_width": null,
832 | "object_fit": null,
833 | "object_position": null,
834 | "order": null,
835 | "overflow": null,
836 | "overflow_x": null,
837 | "overflow_y": null,
838 | "padding": null,
839 | "right": null,
840 | "top": null,
841 | "visibility": null,
842 | "width": null
843 | }
844 | },
845 | "bf1b70fc39db4494aee42122b14a0c8a": {
846 | "model_module": "@jupyter-widgets/base",
847 | "model_name": "LayoutModel",
848 | "model_module_version": "1.2.0",
849 | "state": {
850 | "_model_module": "@jupyter-widgets/base",
851 | "_model_module_version": "1.2.0",
852 | "_model_name": "LayoutModel",
853 | "_view_count": null,
854 | "_view_module": "@jupyter-widgets/base",
855 | "_view_module_version": "1.2.0",
856 | "_view_name": "LayoutView",
857 | "align_content": null,
858 | "align_items": null,
859 | "align_self": null,
860 | "border": null,
861 | "bottom": null,
862 | "display": null,
863 | "flex": null,
864 | "flex_flow": null,
865 | "grid_area": null,
866 | "grid_auto_columns": null,
867 | "grid_auto_flow": null,
868 | "grid_auto_rows": null,
869 | "grid_column": null,
870 | "grid_gap": null,
871 | "grid_row": null,
872 | "grid_template_areas": null,
873 | "grid_template_columns": null,
874 | "grid_template_rows": null,
875 | "height": null,
876 | "justify_content": null,
877 | "justify_items": null,
878 | "left": null,
879 | "margin": null,
880 | "max_height": null,
881 | "max_width": null,
882 | "min_height": null,
883 | "min_width": null,
884 | "object_fit": null,
885 | "object_position": null,
886 | "order": null,
887 | "overflow": null,
888 | "overflow_x": null,
889 | "overflow_y": null,
890 | "padding": null,
891 | "right": null,
892 | "top": null,
893 | "visibility": null,
894 | "width": null
895 | }
896 | },
897 | "9cfbaf78195a4409aa3c751fef6377e1": {
898 | "model_module": "@jupyter-widgets/controls",
899 | "model_name": "DescriptionStyleModel",
900 | "model_module_version": "1.5.0",
901 | "state": {
902 | "_model_module": "@jupyter-widgets/controls",
903 | "_model_module_version": "1.5.0",
904 | "_model_name": "DescriptionStyleModel",
905 | "_view_count": null,
906 | "_view_module": "@jupyter-widgets/base",
907 | "_view_module_version": "1.2.0",
908 | "_view_name": "StyleView",
909 | "description_width": ""
910 | }
911 | },
912 | "c8379e3f85c74bb9889bf49229de82b3": {
913 | "model_module": "@jupyter-widgets/base",
914 | "model_name": "LayoutModel",
915 | "model_module_version": "1.2.0",
916 | "state": {
917 | "_model_module": "@jupyter-widgets/base",
918 | "_model_module_version": "1.2.0",
919 | "_model_name": "LayoutModel",
920 | "_view_count": null,
921 | "_view_module": "@jupyter-widgets/base",
922 | "_view_module_version": "1.2.0",
923 | "_view_name": "LayoutView",
924 | "align_content": null,
925 | "align_items": null,
926 | "align_self": null,
927 | "border": null,
928 | "bottom": null,
929 | "display": null,
930 | "flex": null,
931 | "flex_flow": null,
932 | "grid_area": null,
933 | "grid_auto_columns": null,
934 | "grid_auto_flow": null,
935 | "grid_auto_rows": null,
936 | "grid_column": null,
937 | "grid_gap": null,
938 | "grid_row": null,
939 | "grid_template_areas": null,
940 | "grid_template_columns": null,
941 | "grid_template_rows": null,
942 | "height": null,
943 | "justify_content": null,
944 | "justify_items": null,
945 | "left": null,
946 | "margin": null,
947 | "max_height": null,
948 | "max_width": null,
949 | "min_height": null,
950 | "min_width": null,
951 | "object_fit": null,
952 | "object_position": null,
953 | "order": null,
954 | "overflow": null,
955 | "overflow_x": null,
956 | "overflow_y": null,
957 | "padding": null,
958 | "right": null,
959 | "top": null,
960 | "visibility": null,
961 | "width": null
962 | }
963 | },
964 | "75125bd2901045ffa9c9b7d3583ee94c": {
965 | "model_module": "@jupyter-widgets/controls",
966 | "model_name": "ProgressStyleModel",
967 | "model_module_version": "1.5.0",
968 | "state": {
969 | "_model_module": "@jupyter-widgets/controls",
970 | "_model_module_version": "1.5.0",
971 | "_model_name": "ProgressStyleModel",
972 | "_view_count": null,
973 | "_view_module": "@jupyter-widgets/base",
974 | "_view_module_version": "1.2.0",
975 | "_view_name": "StyleView",
976 | "bar_color": null,
977 | "description_width": ""
978 | }
979 | },
980 | "78a5fa8234ac4ff182f882908461559a": {
981 | "model_module": "@jupyter-widgets/base",
982 | "model_name": "LayoutModel",
983 | "model_module_version": "1.2.0",
984 | "state": {
985 | "_model_module": "@jupyter-widgets/base",
986 | "_model_module_version": "1.2.0",
987 | "_model_name": "LayoutModel",
988 | "_view_count": null,
989 | "_view_module": "@jupyter-widgets/base",
990 | "_view_module_version": "1.2.0",
991 | "_view_name": "LayoutView",
992 | "align_content": null,
993 | "align_items": null,
994 | "align_self": null,
995 | "border": null,
996 | "bottom": null,
997 | "display": null,
998 | "flex": null,
999 | "flex_flow": null,
1000 | "grid_area": null,
1001 | "grid_auto_columns": null,
1002 | "grid_auto_flow": null,
1003 | "grid_auto_rows": null,
1004 | "grid_column": null,
1005 | "grid_gap": null,
1006 | "grid_row": null,
1007 | "grid_template_areas": null,
1008 | "grid_template_columns": null,
1009 | "grid_template_rows": null,
1010 | "height": null,
1011 | "justify_content": null,
1012 | "justify_items": null,
1013 | "left": null,
1014 | "margin": null,
1015 | "max_height": null,
1016 | "max_width": null,
1017 | "min_height": null,
1018 | "min_width": null,
1019 | "object_fit": null,
1020 | "object_position": null,
1021 | "order": null,
1022 | "overflow": null,
1023 | "overflow_x": null,
1024 | "overflow_y": null,
1025 | "padding": null,
1026 | "right": null,
1027 | "top": null,
1028 | "visibility": null,
1029 | "width": null
1030 | }
1031 | },
1032 | "28abc7c5f1914aa0a97fd7d280d75ee0": {
1033 | "model_module": "@jupyter-widgets/controls",
1034 | "model_name": "DescriptionStyleModel",
1035 | "model_module_version": "1.5.0",
1036 | "state": {
1037 | "_model_module": "@jupyter-widgets/controls",
1038 | "_model_module_version": "1.5.0",
1039 | "_model_name": "DescriptionStyleModel",
1040 | "_view_count": null,
1041 | "_view_module": "@jupyter-widgets/base",
1042 | "_view_module_version": "1.2.0",
1043 | "_view_name": "StyleView",
1044 | "description_width": ""
1045 | }
1046 | },
1047 | "c9305060d9e144a095a0d93b63355e0b": {
1048 | "model_module": "@jupyter-widgets/controls",
1049 | "model_name": "HBoxModel",
1050 | "model_module_version": "1.5.0",
1051 | "state": {
1052 | "_dom_classes": [],
1053 | "_model_module": "@jupyter-widgets/controls",
1054 | "_model_module_version": "1.5.0",
1055 | "_model_name": "HBoxModel",
1056 | "_view_count": null,
1057 | "_view_module": "@jupyter-widgets/controls",
1058 | "_view_module_version": "1.5.0",
1059 | "_view_name": "HBoxView",
1060 | "box_style": "",
1061 | "children": [
1062 | "IPY_MODEL_2afc450d38f948ad89af08983065e9e2",
1063 | "IPY_MODEL_6dfbbde3bbe84ab9803ae729c6697aae",
1064 | "IPY_MODEL_58a1dace4c7b4ad98419fb961b920cc0"
1065 | ],
1066 | "layout": "IPY_MODEL_68db21ef3c204407ad9fa181fea152ae"
1067 | }
1068 | },
1069 | "2afc450d38f948ad89af08983065e9e2": {
1070 | "model_module": "@jupyter-widgets/controls",
1071 | "model_name": "HTMLModel",
1072 | "model_module_version": "1.5.0",
1073 | "state": {
1074 | "_dom_classes": [],
1075 | "_model_module": "@jupyter-widgets/controls",
1076 | "_model_module_version": "1.5.0",
1077 | "_model_name": "HTMLModel",
1078 | "_view_count": null,
1079 | "_view_module": "@jupyter-widgets/controls",
1080 | "_view_module_version": "1.5.0",
1081 | "_view_name": "HTMLView",
1082 | "description": "",
1083 | "description_tooltip": null,
1084 | "layout": "IPY_MODEL_b01677a02efb420cb32c0957d77a2345",
1085 | "placeholder": "",
1086 | "style": "IPY_MODEL_f8cfcf541c684ad889fda00b140e3ab1",
1087 | "value": " 2%"
1088 | }
1089 | },
1090 | "6dfbbde3bbe84ab9803ae729c6697aae": {
1091 | "model_module": "@jupyter-widgets/controls",
1092 | "model_name": "FloatProgressModel",
1093 | "model_module_version": "1.5.0",
1094 | "state": {
1095 | "_dom_classes": [],
1096 | "_model_module": "@jupyter-widgets/controls",
1097 | "_model_module_version": "1.5.0",
1098 | "_model_name": "FloatProgressModel",
1099 | "_view_count": null,
1100 | "_view_module": "@jupyter-widgets/controls",
1101 | "_view_module_version": "1.5.0",
1102 | "_view_name": "ProgressView",
1103 | "bar_style": "danger",
1104 | "description": "",
1105 | "description_tooltip": null,
1106 | "layout": "IPY_MODEL_de9dcf17fb4a4858a5b68922376272e2",
1107 | "max": 938,
1108 | "min": 0,
1109 | "orientation": "horizontal",
1110 | "style": "IPY_MODEL_a32ba491756d40f49fe5b7e795bd3f21",
1111 | "value": 22
1112 | }
1113 | },
1114 | "58a1dace4c7b4ad98419fb961b920cc0": {
1115 | "model_module": "@jupyter-widgets/controls",
1116 | "model_name": "HTMLModel",
1117 | "model_module_version": "1.5.0",
1118 | "state": {
1119 | "_dom_classes": [],
1120 | "_model_module": "@jupyter-widgets/controls",
1121 | "_model_module_version": "1.5.0",
1122 | "_model_name": "HTMLModel",
1123 | "_view_count": null,
1124 | "_view_module": "@jupyter-widgets/controls",
1125 | "_view_module_version": "1.5.0",
1126 | "_view_name": "HTMLView",
1127 | "description": "",
1128 | "description_tooltip": null,
1129 | "layout": "IPY_MODEL_1354164d0f164f7dac7a26e7fa86ca61",
1130 | "placeholder": "",
1131 | "style": "IPY_MODEL_02c67b9bb3904e71a68168c23418fa1c",
1132 | "value": " 22/938 [00:05<03:39, 4.17it/s]"
1133 | }
1134 | },
1135 | "68db21ef3c204407ad9fa181fea152ae": {
1136 | "model_module": "@jupyter-widgets/base",
1137 | "model_name": "LayoutModel",
1138 | "model_module_version": "1.2.0",
1139 | "state": {
1140 | "_model_module": "@jupyter-widgets/base",
1141 | "_model_module_version": "1.2.0",
1142 | "_model_name": "LayoutModel",
1143 | "_view_count": null,
1144 | "_view_module": "@jupyter-widgets/base",
1145 | "_view_module_version": "1.2.0",
1146 | "_view_name": "LayoutView",
1147 | "align_content": null,
1148 | "align_items": null,
1149 | "align_self": null,
1150 | "border": null,
1151 | "bottom": null,
1152 | "display": null,
1153 | "flex": null,
1154 | "flex_flow": null,
1155 | "grid_area": null,
1156 | "grid_auto_columns": null,
1157 | "grid_auto_flow": null,
1158 | "grid_auto_rows": null,
1159 | "grid_column": null,
1160 | "grid_gap": null,
1161 | "grid_row": null,
1162 | "grid_template_areas": null,
1163 | "grid_template_columns": null,
1164 | "grid_template_rows": null,
1165 | "height": null,
1166 | "justify_content": null,
1167 | "justify_items": null,
1168 | "left": null,
1169 | "margin": null,
1170 | "max_height": null,
1171 | "max_width": null,
1172 | "min_height": null,
1173 | "min_width": null,
1174 | "object_fit": null,
1175 | "object_position": null,
1176 | "order": null,
1177 | "overflow": null,
1178 | "overflow_x": null,
1179 | "overflow_y": null,
1180 | "padding": null,
1181 | "right": null,
1182 | "top": null,
1183 | "visibility": null,
1184 | "width": null
1185 | }
1186 | },
1187 | "b01677a02efb420cb32c0957d77a2345": {
1188 | "model_module": "@jupyter-widgets/base",
1189 | "model_name": "LayoutModel",
1190 | "model_module_version": "1.2.0",
1191 | "state": {
1192 | "_model_module": "@jupyter-widgets/base",
1193 | "_model_module_version": "1.2.0",
1194 | "_model_name": "LayoutModel",
1195 | "_view_count": null,
1196 | "_view_module": "@jupyter-widgets/base",
1197 | "_view_module_version": "1.2.0",
1198 | "_view_name": "LayoutView",
1199 | "align_content": null,
1200 | "align_items": null,
1201 | "align_self": null,
1202 | "border": null,
1203 | "bottom": null,
1204 | "display": null,
1205 | "flex": null,
1206 | "flex_flow": null,
1207 | "grid_area": null,
1208 | "grid_auto_columns": null,
1209 | "grid_auto_flow": null,
1210 | "grid_auto_rows": null,
1211 | "grid_column": null,
1212 | "grid_gap": null,
1213 | "grid_row": null,
1214 | "grid_template_areas": null,
1215 | "grid_template_columns": null,
1216 | "grid_template_rows": null,
1217 | "height": null,
1218 | "justify_content": null,
1219 | "justify_items": null,
1220 | "left": null,
1221 | "margin": null,
1222 | "max_height": null,
1223 | "max_width": null,
1224 | "min_height": null,
1225 | "min_width": null,
1226 | "object_fit": null,
1227 | "object_position": null,
1228 | "order": null,
1229 | "overflow": null,
1230 | "overflow_x": null,
1231 | "overflow_y": null,
1232 | "padding": null,
1233 | "right": null,
1234 | "top": null,
1235 | "visibility": null,
1236 | "width": null
1237 | }
1238 | },
1239 | "f8cfcf541c684ad889fda00b140e3ab1": {
1240 | "model_module": "@jupyter-widgets/controls",
1241 | "model_name": "DescriptionStyleModel",
1242 | "model_module_version": "1.5.0",
1243 | "state": {
1244 | "_model_module": "@jupyter-widgets/controls",
1245 | "_model_module_version": "1.5.0",
1246 | "_model_name": "DescriptionStyleModel",
1247 | "_view_count": null,
1248 | "_view_module": "@jupyter-widgets/base",
1249 | "_view_module_version": "1.2.0",
1250 | "_view_name": "StyleView",
1251 | "description_width": ""
1252 | }
1253 | },
1254 | "de9dcf17fb4a4858a5b68922376272e2": {
1255 | "model_module": "@jupyter-widgets/base",
1256 | "model_name": "LayoutModel",
1257 | "model_module_version": "1.2.0",
1258 | "state": {
1259 | "_model_module": "@jupyter-widgets/base",
1260 | "_model_module_version": "1.2.0",
1261 | "_model_name": "LayoutModel",
1262 | "_view_count": null,
1263 | "_view_module": "@jupyter-widgets/base",
1264 | "_view_module_version": "1.2.0",
1265 | "_view_name": "LayoutView",
1266 | "align_content": null,
1267 | "align_items": null,
1268 | "align_self": null,
1269 | "border": null,
1270 | "bottom": null,
1271 | "display": null,
1272 | "flex": null,
1273 | "flex_flow": null,
1274 | "grid_area": null,
1275 | "grid_auto_columns": null,
1276 | "grid_auto_flow": null,
1277 | "grid_auto_rows": null,
1278 | "grid_column": null,
1279 | "grid_gap": null,
1280 | "grid_row": null,
1281 | "grid_template_areas": null,
1282 | "grid_template_columns": null,
1283 | "grid_template_rows": null,
1284 | "height": null,
1285 | "justify_content": null,
1286 | "justify_items": null,
1287 | "left": null,
1288 | "margin": null,
1289 | "max_height": null,
1290 | "max_width": null,
1291 | "min_height": null,
1292 | "min_width": null,
1293 | "object_fit": null,
1294 | "object_position": null,
1295 | "order": null,
1296 | "overflow": null,
1297 | "overflow_x": null,
1298 | "overflow_y": null,
1299 | "padding": null,
1300 | "right": null,
1301 | "top": null,
1302 | "visibility": null,
1303 | "width": null
1304 | }
1305 | },
1306 | "a32ba491756d40f49fe5b7e795bd3f21": {
1307 | "model_module": "@jupyter-widgets/controls",
1308 | "model_name": "ProgressStyleModel",
1309 | "model_module_version": "1.5.0",
1310 | "state": {
1311 | "_model_module": "@jupyter-widgets/controls",
1312 | "_model_module_version": "1.5.0",
1313 | "_model_name": "ProgressStyleModel",
1314 | "_view_count": null,
1315 | "_view_module": "@jupyter-widgets/base",
1316 | "_view_module_version": "1.2.0",
1317 | "_view_name": "StyleView",
1318 | "bar_color": null,
1319 | "description_width": ""
1320 | }
1321 | },
1322 | "1354164d0f164f7dac7a26e7fa86ca61": {
1323 | "model_module": "@jupyter-widgets/base",
1324 | "model_name": "LayoutModel",
1325 | "model_module_version": "1.2.0",
1326 | "state": {
1327 | "_model_module": "@jupyter-widgets/base",
1328 | "_model_module_version": "1.2.0",
1329 | "_model_name": "LayoutModel",
1330 | "_view_count": null,
1331 | "_view_module": "@jupyter-widgets/base",
1332 | "_view_module_version": "1.2.0",
1333 | "_view_name": "LayoutView",
1334 | "align_content": null,
1335 | "align_items": null,
1336 | "align_self": null,
1337 | "border": null,
1338 | "bottom": null,
1339 | "display": null,
1340 | "flex": null,
1341 | "flex_flow": null,
1342 | "grid_area": null,
1343 | "grid_auto_columns": null,
1344 | "grid_auto_flow": null,
1345 | "grid_auto_rows": null,
1346 | "grid_column": null,
1347 | "grid_gap": null,
1348 | "grid_row": null,
1349 | "grid_template_areas": null,
1350 | "grid_template_columns": null,
1351 | "grid_template_rows": null,
1352 | "height": null,
1353 | "justify_content": null,
1354 | "justify_items": null,
1355 | "left": null,
1356 | "margin": null,
1357 | "max_height": null,
1358 | "max_width": null,
1359 | "min_height": null,
1360 | "min_width": null,
1361 | "object_fit": null,
1362 | "object_position": null,
1363 | "order": null,
1364 | "overflow": null,
1365 | "overflow_x": null,
1366 | "overflow_y": null,
1367 | "padding": null,
1368 | "right": null,
1369 | "top": null,
1370 | "visibility": null,
1371 | "width": null
1372 | }
1373 | },
1374 | "02c67b9bb3904e71a68168c23418fa1c": {
1375 | "model_module": "@jupyter-widgets/controls",
1376 | "model_name": "DescriptionStyleModel",
1377 | "model_module_version": "1.5.0",
1378 | "state": {
1379 | "_model_module": "@jupyter-widgets/controls",
1380 | "_model_module_version": "1.5.0",
1381 | "_model_name": "DescriptionStyleModel",
1382 | "_view_count": null,
1383 | "_view_module": "@jupyter-widgets/base",
1384 | "_view_module_version": "1.2.0",
1385 | "_view_name": "StyleView",
1386 | "description_width": ""
1387 | }
1388 | }
1389 | }
1390 | }
1391 | },
1392 | "cells": [
1393 | {
1394 | "cell_type": "markdown",
1395 | "metadata": {
1396 | "id": "view-in-github",
1397 | "colab_type": "text"
1398 | },
1399 | "source": [
1400 | "
"
1401 | ]
1402 | },
1403 | {
1404 | "cell_type": "code",
1405 | "execution_count": 1,
1406 | "metadata": {
1407 | "id": "Ee1NBwatIJlR"
1408 | },
1409 | "outputs": [],
1410 | "source": [
1411 | "import torch\n",
1412 | "import torch.nn as nn\n",
1413 | "import torch.nn.functional as F\n",
1414 | "import torch.optim as optim\n",
1415 | "\n",
1416 | "from torch.utils.data import Dataset, DataLoader, ConcatDataset\n",
1417 | "\n",
1418 | "import torchvision as tv\n",
1419 | "import torchvision.transforms as T\n",
1420 | "\n",
1421 | "from PIL import Image\n",
1422 | "\n",
1423 | "import numpy as np\n",
1424 | "import matplotlib.pyplot as plt\n",
1425 | "\n",
1426 | "from tqdm.notebook import tqdm"
1427 | ]
1428 | },
1429 | {
1430 | "cell_type": "code",
1431 | "source": [
1432 | "START = 1e-4\n",
1433 | "END = .02\n",
1434 | "TIMESTEPS = 300\n",
1435 | "\n",
1436 | "IMAGE_SIZE = 64\n",
1437 | "BATCH_SIZE = 64\n",
1438 | "EPOCHS = 5\n",
1439 | "\n",
1440 | "LR = 1e-3\n",
1441 | "\n",
1442 | "DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'"
1443 | ],
1444 | "metadata": {
1445 | "id": "nzHOnslOMzvU"
1446 | },
1447 | "execution_count": 2,
1448 | "outputs": []
1449 | },
1450 | {
1451 | "cell_type": "code",
1452 | "source": [
1453 | "betas = torch.linspace(start=START, end=END, steps=TIMESTEPS)\n",
1454 | "alphas = 1 - betas\n",
1455 | "\n",
1456 | "alpha_bars = torch.cumprod(alphas, dim=0)\n",
1457 | "alpha_bars_prev = F.pad(alpha_bars[:-1], (1, 0), value=1.0)\n",
1458 | "sqrt_one_over_alpha_bars = torch.sqrt(1. / alpha_bars)\n",
1459 | "sqrt_alpha_bars = torch.sqrt(alpha_bars)\n",
1460 | "sqrt_one_minus_alpha_bars = torch.sqrt(1 - alpha_bars)\n",
1461 | "\n",
1462 | "posterior_variance = betas * (1. - alpha_bars_prev) / (1. - alpha_bars)"
1463 | ],
1464 | "metadata": {
1465 | "id": "_zBev601NSRS"
1466 | },
1467 | "execution_count": 3,
1468 | "outputs": []
1469 | },
1470 | {
1471 | "cell_type": "code",
1472 | "source": [
1473 | "class ConvBlock(nn.Module):\n",
1474 | " def __init__(self, in_channels, out_channels):\n",
1475 | " super().__init__()\n",
1476 | "\n",
1477 | " self.conv_blocks = nn.Sequential(\n",
1478 | " nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=3, padding=1, bias=False),\n",
1479 | " nn.ReLU(inplace=True),\n",
1480 | " nn.BatchNorm2d(out_channels),\n",
1481 | " nn.Conv2d(in_channels=out_channels, out_channels=out_channels, kernel_size=3, padding=1, bias=False),\n",
1482 | " nn.ReLU(inplace=True),\n",
1483 | " nn.BatchNorm2d(out_channels),\n",
1484 | " )\n",
1485 | "\n",
1486 | " def forward(self, x):\n",
1487 | " return self.conv_blocks(x)"
1488 | ],
1489 | "metadata": {
1490 | "id": "GMK460xiUdg7"
1491 | },
1492 | "execution_count": 4,
1493 | "outputs": []
1494 | },
1495 | {
1496 | "cell_type": "code",
1497 | "source": [
1498 | "class DownBlock(nn.Module):\n",
1499 | " def __init__(self, in_channels, out_channels):\n",
1500 | " super().__init__()\n",
1501 | "\n",
1502 | " self.conv_blocks = nn.Sequential(\n",
1503 | " nn.MaxPool2d(2),\n",
1504 | " ConvBlock(in_channels, out_channels)\n",
1505 | " )\n",
1506 | "\n",
1507 | " def forward(self, x):\n",
1508 | " return self.conv_blocks(x)"
1509 | ],
1510 | "metadata": {
1511 | "id": "DYvOCCVRUtNS"
1512 | },
1513 | "execution_count": 5,
1514 | "outputs": []
1515 | },
1516 | {
1517 | "cell_type": "code",
1518 | "source": [
1519 | "class UpBlock(nn.Module):\n",
1520 | " def __init__(self, in_channels, out_channels):\n",
1521 | " super().__init__()\n",
1522 | "\n",
1523 | " self.up = nn.ConvTranspose2d(in_channels=in_channels, out_channels=in_channels//2, kernel_size=2, stride=2)\n",
1524 | " self.conv_blocks = ConvBlock(in_channels, out_channels)\n",
1525 | "\n",
1526 | " def forward(self, x, residual_inputs):\n",
1527 | " x = self.up(x)\n",
1528 | "\n",
1529 | " diff_y = residual_inputs.size()[2] - x.size()[2]\n",
1530 | " diff_x = residual_inputs.size()[3] - x.size()[3]\n",
1531 | "\n",
1532 | " x = F.pad(x, [diff_x // 2, diff_x - diff_x // 2,\n",
1533 | " diff_y // 2, diff_y - diff_y // 2])\n",
1534 | "\n",
1535 | " x = torch.cat([residual_inputs, x], dim=1)\n",
1536 | " x = self.conv_blocks(x)\n",
1537 | "\n",
1538 | " return x"
1539 | ],
1540 | "metadata": {
1541 | "id": "3QFPrpawUtP6"
1542 | },
1543 | "execution_count": 6,
1544 | "outputs": []
1545 | },
1546 | {
1547 | "cell_type": "code",
1548 | "source": [
1549 | "class OutBlock(nn.Module):\n",
1550 | " def __init__(self, in_channels, num_classes):\n",
1551 | " super().__init__()\n",
1552 | "\n",
1553 | " self.conv = nn.Conv2d(in_channels=in_channels, out_channels=num_classes, kernel_size=1)\n",
1554 | "\n",
1555 | " def forward(self, x):\n",
1556 | " return self.conv(x)"
1557 | ],
1558 | "metadata": {
1559 | "id": "s-V4VnnUUtTM"
1560 | },
1561 | "execution_count": 7,
1562 | "outputs": []
1563 | },
1564 | {
1565 | "cell_type": "code",
1566 | "source": [
1567 | "class UNet(nn.Module):\n",
1568 | " def __init__(self, in_channels, num_classes):\n",
1569 | " super().__init__()\n",
1570 | "\n",
1571 | " self.input_block = ConvBlock(in_channels, 64)\n",
1572 | "\n",
1573 | " self.down_1 = DownBlock(64, 128)\n",
1574 | " self.down_2 = DownBlock(128, 256)\n",
1575 | " self.down_3 = DownBlock(256, 512)\n",
1576 | " self.down_4 = DownBlock(512, 1024)\n",
1577 | "\n",
1578 | " self.up_4 = UpBlock(1024, 512)\n",
1579 | " self.up_3 = UpBlock(512, 256)\n",
1580 | " self.up_2 = UpBlock(256, 128)\n",
1581 | " self.up_1 = UpBlock(128, 64)\n",
1582 | "\n",
1583 | " self.output_block = OutBlock(64, num_classes)\n",
1584 | "\n",
1585 | " self.embedding_up_1 = nn.Linear(1, 128)\n",
1586 | " self.embedding_up_2 = nn.Linear(1, 256)\n",
1587 | " self.embedding_up_3 = nn.Linear(1, 512)\n",
1588 | " self.embedding_up_4 = nn.Linear(1, 1024)\n",
1589 | "\n",
1590 | " def forward(self, x, t):\n",
1591 | " batch_size = x.size(0)\n",
1592 | " down_cache_1 = self.input_block(x)\n",
1593 | "\n",
1594 | " down_cache_2 = self.down_1(down_cache_1)\n",
1595 | " down_cache_3 = self.down_2(down_cache_2)\n",
1596 | " down_cache_4 = self.down_3(down_cache_3)\n",
1597 | " down_cache_5 = self.down_4(down_cache_4)\n",
1598 | "\n",
1599 | " t_embed = self.embedding_up_4(t).view(batch_size, -1, 1, 1)\n",
1600 | " x = self.up_4(down_cache_5 + t_embed, down_cache_4)\n",
1601 | "\n",
1602 | " t_embed = self.embedding_up_3(t).view(batch_size, -1, 1, 1)\n",
1603 | " x = self.up_3(x + t_embed, down_cache_3)\n",
1604 | "\n",
1605 | " t_embed = self.embedding_up_2(t).view(batch_size, -1, 1, 1)\n",
1606 | " x = self.up_2(x + t_embed, down_cache_2)\n",
1607 | "\n",
1608 | " t_embed = self.embedding_up_1(t).view(batch_size, -1, 1, 1)\n",
1609 | " x = self.up_1(x + t_embed, down_cache_1)\n",
1610 | "\n",
1611 | " x = self.output_block(x)\n",
1612 | "\n",
1613 | " return x"
1614 | ],
1615 | "metadata": {
1616 | "id": "nQd2F863UtWj"
1617 | },
1618 | "execution_count": 8,
1619 | "outputs": []
1620 | },
1621 | {
1622 | "cell_type": "code",
1623 | "source": [
1624 | "def get_index_for_batch(values, t, x_shape):\n",
1625 | " batch_size = t.size(0)\n",
1626 | " out = values.gather(-1, t.cpu())\n",
1627 | "\n",
1628 | " return out.reshape(batch_size, *((1,) * (len(x_shape) - 1))).to(DEVICE)"
1629 | ],
1630 | "metadata": {
1631 | "id": "0d_mFHm6N0mp"
1632 | },
1633 | "execution_count": 9,
1634 | "outputs": []
1635 | },
1636 | {
1637 | "cell_type": "code",
1638 | "source": [
1639 | "def forward_process(x_0, t):\n",
1640 | " noise = torch.randn_like(x_0)\n",
1641 | "\n",
1642 | " sqrt_alpha_bars_for_batch = get_index_for_batch(sqrt_alpha_bars, t, x_0.shape).to(DEVICE)\n",
1643 | " sqrt_one_minus_alpha_bars_for_batch = get_index_for_batch(sqrt_one_minus_alpha_bars, t, x_0.shape).to(DEVICE)\n",
1644 | "\n",
1645 | " z = sqrt_one_minus_alpha_bars_for_batch * noise + sqrt_alpha_bars_for_batch * x_0\n",
1646 | "\n",
1647 | " return z, noise"
1648 | ],
1649 | "metadata": {
1650 | "id": "uhOmFQeZN5XY"
1651 | },
1652 | "execution_count": 10,
1653 | "outputs": []
1654 | },
1655 | {
1656 | "cell_type": "code",
1657 | "source": [
1658 | "reverse_transforms = T.Compose([\n",
1659 | " T.Lambda(lambda x: (x + 1) / 2),\n",
1660 | " T.Lambda(lambda x: x.permute(1, 2, 0)),\n",
1661 | " T.Lambda(lambda x: x * 255),\n",
1662 | " T.Lambda(lambda x: x.cpu().numpy().astype(np.uint8)),\n",
1663 | " T.ToPILImage()\n",
1664 | "])\n",
1665 | "\n",
1666 | "def convert_tensor_image(image):\n",
1667 | " if len(image.shape) == 4:\n",
1668 | " image = image[0, :, :, :]\n",
1669 | "\n",
1670 | " image = reverse_transforms(image)\n",
1671 | " return image"
1672 | ],
1673 | "metadata": {
1674 | "id": "-oWTY3w9SxDK"
1675 | },
1676 | "execution_count": 11,
1677 | "outputs": []
1678 | },
1679 | {
1680 | "cell_type": "code",
1681 | "source": [
1682 | "transforms = T.Compose([\n",
1683 | " T.Resize((IMAGE_SIZE, IMAGE_SIZE)),\n",
1684 | " T.RandomHorizontalFlip(),\n",
1685 | " T.ToTensor(),\n",
1686 | " T.Lambda(lambda x: (x * 2) - 1)\n",
1687 | "])\n",
1688 | "\n",
1689 | "train = tv.datasets.CIFAR10(root='./dataset', download=True, transform=transforms, train=True)\n",
1690 | "val = tv.datasets.CIFAR10(root='./dataset', download=True, transform=transforms, train=False)\n",
1691 | "\n",
1692 | "dataset = ConcatDataset([train, val])\n",
1693 | "dataloader = DataLoader(dataset, batch_size=BATCH_SIZE, shuffle=True)"
1694 | ],
1695 | "metadata": {
1696 | "colab": {
1697 | "base_uri": "https://localhost:8080/"
1698 | },
1699 | "id": "aRMbMaGMRrgS",
1700 | "outputId": "763ce410-8c10-42dd-9468-f922c4055924"
1701 | },
1702 | "execution_count": 12,
1703 | "outputs": [
1704 | {
1705 | "output_type": "stream",
1706 | "name": "stdout",
1707 | "text": [
1708 | "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./dataset/cifar-10-python.tar.gz\n"
1709 | ]
1710 | },
1711 | {
1712 | "output_type": "stream",
1713 | "name": "stderr",
1714 | "text": [
1715 | "100%|██████████| 170498071/170498071 [00:13<00:00, 12645277.96it/s]\n"
1716 | ]
1717 | },
1718 | {
1719 | "output_type": "stream",
1720 | "name": "stdout",
1721 | "text": [
1722 | "Extracting ./dataset/cifar-10-python.tar.gz to ./dataset\n",
1723 | "Files already downloaded and verified\n"
1724 | ]
1725 | }
1726 | ]
1727 | },
1728 | {
1729 | "cell_type": "code",
1730 | "source": [
1731 | "network = UNet(3, 3).to(DEVICE)"
1732 | ],
1733 | "metadata": {
1734 | "id": "5WW4S17DSgsI"
1735 | },
1736 | "execution_count": 13,
1737 | "outputs": []
1738 | },
1739 | {
1740 | "cell_type": "code",
1741 | "source": [
1742 | "optimizer = optim.Adam(network.parameters(), lr=LR)"
1743 | ],
1744 | "metadata": {
1745 | "id": "DNCJALJwToDx"
1746 | },
1747 | "execution_count": 14,
1748 | "outputs": []
1749 | },
1750 | {
1751 | "cell_type": "code",
1752 | "source": [
1753 | "criterion = nn.MSELoss()"
1754 | ],
1755 | "metadata": {
1756 | "id": "nnYKe7ZwXPth"
1757 | },
1758 | "execution_count": 15,
1759 | "outputs": []
1760 | },
1761 | {
1762 | "cell_type": "code",
1763 | "source": [
1764 | "for epoch in range(1, EPOCHS + 1):\n",
1765 | " print(f'Epoch {epoch} / {EPOCHS}')\n",
1766 | " total_loss = .0\n",
1767 | " for images, _ in tqdm(dataloader):\n",
1768 | " optimizer.zero_grad()\n",
1769 | "\n",
1770 | " images = images.to(DEVICE)\n",
1771 | "\n",
1772 | " batch_size = images.size(0)\n",
1773 | " t = torch.randint(0, TIMESTEPS, (batch_size,)).to(DEVICE).long()\n",
1774 | " noisy_image, noise = forward_process(images, t)\n",
1775 | " noise_preds = network(noisy_image, t.unsqueeze(-1).float())\n",
1776 | "\n",
1777 | " loss = criterion(noise_preds, noise)\n",
1778 | " loss.backward()\n",
1779 | "\n",
1780 | " optimizer.step()\n",
1781 | "\n",
1782 | " total_loss += loss.detach().cpu().item()\n",
1783 | "\n",
1784 | " print(f'Loss: {total_loss:.2f}')"
1785 | ],
1786 | "metadata": {
1787 | "colab": {
1788 | "base_uri": "https://localhost:8080/",
1789 | "height": 474,
1790 | "referenced_widgets": [
1791 | "b0fa66fc56e34465bb2a59f9ce916b71",
1792 | "14019560a279458cb775634b162b2407",
1793 | "4db4b93e47bd4c859b1d6685ed8cf76e",
1794 | "2ef34af8de2c4c7eab85fd3c83a5e1c5",
1795 | "1638fe599f2c409c8d75396bbad174b7",
1796 | "0a2010f11ba345a385997b328168127a",
1797 | "5a39152a73cb4a87bd5bdf6f5a6888cc",
1798 | "b72fab00156243478d0619f3f8a56a1a",
1799 | "38548a20e7744f098a9118b82ff13f95",
1800 | "47d16d89d79543ab8b893ccae490d2f0",
1801 | "05f22484b66641818d3288792ead2efa",
1802 | "7c76076cccf04326a82ec69c5b33c9af",
1803 | "326f80a6a9364bc4a37fd727649c5599",
1804 | "cd209532893744078f13583bc2765ef5",
1805 | "9933cef2fd0c44c2a308f24e5de0b1ea",
1806 | "9d07802c82da4382966ee2bc58bff4e2",
1807 | "7c62a32ae5944b7584b0026533d3bea9",
1808 | "7d6defe1998a4083bbf9f4fdb4e5d599",
1809 | "5a2ad31325dc45d0b795eb88daf147df",
1810 | "c981017d7c39426dbaf566505c817bf4",
1811 | "2ca3d70b283a4eaba7c683d03a53da07",
1812 | "51922432c661481da1ebe8192367c4dd",
1813 | "61d30891744b4dcda25e8eeb71b54aad",
1814 | "718e38085b3b4f5eab8c481913bad4fb",
1815 | "3346c18e5aae424a9705689c62854830",
1816 | "1a782ba0602d4f7ebb0659295f7497f0",
1817 | "80ad93a8096a41f6ba7035bb483ee461",
1818 | "bf1b70fc39db4494aee42122b14a0c8a",
1819 | "9cfbaf78195a4409aa3c751fef6377e1",
1820 | "c8379e3f85c74bb9889bf49229de82b3",
1821 | "75125bd2901045ffa9c9b7d3583ee94c",
1822 | "78a5fa8234ac4ff182f882908461559a",
1823 | "28abc7c5f1914aa0a97fd7d280d75ee0",
1824 | "c9305060d9e144a095a0d93b63355e0b",
1825 | "2afc450d38f948ad89af08983065e9e2",
1826 | "6dfbbde3bbe84ab9803ae729c6697aae",
1827 | "58a1dace4c7b4ad98419fb961b920cc0",
1828 | "68db21ef3c204407ad9fa181fea152ae",
1829 | "b01677a02efb420cb32c0957d77a2345",
1830 | "f8cfcf541c684ad889fda00b140e3ab1",
1831 | "de9dcf17fb4a4858a5b68922376272e2",
1832 | "a32ba491756d40f49fe5b7e795bd3f21",
1833 | "1354164d0f164f7dac7a26e7fa86ca61",
1834 | "02c67b9bb3904e71a68168c23418fa1c"
1835 | ]
1836 | },
1837 | "id": "re16Q5X9Xjij",
1838 | "outputId": "177d142f-c50b-4ced-9ef8-7b0119d95643"
1839 | },
1840 | "execution_count": 20,
1841 | "outputs": [
1842 | {
1843 | "output_type": "stream",
1844 | "name": "stdout",
1845 | "text": [
1846 | "Epoch 1 / 5\n"
1847 | ]
1848 | },
1849 | {
1850 | "output_type": "display_data",
1851 | "data": {
1852 | "text/plain": [
1853 | " 0%| | 0/938 [00:00, ?it/s]"
1854 | ],
1855 | "application/vnd.jupyter.widget-view+json": {
1856 | "version_major": 2,
1857 | "version_minor": 0,
1858 | "model_id": "b0fa66fc56e34465bb2a59f9ce916b71"
1859 | }
1860 | },
1861 | "metadata": {}
1862 | },
1863 | {
1864 | "output_type": "stream",
1865 | "name": "stdout",
1866 | "text": [
1867 | "Loss: 135.68\n",
1868 | "Epoch 2 / 5\n"
1869 | ]
1870 | },
1871 | {
1872 | "output_type": "display_data",
1873 | "data": {
1874 | "text/plain": [
1875 | " 0%| | 0/938 [00:00, ?it/s]"
1876 | ],
1877 | "application/vnd.jupyter.widget-view+json": {
1878 | "version_major": 2,
1879 | "version_minor": 0,
1880 | "model_id": "7c76076cccf04326a82ec69c5b33c9af"
1881 | }
1882 | },
1883 | "metadata": {}
1884 | },
1885 | {
1886 | "output_type": "stream",
1887 | "name": "stdout",
1888 | "text": [
1889 | "Loss: 44.75\n",
1890 | "Epoch 3 / 5\n"
1891 | ]
1892 | },
1893 | {
1894 | "output_type": "display_data",
1895 | "data": {
1896 | "text/plain": [
1897 | " 0%| | 0/938 [00:00, ?it/s]"
1898 | ],
1899 | "application/vnd.jupyter.widget-view+json": {
1900 | "version_major": 2,
1901 | "version_minor": 0,
1902 | "model_id": "61d30891744b4dcda25e8eeb71b54aad"
1903 | }
1904 | },
1905 | "metadata": {}
1906 | },
1907 | {
1908 | "output_type": "stream",
1909 | "name": "stdout",
1910 | "text": [
1911 | "Loss: 39.01\n",
1912 | "Epoch 4 / 5\n"
1913 | ]
1914 | },
1915 | {
1916 | "output_type": "display_data",
1917 | "data": {
1918 | "text/plain": [
1919 | " 0%| | 0/938 [00:00, ?it/s]"
1920 | ],
1921 | "application/vnd.jupyter.widget-view+json": {
1922 | "version_major": 2,
1923 | "version_minor": 0,
1924 | "model_id": "c9305060d9e144a095a0d93b63355e0b"
1925 | }
1926 | },
1927 | "metadata": {}
1928 | },
1929 | {
1930 | "output_type": "error",
1931 | "ename": "KeyboardInterrupt",
1932 | "evalue": "",
1933 | "traceback": [
1934 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
1935 | "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
1936 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 19\u001b[0;31m \u001b[0mtotal_loss\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdetach\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcpu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mitem\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf'Loss: {total_loss:.2f}'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
1937 | "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
1938 | ]
1939 | }
1940 | ]
1941 | },
1942 | {
1943 | "cell_type": "code",
1944 | "source": [
1945 | "@torch.no_grad()\n",
1946 | "def sample_timestep(x, t):\n",
1947 | " betas_for_batch = get_index_for_batch(betas, t, x.shape)\n",
1948 | " sqrt_one_minus_alpha_for_batch = get_index_for_batch(\n",
1949 | " sqrt_one_minus_alpha_bars, t, x.shape\n",
1950 | " )\n",
1951 | " sqrt_one_over_alpha_bars_for_batch = get_index_for_batch(\n",
1952 | " sqrt_one_over_alpha_bars, t, x.shape\n",
1953 | " )\n",
1954 | "\n",
1955 | " model_mean = sqrt_one_over_alpha_bars_for_batch * (\n",
1956 | " x - betas_for_batch * network(x, t.float()) / sqrt_one_minus_alpha_for_batch\n",
1957 | " )\n",
1958 | "\n",
1959 | " posterior_variance_for_batch = get_index_for_batch(\n",
1960 | " posterior_variance, t, x.shape\n",
1961 | " )\n",
1962 | "\n",
1963 | " if t == 0:\n",
1964 | " return model_mean\n",
1965 | " else:\n",
1966 | " noise = torch.randn_like(x)\n",
1967 | " return model_mean + torch.sqrt(posterior_variance_for_batch) * noise"
1968 | ],
1969 | "metadata": {
1970 | "id": "WO7VBqT3YYei"
1971 | },
1972 | "execution_count": 64,
1973 | "outputs": []
1974 | },
1975 | {
1976 | "cell_type": "code",
1977 | "source": [
1978 | "@torch.no_grad()\n",
1979 | "def sample_plot_image():\n",
1980 | " img_size = IMAGE_SIZE\n",
1981 | " img = torch.randn((1, 3, img_size, img_size), device=DEVICE)\n",
1982 | " num_images = 10\n",
1983 | " stepsize = int(TIMESTEPS / num_images)\n",
1984 | "\n",
1985 | " for i in range(0, TIMESTEPS)[::-1]:\n",
1986 | " t = torch.full((1,), i, device=DEVICE, dtype=torch.long)\n",
1987 | " img = sample_timestep(img, t)\n",
1988 | "\n",
1989 | " return img"
1990 | ],
1991 | "metadata": {
1992 | "id": "WhA9Wk8Mcerx"
1993 | },
1994 | "execution_count": 73,
1995 | "outputs": []
1996 | },
1997 | {
1998 | "cell_type": "code",
1999 | "source": [
2000 | "img = sample_plot_image()"
2001 | ],
2002 | "metadata": {
2003 | "id": "8DGzIGuXeJf-"
2004 | },
2005 | "execution_count": 79,
2006 | "outputs": []
2007 | },
2008 | {
2009 | "cell_type": "code",
2010 | "source": [
2011 | "img = convert_tensor_image(img)\n",
2012 | "plt.imshow(img)\n",
2013 | "plt.show()"
2014 | ],
2015 | "metadata": {
2016 | "id": "Kbc0j49gnQ0I"
2017 | },
2018 | "execution_count": null,
2019 | "outputs": []
2020 | },
2021 | {
2022 | "cell_type": "code",
2023 | "source": [
2024 | "i = 0\n",
2025 | "img = torch.randn((1, 3, IMAGE_SIZE, IMAGE_SIZE), device=DEVICE)\n",
2026 | "t = torch.full((1,), i, device=DEVICE, dtype=torch.long)\n",
2027 | "img = sample_timestep(img, t)"
2028 | ],
2029 | "metadata": {
2030 | "id": "jK--uaBboI5a"
2031 | },
2032 | "execution_count": 81,
2033 | "outputs": []
2034 | },
2035 | {
2036 | "cell_type": "code",
2037 | "source": [
2038 | "img"
2039 | ],
2040 | "metadata": {
2041 | "id": "iFnbbmNXocA2"
2042 | },
2043 | "execution_count": null,
2044 | "outputs": []
2045 | },
2046 | {
2047 | "cell_type": "code",
2048 | "source": [],
2049 | "metadata": {
2050 | "id": "3NgzKu8mov3g"
2051 | },
2052 | "execution_count": 45,
2053 | "outputs": []
2054 | },
2055 | {
2056 | "cell_type": "code",
2057 | "source": [],
2058 | "metadata": {
2059 | "id": "qJxom48CpbRj"
2060 | },
2061 | "execution_count": null,
2062 | "outputs": []
2063 | }
2064 | ]
2065 | }
--------------------------------------------------------------------------------
/23_Value_functions_and_policy_iteration.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "authorship_tag": "ABX9TyN0jZMs8LETkT8dHP5fS1rg",
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | " "
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {
33 | "id": "Fz5lLqGQzR5M"
34 | },
35 | "outputs": [],
36 | "source": [
37 | "import numpy as np"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "source": [
43 | "class Environment:\n",
44 | " def __init__(self):\n",
45 | " self.x = 2\n",
46 | " self.y = 2\n",
47 | " self.A = (0, 1)\n",
48 | " self.B = (0, 3)\n",
49 | " self.A_next = (1, 4)\n",
50 | " self.B_next = (3, 2)\n",
51 | " self.edge_size = 5\n",
52 | "\n",
53 | " def calculate_next(self, y, x, move):\n",
54 | " if isinstance(move, str):\n",
55 | " move = move.lower()\n",
56 | " new_x, new_y = x, y\n",
57 | "\n",
58 | " if move in ('u', 'up', 0):\n",
59 | " new_y -= 1\n",
60 | " elif move in ('d', 'down', 1):\n",
61 | " new_y += 1\n",
62 | " elif move in ('r', 'right', 2):\n",
63 | " new_x += 1\n",
64 | " elif move in ('l', 'left', 3):\n",
65 | " new_x -= 1\n",
66 | "\n",
67 | " if (y, x) == self.A:\n",
68 | " new_x, new_y = self.A_next\n",
69 | " reward = 10\n",
70 | " elif (y, x) == self.B:\n",
71 | " new_x, new_y = self.B_next\n",
72 | " reward = 5\n",
73 | " elif new_x < 0 or new_x >= self.edge_size:\n",
74 | " new_x, new_y = x, y\n",
75 | " reward = -1\n",
76 | " elif new_y < 0 or new_y >= self.edge_size:\n",
77 | " new_x, new_y = x, y\n",
78 | " reward = -1\n",
79 | " else:\n",
80 | " reward = 0\n",
81 | "\n",
82 | " return new_y, new_x, reward\n",
83 | "\n",
84 | " def step(self, move):\n",
85 | " new_y, new_x, reward = self.calculate_next(self.y, self.x, move)\n",
86 | "\n",
87 | " self.y = new_y\n",
88 | " self.x = new_x\n",
89 | "\n",
90 | " return reward\n",
91 | "\n",
92 | " def predict_reward(self, y, x, move):\n",
93 | " new_y, new_x, reward = self.calculate_next(y, x, move)\n",
94 | " return new_y, new_x, reward\n",
95 | "\n",
96 | " def reset(self):\n",
97 | " self.x = 2\n",
98 | " self.y = 2\n",
99 | "\n",
100 | " @property\n",
101 | " def moves(self):\n",
102 | " return range(4)\n",
103 | "\n",
104 | " def __repr__(self):\n",
105 | " val = ''\n",
106 | " for i in range(self.edge_size):\n",
107 | " for j in range(self.edge_size):\n",
108 | " if i == self.y and j == self.x:\n",
109 | " val += '*'\n",
110 | " else:\n",
111 | " val += '_'\n",
112 | " val += '\\n'\n",
113 | " return val"
114 | ],
115 | "metadata": {
116 | "id": "7fxGRyVVzf1U"
117 | },
118 | "execution_count": 126,
119 | "outputs": []
120 | },
121 | {
122 | "cell_type": "code",
123 | "source": [
124 | "def argmax(values):\n",
125 | " maximum = float('-inf')\n",
126 | " moves = []\n",
127 | "\n",
128 | " for i, value in enumerate(values):\n",
129 | " if value > maximum:\n",
130 | " moves = [i]\n",
131 | " maximum = value\n",
132 | " elif value == maximum:\n",
133 | " moves.append(i)\n",
134 | "\n",
135 | " return moves"
136 | ],
137 | "metadata": {
138 | "id": "SBIJaIUV-ELw"
139 | },
140 | "execution_count": 161,
141 | "outputs": []
142 | },
143 | {
144 | "cell_type": "code",
145 | "source": [
146 | "def calculate_value_function(env, policy, gamma=.9):\n",
147 | " value_function = np.zeros((5, 5))\n",
148 | "\n",
149 | " for _ in range(50):\n",
150 | " for i in range(5):\n",
151 | " for j in range(5):\n",
152 | " temp = 0\n",
153 | " for a in env.moves:\n",
154 | " next_y, next_x, reward = env.predict_reward(i, j, a)\n",
155 | " temp += policy[i, j, a] * (reward + gamma * value_function[next_y, next_x])\n",
156 | " value_function[i, j] = temp\n",
157 | "\n",
158 | " return value_function"
159 | ],
160 | "metadata": {
161 | "id": "v4175Xl_1h84"
162 | },
163 | "execution_count": 134,
164 | "outputs": []
165 | },
166 | {
167 | "cell_type": "code",
168 | "source": [
169 | "def update_policy(value_function):\n",
170 | " new_policy = np.zeros((5, 5, 4))\n",
171 | "\n",
172 | " for i in range(5):\n",
173 | " for j in range(5):\n",
174 | " l = []\n",
175 | " for a in env.moves:\n",
176 | " new_y, new_x, _ = env.predict_reward(i, j, a)\n",
177 | " l.append(value_function[new_y, new_x])\n",
178 | " maximums = argmax(l)\n",
179 | "\n",
180 | " new_policy[i, j, maximums] = 1 / len(maximums)\n",
181 | "\n",
182 | " return new_policy"
183 | ],
184 | "metadata": {
185 | "id": "Vd9Wp36NAAfM"
186 | },
187 | "execution_count": 171,
188 | "outputs": []
189 | },
190 | {
191 | "cell_type": "code",
192 | "source": [
193 | "env = Environment()"
194 | ],
195 | "metadata": {
196 | "id": "AdXjN_rG1fVy"
197 | },
198 | "execution_count": 172,
199 | "outputs": []
200 | },
201 | {
202 | "cell_type": "code",
203 | "source": [
204 | "policy = np.ones((5, 5, 4)) * .25"
205 | ],
206 | "metadata": {
207 | "id": "XQdAZ2KQ8nn5"
208 | },
209 | "execution_count": 173,
210 | "outputs": []
211 | },
212 | {
213 | "cell_type": "code",
214 | "source": [
215 | "for _ in range(10):\n",
216 | " value_function = calculate_value_function(env, policy)\n",
217 | " policy = update_policy(value_function)"
218 | ],
219 | "metadata": {
220 | "id": "ZEUZexM15bAb"
221 | },
222 | "execution_count": 174,
223 | "outputs": []
224 | },
225 | {
226 | "cell_type": "code",
227 | "source": [
228 | "value_function # Q table"
229 | ],
230 | "metadata": {
231 | "colab": {
232 | "base_uri": "https://localhost:8080/"
233 | },
234 | "id": "Q1ey6vjm9Jgw",
235 | "outputId": "4072c658-1386-4fce-82e4-cb718f90e9a2"
236 | },
237 | "execution_count": 175,
238 | "outputs": [
239 | {
240 | "output_type": "execute_result",
241 | "data": {
242 | "text/plain": [
243 | "array([[21.97748529, 24.4194281 , 21.97748529, 19.4194281 , 17.47748529],\n",
244 | " [19.77973676, 21.97748529, 19.77973676, 17.80176308, 16.02158677],\n",
245 | " [17.80176308, 19.77973676, 17.80176308, 16.02158677, 14.4194281 ],\n",
246 | " [16.02158677, 17.80176308, 16.02158677, 14.4194281 , 12.97748529],\n",
247 | " [14.4194281 , 16.02158677, 14.4194281 , 12.97748529, 11.67973676]])"
248 | ]
249 | },
250 | "metadata": {},
251 | "execution_count": 175
252 | }
253 | ]
254 | },
255 | {
256 | "cell_type": "code",
257 | "source": [
258 | "moves = ['U', 'D', 'R', 'L']\n",
259 | "\n",
260 | "for i in range(5):\n",
261 | " print('|', end='')\n",
262 | " for j in range(5):\n",
263 | " for a in env.moves:\n",
264 | " if policy[i, j, a] != 0:\n",
265 | " print(moves[a], end='')\n",
266 | " else:\n",
267 | " print(' ', end='')\n",
268 | " print('|', end='')\n",
269 | " print('')"
270 | ],
271 | "metadata": {
272 | "colab": {
273 | "base_uri": "https://localhost:8080/"
274 | },
275 | "id": "N9X8m-LH9UfU",
276 | "outputId": "b619cb70-3ca9-4aef-d4c5-e60917e2ba90"
277 | },
278 | "execution_count": 181,
279 | "outputs": [
280 | {
281 | "output_type": "stream",
282 | "name": "stdout",
283 | "text": [
284 | "| R |UDRL| L|UDRL| L|\n",
285 | "| R |U |U L| L| L|\n",
286 | "| R |U |U L|U L|U L|\n",
287 | "| R |U |U L|U L|U L|\n",
288 | "| R |U |U L|U L|U L|\n"
289 | ]
290 | }
291 | ]
292 | },
293 | {
294 | "cell_type": "code",
295 | "source": [],
296 | "metadata": {
297 | "id": "OXFIubz3_IyX"
298 | },
299 | "execution_count": null,
300 | "outputs": []
301 | }
302 | ]
303 | }
--------------------------------------------------------------------------------
/24_Double_Deep_Q_Learning_1_gym_intro.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "authorship_tag": "ABX9TyM4+5u2E899RPT5eXzO/42D",
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | " "
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "source": [
32 | "!pip install -q pyvirtualdisplay\n",
33 | "!pip install -q swig\n",
34 | "!pip install -q gymnasium[all]"
35 | ],
36 | "metadata": {
37 | "colab": {
38 | "base_uri": "https://localhost:8080/"
39 | },
40 | "id": "OqttDVvk0LTA",
41 | "outputId": "5247d6e3-b297-47fd-efde-1fbf7f30090a"
42 | },
43 | "execution_count": 12,
44 | "outputs": [
45 | {
46 | "output_type": "stream",
47 | "name": "stdout",
48 | "text": [
49 | " Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
50 | " Building wheel for box2d-py (setup.py) ... \u001b[?25l\u001b[?25hdone\n"
51 | ]
52 | }
53 | ]
54 | },
55 | {
56 | "cell_type": "code",
57 | "execution_count": 117,
58 | "metadata": {
59 | "id": "ufYQ8d50z_6t"
60 | },
61 | "outputs": [],
62 | "source": [
63 | "import gymnasium as gym\n",
64 | "import numpy as np\n",
65 | "import matplotlib.pyplot as plt\n",
66 | "\n",
67 | "import random\n",
68 | "from collections import namedtuple, deque\n",
69 | "\n",
70 | "from IPython.display import clear_output"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "source": [
76 | "env = gym.make(\"LunarLander-v2\", render_mode=\"rgb_array\")"
77 | ],
78 | "metadata": {
79 | "id": "jNSDYwlI0HL4"
80 | },
81 | "execution_count": 28,
82 | "outputs": []
83 | },
84 | {
85 | "cell_type": "code",
86 | "source": [
87 | "observation, info = env.reset()"
88 | ],
89 | "metadata": {
90 | "id": "G8V5e4Lb0Zgj"
91 | },
92 | "execution_count": 29,
93 | "outputs": []
94 | },
95 | {
96 | "cell_type": "code",
97 | "source": [
98 | "observation"
99 | ],
100 | "metadata": {
101 | "colab": {
102 | "base_uri": "https://localhost:8080/"
103 | },
104 | "id": "Bg3ih6gk27ll",
105 | "outputId": "cf92c132-f634-4f83-9c72-c5b3df1e52cd"
106 | },
107 | "execution_count": 32,
108 | "outputs": [
109 | {
110 | "output_type": "execute_result",
111 | "data": {
112 | "text/plain": [
113 | "array([-0.00484533, 1.408985 , -0.4908019 , -0.08600599, 0.00562137,\n",
114 | " 0.11117391, 0. , 0. ], dtype=float32)"
115 | ]
116 | },
117 | "metadata": {},
118 | "execution_count": 32
119 | }
120 | ]
121 | },
122 | {
123 | "cell_type": "code",
124 | "source": [
125 | "env.action_space.sample()"
126 | ],
127 | "metadata": {
128 | "colab": {
129 | "base_uri": "https://localhost:8080/"
130 | },
131 | "id": "z5qq_0PW5YXC",
132 | "outputId": "ee96bf80-3dce-4141-8f79-4ac61bd0ce92"
133 | },
134 | "execution_count": 57,
135 | "outputs": [
136 | {
137 | "output_type": "execute_result",
138 | "data": {
139 | "text/plain": [
140 | "1"
141 | ]
142 | },
143 | "metadata": {},
144 | "execution_count": 57
145 | }
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "source": [
151 | "fig, axs = plt.subplots(1, 1, figsize=(5, 5))\n",
152 | "\n",
153 | "for _ in range(100):\n",
154 | " action = env.action_space.sample() # agent policy that uses the observation and info\n",
155 | " observation, reward, terminated, truncated, info = env.step(action)\n",
156 | "\n",
157 | " if terminated or truncated:\n",
158 | " observation, info = env.reset()\n",
159 | "\n",
160 | " axs.imshow(env.render())\n",
161 | " axs.axis('off')\n",
162 | " plt.pause(.01)\n",
163 | "\n",
164 | "env.close()"
165 | ],
166 | "metadata": {
167 | "colab": {
168 | "base_uri": "https://localhost:8080/",
169 | "height": 295
170 | },
171 | "id": "xKmBOW9_29UQ",
172 | "outputId": "e6851b6b-8cac-4260-ccef-88b47bc5a763"
173 | },
174 | "execution_count": 52,
175 | "outputs": [
176 | {
177 | "output_type": "display_data",
178 | "data": {
179 | "text/plain": [
180 | ""
181 | ],
182 | "image/png": "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\n"
183 | },
184 | "metadata": {}
185 | }
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "source": [
191 | "MemoryBlock = namedtuple('MemoryBlock', ('current', 'action', 'reward', 'next'))"
192 | ],
193 | "metadata": {
194 | "id": "CatEHV-C5Ard"
195 | },
196 | "execution_count": 62,
197 | "outputs": []
198 | },
199 | {
200 | "cell_type": "code",
201 | "source": [
202 | "block = MemoryBlock(1, 1, 2, 1)"
203 | ],
204 | "metadata": {
205 | "id": "awpIYsZg6Phm"
206 | },
207 | "execution_count": 64,
208 | "outputs": []
209 | },
210 | {
211 | "cell_type": "code",
212 | "source": [
213 | "block.action"
214 | ],
215 | "metadata": {
216 | "colab": {
217 | "base_uri": "https://localhost:8080/"
218 | },
219 | "id": "j0Xnvz_C6d9B",
220 | "outputId": "f2a5c582-9655-4fbb-95ee-39a561cecc76"
221 | },
222 | "execution_count": 68,
223 | "outputs": [
224 | {
225 | "output_type": "execute_result",
226 | "data": {
227 | "text/plain": [
228 | "1"
229 | ]
230 | },
231 | "metadata": {},
232 | "execution_count": 68
233 | }
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "source": [
239 | "memory = deque(maxlen=10)"
240 | ],
241 | "metadata": {
242 | "id": "LlcxJRes6gH4"
243 | },
244 | "execution_count": 80,
245 | "outputs": []
246 | },
247 | {
248 | "cell_type": "code",
249 | "source": [
250 | "memory"
251 | ],
252 | "metadata": {
253 | "colab": {
254 | "base_uri": "https://localhost:8080/"
255 | },
256 | "id": "SaUTuWou6r81",
257 | "outputId": "703aa9af-8471-4647-a8eb-4270d08266ee"
258 | },
259 | "execution_count": 81,
260 | "outputs": [
261 | {
262 | "output_type": "execute_result",
263 | "data": {
264 | "text/plain": [
265 | "deque([])"
266 | ]
267 | },
268 | "metadata": {},
269 | "execution_count": 81
270 | }
271 | ]
272 | },
273 | {
274 | "cell_type": "code",
275 | "source": [
276 | "memory.append(100)"
277 | ],
278 | "metadata": {
279 | "id": "fSD6S3pK61Dh"
280 | },
281 | "execution_count": 82,
282 | "outputs": []
283 | },
284 | {
285 | "cell_type": "code",
286 | "source": [
287 | "memory"
288 | ],
289 | "metadata": {
290 | "colab": {
291 | "base_uri": "https://localhost:8080/"
292 | },
293 | "id": "AX6uGERC62dL",
294 | "outputId": "f26a33f1-4838-45a3-a1b7-06cf638f1ab2"
295 | },
296 | "execution_count": 83,
297 | "outputs": [
298 | {
299 | "output_type": "execute_result",
300 | "data": {
301 | "text/plain": [
302 | "deque([100])"
303 | ]
304 | },
305 | "metadata": {},
306 | "execution_count": 83
307 | }
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "source": [
313 | "for i in range(10):\n",
314 | " memory.append(i)\n",
315 | " print(memory)"
316 | ],
317 | "metadata": {
318 | "colab": {
319 | "base_uri": "https://localhost:8080/"
320 | },
321 | "id": "W87WmNCE65fe",
322 | "outputId": "7f177f5b-a448-4fb4-b04d-aae531d306b2"
323 | },
324 | "execution_count": 84,
325 | "outputs": [
326 | {
327 | "output_type": "stream",
328 | "name": "stdout",
329 | "text": [
330 | "deque([100, 0], maxlen=10)\n",
331 | "deque([100, 0, 1], maxlen=10)\n",
332 | "deque([100, 0, 1, 2], maxlen=10)\n",
333 | "deque([100, 0, 1, 2, 3], maxlen=10)\n",
334 | "deque([100, 0, 1, 2, 3, 4], maxlen=10)\n",
335 | "deque([100, 0, 1, 2, 3, 4, 5], maxlen=10)\n",
336 | "deque([100, 0, 1, 2, 3, 4, 5, 6], maxlen=10)\n",
337 | "deque([100, 0, 1, 2, 3, 4, 5, 6, 7], maxlen=10)\n",
338 | "deque([100, 0, 1, 2, 3, 4, 5, 6, 7, 8], maxlen=10)\n",
339 | "deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], maxlen=10)\n"
340 | ]
341 | }
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "source": [
347 | "env = gym.make(\"LunarLander-v2\", render_mode=\"rgb_array\")\n",
348 | "observation, info = env.reset()\n",
349 | "\n",
350 | "memory = deque(maxlen=150)\n",
351 | "\n",
352 | "for _ in range(100):\n",
353 | " action = env.action_space.sample() # agent policy that uses the observation and info\n",
354 | "\n",
355 | " current = observation.copy()\n",
356 | " observation, reward, terminated, truncated, info = env.step(action)\n",
357 | " block = MemoryBlock(current, action, reward, observation)\n",
358 | " memory.append(block)\n",
359 | "\n",
360 | " if terminated or truncated:\n",
361 | " observation, info = env.reset()\n",
362 | "\n",
363 | "\n",
364 | "env.close()"
365 | ],
366 | "metadata": {
367 | "id": "V0EB3J8F6-GP"
368 | },
369 | "execution_count": 87,
370 | "outputs": []
371 | },
372 | {
373 | "cell_type": "code",
374 | "source": [
375 | "b1 = memory[0]\n",
376 | "b2 = memory[1]"
377 | ],
378 | "metadata": {
379 | "id": "Hd4Jcpkn7gS1"
380 | },
381 | "execution_count": 96,
382 | "outputs": []
383 | },
384 | {
385 | "cell_type": "code",
386 | "source": [
387 | "b1"
388 | ],
389 | "metadata": {
390 | "colab": {
391 | "base_uri": "https://localhost:8080/"
392 | },
393 | "id": "MKW7UpO87hYY",
394 | "outputId": "5338c33f-7b14-4bf1-94f7-3e09ae6dac7f"
395 | },
396 | "execution_count": 97,
397 | "outputs": [
398 | {
399 | "output_type": "execute_result",
400 | "data": {
401 | "text/plain": [
402 | "MemoryBlock(current=array([ 0.0032485 , 1.4054555 , 0.32901463, -0.24287517, -0.00375733,\n",
403 | " -0.07452664, 0. , 0. ], dtype=float32), action=0, reward=-1.3044605623392442, next=array([ 0.006497 , 1.3994141 , 0.32857022, -0.26852667, -0.00744009,\n",
404 | " -0.07366162, 0. , 0. ], dtype=float32))"
405 | ]
406 | },
407 | "metadata": {},
408 | "execution_count": 97
409 | }
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "source": [
415 | "b2"
416 | ],
417 | "metadata": {
418 | "colab": {
419 | "base_uri": "https://localhost:8080/"
420 | },
421 | "id": "FuteA5op788U",
422 | "outputId": "fdca541a-a4a7-47dd-e211-93400c3ce372"
423 | },
424 | "execution_count": 98,
425 | "outputs": [
426 | {
427 | "output_type": "execute_result",
428 | "data": {
429 | "text/plain": [
430 | "MemoryBlock(current=array([ 0.006497 , 1.3994141 , 0.32857022, -0.26852667, -0.00744009,\n",
431 | " -0.07366162, 0. , 0. ], dtype=float32), action=2, reward=-1.3291067603536988, next=array([ 0.00991163, 1.3933325 , 0.34438816, -0.2703012 , -0.01033648,\n",
432 | " -0.05793293, 0. , 0. ], dtype=float32))"
433 | ]
434 | },
435 | "metadata": {},
436 | "execution_count": 98
437 | }
438 | ]
439 | },
440 | {
441 | "cell_type": "code",
442 | "source": [
443 | "batch = MemoryBlock(*zip(*memory))"
444 | ],
445 | "metadata": {
446 | "id": "b0Z0mrcu79K8"
447 | },
448 | "execution_count": 115,
449 | "outputs": []
450 | },
451 | {
452 | "cell_type": "code",
453 | "source": [
454 | "batch.current"
455 | ],
456 | "metadata": {
457 | "colab": {
458 | "base_uri": "https://localhost:8080/"
459 | },
460 | "id": "t4YaNqJK8C4S",
461 | "outputId": "706880f1-a7d6-453e-f28e-3aa8917b9f99"
462 | },
463 | "execution_count": 116,
464 | "outputs": [
465 | {
466 | "output_type": "execute_result",
467 | "data": {
468 | "text/plain": [
469 | "(array([ 0.0032485 , 1.4054555 , 0.32901463, -0.24287517, -0.00375733,\n",
470 | " -0.07452664, 0. , 0. ], dtype=float32),\n",
471 | " array([ 0.006497 , 1.3994141 , 0.32857022, -0.26852667, -0.00744009,\n",
472 | " -0.07366162, 0. , 0. ], dtype=float32),\n",
473 | " array([ 0.00991163, 1.3933325 , 0.34438816, -0.2703012 , -0.01033648,\n",
474 | " -0.05793293, 0. , 0. ], dtype=float32),\n",
475 | " array([ 0.01323576, 1.3866549 , 0.33303937, -0.29678914, -0.01095505,\n",
476 | " -0.0123724 , 0. , 0. ], dtype=float32),\n",
477 | " array([ 0.01642313, 1.3809104 , 0.32008106, -0.25532517, -0.01228218,\n",
478 | " -0.02654489, 0. , 0. ], dtype=float32),\n",
479 | " array([ 0.0196105 , 1.3745655 , 0.32008517, -0.28200608, -0.01360798,\n",
480 | " -0.02651851, 0. , 0. ], dtype=float32),\n",
481 | " array([ 0.02286119, 1.3676276 , 0.32800844, -0.30837443, -0.01652008,\n",
482 | " -0.05824757, 0. , 0. ], dtype=float32),\n",
483 | " array([ 0.0260045 , 1.3614005 , 0.31786153, -0.27680793, -0.0200112 ,\n",
484 | " -0.06982894, 0. , 0. ], dtype=float32),\n",
485 | " array([ 0.02913609, 1.3556799 , 0.31680828, -0.25429958, -0.02362819,\n",
486 | " -0.07234631, 0. , 0. ], dtype=float32),\n",
487 | " array([ 0.03228216, 1.350129 , 0.3182506 , -0.24676459, -0.02723356,\n",
488 | " -0.07211356, 0. , 0. ], dtype=float32),\n",
489 | " array([ 0.03551693, 1.3439851 , 0.32936293, -0.2731835 , -0.03306038,\n",
490 | " -0.11654727, 0. , 0. ], dtype=float32),\n",
491 | " array([ 0.03875179, 1.3372415 , 0.32938066, -0.29985175, -0.03888537,\n",
492 | " -0.11651033, 0. , 0. ], dtype=float32),\n",
493 | " array([ 0.04192553, 1.3298929 , 0.3217017 , -0.32672888, -0.04317166,\n",
494 | " -0.08573384, 0. , 0. ], dtype=float32),\n",
495 | " array([ 0.04518175, 1.3219506 , 0.33203125, -0.353187 , -0.04952039,\n",
496 | " -0.12698598, 0. , 0. ], dtype=float32),\n",
497 | " array([ 0.04841232, 1.314907 , 0.32982442, -0.31328657, -0.05622081,\n",
498 | " -0.13402088, 0. , 0. ], dtype=float32),\n",
499 | " array([ 0.05172186, 1.3072615 , 0.33972174, -0.34014696, -0.06490061,\n",
500 | " -0.17361203, 0. , 0. ], dtype=float32),\n",
501 | " array([ 0.05503168, 1.2990172 , 0.33974722, -0.36681646, -0.07357845,\n",
502 | " -0.17357238, 0. , 0. ], dtype=float32),\n",
503 | " array([ 0.05834246, 1.2912889 , 0.3400916 , -0.34394732, -0.08250807,\n",
504 | " -0.17860876, 0. , 0. ], dtype=float32),\n",
505 | " array([ 0.06172209, 1.2829638 , 0.34867343, -0.37062198, -0.09314454,\n",
506 | " -0.21274868, 0. , 0. ], dtype=float32),\n",
507 | " array([ 0.06502628, 1.2740395 , 0.33922154, -0.39720652, -0.10188421,\n",
508 | " -0.17480874, 0. , 0. ], dtype=float32),\n",
509 | " array([ 0.06852102, 1.2659017 , 0.35781997, -0.36226854, -0.11017855,\n",
510 | " -0.1659019 , 0. , 0. ], dtype=float32),\n",
511 | " array([ 0.07213764, 1.2581213 , 0.3697724 , -0.34640688, -0.11823454,\n",
512 | " -0.16113424, 0. , 0. ], dtype=float32),\n",
513 | " array([ 0.07599831, 1.250621 , 0.39334607, -0.33393574, -0.1254857 ,\n",
514 | " -0.14503631, 0. , 0. ], dtype=float32),\n",
515 | " array([ 0.07978897, 1.2425411 , 0.3845337 , -0.35957322, -0.13093206,\n",
516 | " -0.10893674, 0. , 0. ], dtype=float32),\n",
517 | " array([ 0.08357992, 1.2338617 , 0.38454834, -0.38624236, -0.136378 ,\n",
518 | " -0.10892855, 0. , 0. ], dtype=float32),\n",
519 | " array([ 0.08736897, 1.2245612 , 0.3843667 , -0.41385975, -0.14182337,\n",
520 | " -0.10890688, 0. , 0. ], dtype=float32),\n",
521 | " array([ 0.09117527, 1.2154578 , 0.3863613 , -0.4051519 , -0.14753653,\n",
522 | " -0.11426322, 0. , 0. ], dtype=float32),\n",
523 | " array([ 0.09506798, 1.2057257 , 0.39723632, -0.43334863, -0.15548898,\n",
524 | " -0.15904924, 0. , 0. ], dtype=float32),\n",
525 | " array([ 0.09896078, 1.1953943 , 0.39723513, -0.4600205 , -0.16344142,\n",
526 | " -0.15904859, 0. , 0. ], dtype=float32),\n",
527 | " array([ 0.10305023, 1.1857693 , 0.41663918, -0.42865118, -0.1711515 ,\n",
528 | " -0.15420182, 0. , 0. ], dtype=float32),\n",
529 | " array([ 0.10713968, 1.1755449 , 0.41663796, -0.45532274, -0.17886156,\n",
530 | " -0.15420106, 0. , 0. ], dtype=float32),\n",
531 | " array([ 0.11116524, 1.1647334 , 0.40861574, -0.4812524 , -0.18494107,\n",
532 | " -0.12159048, 0. , 0. ], dtype=float32),\n",
533 | " array([ 0.1151638 , 1.1540335 , 0.40642828, -0.47639313, -0.19154665,\n",
534 | " -0.13211167, 0. , 0. ], dtype=float32),\n",
535 | " array([ 0.11916237, 1.1427339 , 0.4064273 , -0.50306344, -0.19815221,\n",
536 | " -0.13211125, 0. , 0. ], dtype=float32),\n",
537 | " array([ 0.12323084, 1.1308116 , 0.41521496, -0.53102475, -0.20657948,\n",
538 | " -0.16854541, 0. , 0. ], dtype=float32),\n",
539 | " array([ 0.12759057, 1.1193523 , 0.44367886, -0.5104016 , -0.21436031,\n",
540 | " -0.15561649, 0. , 0. ], dtype=float32),\n",
541 | " array([ 0.1321722 , 1.1080383 , 0.46535143, -0.50390726, -0.22162652,\n",
542 | " -0.1453242 , 0. , 0. ], dtype=float32),\n",
543 | " array([ 0.13710518, 1.0973196 , 0.49971023, -0.4773649 , -0.2281169 ,\n",
544 | " -0.1298075 , 0. , 0. ], dtype=float32),\n",
545 | " array([ 0.14234333, 1.086952 , 0.52950966, -0.46167386, -0.23389536,\n",
546 | " -0.11556929, 0. , 0. ], dtype=float32),\n",
547 | " array([ 0.14751807, 1.0759965 , 0.52158654, -0.4875675 , -0.23806275,\n",
548 | " -0.08334794, 0. , 0. ], dtype=float32),\n",
549 | " array([ 0.15269288, 1.0644413 , 0.52158606, -0.51423556, -0.24223015,\n",
550 | " -0.08334783, 0. , 0. ], dtype=float32),\n",
551 | " array([ 0.15786782, 1.0522863 , 0.5215855 , -0.5409037 , -0.24639754,\n",
552 | " -0.08334772, 0. , 0. ], dtype=float32),\n",
553 | " array([ 0.16310024, 1.0408137 , 0.52803177, -0.5107082 , -0.25127062,\n",
554 | " -0.09746158, 0. , 0. ], dtype=float32),\n",
555 | " array([ 0.16864958, 1.029617 , 0.5589772 , -0.49832523, -0.25539538,\n",
556 | " -0.08249549, 0. , 0. ], dtype=float32),\n",
557 | " array([ 0.17437668, 1.019299 , 0.57709444, -0.45934814, -0.259876 ,\n",
558 | " -0.08961239, 0. , 0. ], dtype=float32),\n",
559 | " array([ 0.18010378, 1.0083812 , 0.5770937 , -0.48601642, -0.2643566 ,\n",
560 | " -0.08961224, 0. , 0. ], dtype=float32),\n",
561 | " array([ 0.1859231 , 0.99682903, 0.588689 , -0.5146646 , -0.2712742 ,\n",
562 | " -0.1383522 , 0. , 0. ], dtype=float32),\n",
563 | " array([ 0.19174251, 0.98467755, 0.5886875 , -0.5413351 , -0.2781918 ,\n",
564 | " -0.13835177, 0. , 0. ], dtype=float32),\n",
565 | " array([ 0.19747925, 0.9719698 , 0.5782013 , -0.5656596 , -0.2828468 ,\n",
566 | " -0.09309985, 0. , 0. ], dtype=float32),\n",
567 | " array([ 0.20321599, 0.9586623 , 0.5782005 , -0.592328 , -0.28750178,\n",
568 | " -0.09309975, 0. , 0. ], dtype=float32),\n",
569 | " array([ 0.20902376, 0.9447341 , 0.5870816 , -0.62028587, -0.29400042,\n",
570 | " -0.12997194, 0. , 0. ], dtype=float32),\n",
571 | " array([ 0.21475688, 0.9302393 , 0.57767045, -0.6450995 , -0.2984922 ,\n",
572 | " -0.08983554, 0. , 0. ], dtype=float32),\n",
573 | " array([ 0.22040614, 0.9151806 , 0.56708866, -0.6697237 , -0.3007316 ,\n",
574 | " -0.04478817, 0. , 0. ], dtype=float32),\n",
575 | " array([ 0.22598 , 0.89956385, 0.5575346 , -0.69411033, -0.30088818,\n",
576 | " -0.00313152, 0. , 0. ], dtype=float32),\n",
577 | " array([ 0.23146506, 0.8833899 , 0.54632086, -0.7183911 , -0.2986327 ,\n",
578 | " 0.0451091 , 0. , 0. ], dtype=float32),\n",
579 | " array([ 0.23701553, 0.866591 , 0.5545404 , -0.7465191 , -0.2981128 ,\n",
580 | " 0.01039831, 0. , 0. ], dtype=float32),\n",
581 | " array([ 0.24256602, 0.84919196, 0.5545404 , -0.77318585, -0.29759288,\n",
582 | " 0.01039837, 0. , 0. ], dtype=float32),\n",
583 | " array([ 0.24834327, 0.8317434 , 0.5767339 , -0.77528656, -0.29656732,\n",
584 | " 0.02051135, 0. , 0. ], dtype=float32),\n",
585 | " array([ 0.25418806, 0.8136553 , 0.5852955 , -0.80408293, -0.29741687,\n",
586 | " -0.01699063, 0. , 0. ], dtype=float32),\n",
587 | " array([ 0.26003274, 0.7949673 , 0.5852954 , -0.83074963, -0.2982664 ,\n",
588 | " -0.01699061, 0. , 0. ], dtype=float32),\n",
589 | " array([ 0.26631337, 0.77691966, 0.62809825, -0.80212414, -0.2983126 ,\n",
590 | " -0.00092363, 0. , 0. ], dtype=float32),\n",
591 | " array([ 0.2725939 , 0.7582721 , 0.62809837, -0.82879084, -0.2983588 ,\n",
592 | " -0.00092367, 0. , 0. ], dtype=float32),\n",
593 | " array([ 2.7907389e-01, 7.3992133e-01, 6.4797944e-01, -8.1558305e-01,\n",
594 | " -2.9833561e-01, 4.6390909e-04, 0.0000000e+00, 0.0000000e+00],\n",
595 | " dtype=float32),\n",
596 | " array([ 0.28546923, 0.7210037 , 0.63733035, -0.8403326 , -0.29606122,\n",
597 | " 0.04548761, 0. , 0. ], dtype=float32),\n",
598 | " array([ 0.29180604, 0.70152026, 0.6298959 , -0.8651683 , -0.29216075,\n",
599 | " 0.07800949, 0. , 0. ], dtype=float32),\n",
600 | " array([ 0.29806557, 0.6814782 , 0.6201067 , -0.8896006 , -0.2861396 ,\n",
601 | " 0.12042297, 0. , 0. ], dtype=float32),\n",
602 | " array([ 0.304393 , 0.66080976, 0.62864447, -0.917799 , -0.28192195,\n",
603 | " 0.08435254, 0. , 0. ], dtype=float32),\n",
604 | " array([ 0.31065854, 0.63955736, 0.62088794, -0.9434684 , -0.27610767,\n",
605 | " 0.11628503, 0. , 0. ], dtype=float32),\n",
606 | " array([ 0.31683215, 0.6177396 , 0.60932267, -0.96817976, -0.26786372,\n",
607 | " 0.16487893, 0. , 0. ], dtype=float32),\n",
608 | " array([ 0.32300606, 0.5953227 , 0.60932034, -0.9948518 , -0.2596198 ,\n",
609 | " 0.16487816, 0. , 0. ], dtype=float32),\n",
610 | " array([ 0.32926998, 0.5733222 , 0.61870646, -0.9764615 , -0.25177723,\n",
611 | " 0.1568514 , 0. , 0. ], dtype=float32),\n",
612 | " array([ 0.335534 , 0.5507224 , 0.6187045 , -1.0031332 , -0.24393468,\n",
613 | " 0.15685079, 0. , 0. ], dtype=float32),\n",
614 | " array([ 0.34193307, 0.5280501 , 0.63197047, -1.0063579 , -0.23587935,\n",
615 | " 0.16110703, 0. , 0. ], dtype=float32),\n",
616 | " array([ 0.3483321 , 0.5047788 , 0.6319685 , -1.0330298 , -0.22782403,\n",
617 | " 0.16110618, 0. , 0. ], dtype=float32),\n",
618 | " array([ 0.35482207, 0.4808718 , 0.6434083 , -1.061682 , -0.22217 ,\n",
619 | " 0.11308068, 0. , 0. ], dtype=float32),\n",
620 | " array([ 0.36123332, 0.45639145, 0.63350135, -1.0868869 , -0.21445887,\n",
621 | " 0.1542222 , 0. , 0. ], dtype=float32),\n",
622 | " array([ 0.36755657, 0.4313467 , 0.6223889 , -1.1116874 , -0.2044231 ,\n",
623 | " 0.20071515, 0. , 0. ], dtype=float32),\n",
624 | " array([ 0.3738801 , 0.4057033 , 0.62238616, -1.1383624 , -0.1943874 ,\n",
625 | " 0.20071383, 0. , 0. ], dtype=float32),\n",
626 | " array([ 0.3802759 , 0.37943146, 0.63148636, -1.1665958 , -0.18625432,\n",
627 | " 0.16266184, 0. , 0. ], dtype=float32),\n",
628 | " array([ 0.3866108 , 0.35258853, 0.6237731 , -1.1918262 , -0.17650253,\n",
629 | " 0.19503552, 0. , 0. ], dtype=float32),\n",
630 | " array([ 0.3928669 , 0.32515943, 0.6138825 , -1.2177227 , -0.1647498 ,\n",
631 | " 0.23505464, 0. , 0. ], dtype=float32),\n",
632 | " array([ 0.39912328, 0.29713205, 0.6138795 , -1.2444009 , -0.15299718,\n",
633 | " 0.23505235, 0. , 0. ], dtype=float32),\n",
634 | " array([ 0.40555716, 0.26928914, 0.63117206, -1.23625 , -0.14080116,\n",
635 | " 0.24392083, 0. , 0. ], dtype=float32),\n",
636 | " array([ 0.41192016, 0.24086352, 0.62222606, -1.262094 , -0.12678766,\n",
637 | " 0.28026995, 0. , 0. ], dtype=float32),\n",
638 | " array([ 0.4183545 , 0.2118345 , 0.63115126, -1.2891777 , -0.11456715,\n",
639 | " 0.24441049, 0. , 0. ], dtype=float32),\n",
640 | " array([ 0.42478913, 0.18220748, 0.63114893, -1.3158567 , -0.10234676,\n",
641 | " 0.24440798, 0. , 0. ], dtype=float32),\n",
642 | " array([ 0.43113318, 0.15199342, 0.6197608 , -1.3419081 , -0.08783399,\n",
643 | " 0.29025573, 0. , 0. ], dtype=float32),\n",
644 | " array([ 0.43754464, 0.12116834, 0.6282196 , -1.369294 , -0.07503272,\n",
645 | " 0.25602564, 0. , 0. ], dtype=float32),\n",
646 | " array([ 0.44387072, 0.08976682, 0.6174868 , -1.3949317 , -0.06005894,\n",
647 | " 0.2994754 , 0. , 0. ], dtype=float32),\n",
648 | " array([ 0.45019692, 0.05776836, 0.6174848 , -1.4216172 , -0.04508539,\n",
649 | " 0.29947075, 0. , 0. ], dtype=float32),\n",
650 | " array([ 0.45643815, 0.0251823 , 0.60678774, -1.4478359 , -0.02796434,\n",
651 | " 0.34242067, 0. , 0. ], dtype=float32),\n",
652 | " array([ 0.46254796, -0.00653446, 0.5943854 , -1.4094068 , -0.01157715,\n",
653 | " 0.3277441 , 0. , 0. ], dtype=float32),\n",
654 | " array([ 0.46856374, -0.03884045, 0.5825814 , -1.4357822 , 0.00717474,\n",
655 | " 0.37503785, 1. , 0. ], dtype=float32),\n",
656 | " array([ 0.47394055, -0.07029414, 0.5007308 , -1.398636 , 0.03890656,\n",
657 | " 0.62863874, 1. , 0. ], dtype=float32),\n",
658 | " array([ 6.3772203e-04, 1.4035777e+00, 6.4582005e-02, -3.2633755e-01,\n",
659 | " -7.3219155e-04, -1.4628743e-02, 0.0000000e+00, 0.0000000e+00],\n",
660 | " dtype=float32),\n",
661 | " array([ 1.2557984e-03, 1.3968295e+00, 6.2634937e-02, -2.9991859e-01,\n",
662 | " -1.5520940e-03, -1.6398780e-02, 0.0000000e+00, 0.0000000e+00],\n",
663 | " dtype=float32),\n",
664 | " array([ 2.0483017e-03, 1.3907650e+00, 7.9237178e-02, -2.6953679e-01,\n",
665 | " -1.5398865e-03, 2.4391804e-04, 0.0000000e+00, 0.0000000e+00],\n",
666 | " dtype=float32),\n",
667 | " array([ 2.8409003e-03, 1.3841002e+00, 7.9236843e-02, -2.9621407e-01,\n",
668 | " -1.5283929e-03, 2.3040108e-04, 0.0000000e+00, 0.0000000e+00],\n",
669 | " dtype=float32),\n",
670 | " array([ 0.00369711, 1.3768382 , 0.08724354, -0.3227533 , -0.00312197,\n",
671 | " -0.03187469, 0. , 0. ], dtype=float32),\n",
672 | " array([ 0.00447617, 1.3689772 , 0.0775428 , -0.3493837 , -0.00276848,\n",
673 | " 0.00707043, 0. , 0. ], dtype=float32))"
674 | ]
675 | },
676 | "metadata": {},
677 | "execution_count": 116
678 | }
679 | ]
680 | },
681 | {
682 | "cell_type": "code",
683 | "source": [
684 | "s = random.sample(memory, 10)\n",
685 | "batch = MemoryBlock(*zip(*s))"
686 | ],
687 | "metadata": {
688 | "id": "dkcpe-Qw9E2X"
689 | },
690 | "execution_count": 119,
691 | "outputs": []
692 | },
693 | {
694 | "cell_type": "code",
695 | "source": [
696 | "batch.reward"
697 | ],
698 | "metadata": {
699 | "colab": {
700 | "base_uri": "https://localhost:8080/"
701 | },
702 | "id": "Z2dSnIvO9P62",
703 | "outputId": "93da11b9-a8a7-4090-8862-dbf46a493ace"
704 | },
705 | "execution_count": 120,
706 | "outputs": [
707 | {
708 | "output_type": "execute_result",
709 | "data": {
710 | "text/plain": [
711 | "(0.7480714012465353,\n",
712 | " -0.6803533446248753,\n",
713 | " 3.16454145519175,\n",
714 | " -0.4614322955537659,\n",
715 | " -1.2174461058552595,\n",
716 | " 0.24074994760946994,\n",
717 | " -0.9185988699621135,\n",
718 | " -0.9376932553099369,\n",
719 | " -0.575740884578579,\n",
720 | " -0.37997100287804986)"
721 | ]
722 | },
723 | "metadata": {},
724 | "execution_count": 120
725 | }
726 | ]
727 | },
728 | {
729 | "cell_type": "code",
730 | "source": [],
731 | "metadata": {
732 | "id": "Ej2l8P2R9U3E"
733 | },
734 | "execution_count": null,
735 | "outputs": []
736 | }
737 | ]
738 | }
--------------------------------------------------------------------------------
/25_Double_Deep_Q_Learning_2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "gpuType": "T4",
8 | "authorship_tag": "ABX9TyO5oExkA5B4ZMegA5eJNX6v",
9 | "include_colab_link": true
10 | },
11 | "kernelspec": {
12 | "name": "python3",
13 | "display_name": "Python 3"
14 | },
15 | "language_info": {
16 | "name": "python"
17 | },
18 | "accelerator": "GPU"
19 | },
20 | "cells": [
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {
24 | "id": "view-in-github",
25 | "colab_type": "text"
26 | },
27 | "source": [
28 | " "
29 | ]
30 | },
31 | {
32 | "cell_type": "markdown",
33 | "source": [
34 | "Main source: https://pytorch.org/tutorials/intermediate/reinforcement_q_learning.html"
35 | ],
36 | "metadata": {
37 | "id": "e2c9wneh2jNf"
38 | }
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 1,
43 | "metadata": {
44 | "colab": {
45 | "base_uri": "https://localhost:8080/"
46 | },
47 | "id": "kMrwaCQ804lM",
48 | "outputId": "51b22a64-3639-4925-b883-7affe72d375f"
49 | },
50 | "outputs": [
51 | {
52 | "output_type": "stream",
53 | "name": "stdout",
54 | "text": [
55 | "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m953.9/953.9 kB\u001b[0m \u001b[31m4.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
56 | "\u001b[?25h"
57 | ]
58 | }
59 | ],
60 | "source": [
61 | "!pip install -q gymnasium[classic_control]"
62 | ]
63 | },
64 | {
65 | "cell_type": "code",
66 | "source": [
67 | "import math\n",
68 | "import random\n",
69 | "from collections import namedtuple, deque\n",
70 | "from itertools import count\n",
71 | "\n",
72 | "import gymnasium as gym\n",
73 | "\n",
74 | "import torch\n",
75 | "import torch.nn as nn\n",
76 | "import torch.nn.functional as F\n",
77 | "import torch.optim as optim\n",
78 | "\n",
79 | "from IPython import display\n",
80 | "\n",
81 | "import numpy as np\n",
82 | "import matplotlib.pyplot as plt"
83 | ],
84 | "metadata": {
85 | "id": "S-VcJSlJ2hM3"
86 | },
87 | "execution_count": 2,
88 | "outputs": []
89 | },
90 | {
91 | "cell_type": "code",
92 | "source": [
93 | "env = gym.make('CartPole-v1')"
94 | ],
95 | "metadata": {
96 | "id": "d4JAWIO23I6V"
97 | },
98 | "execution_count": 3,
99 | "outputs": []
100 | },
101 | {
102 | "cell_type": "code",
103 | "source": [
104 | "BATCH_SIZE = 128\n",
105 | "NUM_EPISODES = 600\n",
106 | "\n",
107 | "GAMMA = .99 # Discount factor\n",
108 | "\n",
109 | "# epsilon-greedy parameters:\n",
110 | "EPS_START = .9\n",
111 | "EPS_END = .05\n",
112 | "EPS_DECAY = 1000\n",
113 | "\n",
114 | "TAU = 5e-3\n",
115 | "\n",
116 | "LR = 1e-4\n",
117 | "CLIP_VALUE = 100\n",
118 | "\n",
119 | "MEMORY_SIZE = 10000\n",
120 | "\n",
121 | "DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'"
122 | ],
123 | "metadata": {
124 | "id": "-tf9lVbc3CsC"
125 | },
126 | "execution_count": 4,
127 | "outputs": []
128 | },
129 | {
130 | "cell_type": "code",
131 | "source": [
132 | "state, info = env.reset()\n",
133 | "N_OBSERVATIONS = len(state)\n",
134 | "N_ACTIONS = env.action_space.n"
135 | ],
136 | "metadata": {
137 | "id": "7LuXu5sU5qGW"
138 | },
139 | "execution_count": 5,
140 | "outputs": []
141 | },
142 | {
143 | "cell_type": "code",
144 | "source": [
145 | "plt.ion()"
146 | ],
147 | "metadata": {
148 | "colab": {
149 | "base_uri": "https://localhost:8080/"
150 | },
151 | "id": "9Py_Q-6j3M9n",
152 | "outputId": "f3bfeeed-f12b-44b3-fa5b-f7dc89c5af2c"
153 | },
154 | "execution_count": 6,
155 | "outputs": [
156 | {
157 | "output_type": "execute_result",
158 | "data": {
159 | "text/plain": [
160 | ""
161 | ]
162 | },
163 | "metadata": {},
164 | "execution_count": 6
165 | }
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "source": [
171 | "MemoryBlock = namedtuple('MemoryBlock', ('state', 'action', 'reward', 'next_state'))\n",
172 | "\n",
173 | "class ReplayMemory:\n",
174 | " def __init__(self, capacity):\n",
175 | " self.memory = deque(maxlen=capacity)\n",
176 | "\n",
177 | " def __len__(self):\n",
178 | " return len(self.memory)\n",
179 | "\n",
180 | " def push(self, state, action, reward, next_state):\n",
181 | " block = MemoryBlock(state, action, reward, next_state)\n",
182 | " self.memory.append(block)\n",
183 | "\n",
184 | " def sample(self, batch_size):\n",
185 | " return random.sample(self.memory, batch_size)"
186 | ],
187 | "metadata": {
188 | "id": "A-qtTzAV3ZY8"
189 | },
190 | "execution_count": 7,
191 | "outputs": []
192 | },
193 | {
194 | "cell_type": "code",
195 | "source": [
196 | "class PolicyNetwork(nn.Module):\n",
197 | " def __init__(self, n_observations, n_actions, latent_dim=128):\n",
198 | " super().__init__()\n",
199 | "\n",
200 | " self.layers = nn.Sequential(\n",
201 | " nn.Linear(n_observations, latent_dim),\n",
202 | " nn.ReLU(),\n",
203 | " nn.Linear(latent_dim, latent_dim),\n",
204 | " nn.ReLU(),\n",
205 | " nn.Linear(latent_dim, n_actions)\n",
206 | " )\n",
207 | "\n",
208 | " def forward(self, x):\n",
209 | " return self.layers(x)"
210 | ],
211 | "metadata": {
212 | "id": "3EQxRKlX4gPh"
213 | },
214 | "execution_count": 8,
215 | "outputs": []
216 | },
217 | {
218 | "cell_type": "code",
219 | "source": [
220 | "policy_net = PolicyNetwork(N_OBSERVATIONS, N_ACTIONS).to(DEVICE)\n",
221 | "target_net = PolicyNetwork(N_OBSERVATIONS, N_ACTIONS).to(DEVICE)\n",
222 | "\n",
223 | "target_net.load_state_dict(policy_net.state_dict())"
224 | ],
225 | "metadata": {
226 | "colab": {
227 | "base_uri": "https://localhost:8080/"
228 | },
229 | "id": "y3MogvRV5MmR",
230 | "outputId": "e3742ebb-08ad-4d5d-cb64-c9a0333e7f68"
231 | },
232 | "execution_count": 9,
233 | "outputs": [
234 | {
235 | "output_type": "execute_result",
236 | "data": {
237 | "text/plain": [
238 | ""
239 | ]
240 | },
241 | "metadata": {},
242 | "execution_count": 9
243 | }
244 | ]
245 | },
246 | {
247 | "cell_type": "code",
248 | "source": [
249 | "optimizer = optim.AdamW(policy_net.parameters(), lr=LR, amsgrad=True)\n",
250 | "criterion = nn.SmoothL1Loss()"
251 | ],
252 | "metadata": {
253 | "id": "vZTxKNpG6IAT"
254 | },
255 | "execution_count": 10,
256 | "outputs": []
257 | },
258 | {
259 | "cell_type": "code",
260 | "source": [
261 | "memory = ReplayMemory(MEMORY_SIZE)"
262 | ],
263 | "metadata": {
264 | "id": "qK5Uinxk6Uxp"
265 | },
266 | "execution_count": 11,
267 | "outputs": []
268 | },
269 | {
270 | "cell_type": "code",
271 | "source": [
272 | "x = np.array(range(6000))\n",
273 | "\n",
274 | "eps = EPS_END + (EPS_START - EPS_END) * np.exp(-1 * x / EPS_DECAY)\n",
275 | "\n",
276 | "plt.plot(x, eps)\n",
277 | "plt.show()"
278 | ],
279 | "metadata": {
280 | "colab": {
281 | "base_uri": "https://localhost:8080/",
282 | "height": 430
283 | },
284 | "id": "ln4qZVoT7Dhi",
285 | "outputId": "66003bd4-5de0-453c-dff1-5f7174cb12f3"
286 | },
287 | "execution_count": 12,
288 | "outputs": [
289 | {
290 | "output_type": "display_data",
291 | "data": {
292 | "text/plain": [
293 | ""
294 | ],
295 | "image/png": "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Ustncblcio2NbdP2+P46U1+cqo3X69Xhw4e74uN0ic2bNysyMlJut1t33nmnXn31VY0aNYp+OonFixdr3bp1mj9//gn76K+2srKy9Mwzz2jJkiV67LHHtGfPHk2dOlXV1dX01XHy8/P12GOPadiwYXr33Xd111136Yc//KGeffZZScH/HR8Sd+0FrDR79mxt2bJFH330kdWlBK0RI0Zow4YNqqqq0ssvv6zbbrtNK1assLqsoFNYWKi7775bS5culcfjsbqcoHfllVcGfh43bpyysrKUnp6uf/7znwoPD7ewsuDj9/s1ceJEPfjgg5Kk888/X1u2bNHjjz+u2267zeLqzqxXnhlJTEyUw+E4YdR1cXGxUlJSLKrKWkc+9+n6JCUlRSUlJW32Nzc3q6Kiok2bk73Gse8RSn7wgx/ozTff1AcffKABAwYEtqekpKixsVGVlZVt2h/fX2fqi1O1iY6ODqkvW5fLpaFDhyozM1Pz58/X+PHj9cc//pF+Ok5eXp5KSkp0wQUXyOl0yul0asWKFfrTn/4kp9Op5ORk+us0YmNjNXz4cO3atYt/W8dJTU3VqFGj2mw777zzApe1gv07vleGEZfLpczMTC1btiywze/3a9myZcrOzrawMusMGjRIKSkpbfrE6/Vq9erVgT7Jzs5WZWWl8vLyAm3ef/99+f1+ZWVlBdp8+OGHampqCrRZunSpRowYobi4uG76NOfOGKMf/OAHevXVV/X+++9r0KBBbfZnZmYqLCysTX9t375dBQUFbfpr8+bNbf7PvXTpUkVHRwe+NLKzs9u8xpE2of7v0O/3q6GhgX46zuWXX67Nmzdrw4YNgcfEiRN18803B36mv06tpqZGu3fvVmpqKv+2jjNlypQTlh/YsWOH0tPTJYXAd/w5DX8NYYsXLzZut9s888wzZuvWreZ73/ueiY2NbTPquqeprq4269evN+vXrzeSzKOPPmrWr19v9u3bZ4xpmfYVGxtrXn/9dbNp0yZz3XXXnXTa1/nnn29Wr15tPvroIzNs2LA2074qKytNcnKyueWWW8yWLVvM4sWLTURERMhN7b3rrrtMTEyMWb58eZtphXV1dYE2d955pxk4cKB5//33zdq1a012drbJzs4O7D8yrXDatGlmw4YNZsmSJaZv374nnVb4s5/9zGzbts0sWLAg5KYV3nvvvWbFihVmz549ZtOmTebee+81NpvNvPfee8YY+ulMjp1NYwz9dayf/OQnZvny5WbPnj3m448/Njk5OSYxMdGUlJQYY+irY61Zs8Y4nU7zu9/9zuzcudP84x//MBEREea5554LtAnm7/heG0aMMebPf/6zGThwoHG5XGby5Mlm1apVVpfUpT744AMj6YTHbbfdZoxpmfp1//33m+TkZON2u83ll19utm/f3uY1ysvLzY033mgiIyNNdHS0mTlzpqmurm7TZuPGjebiiy82brfb9O/f3zz00EPd9RE7zcn6SZJ5+umnA20OHz5s/v3f/93ExcWZiIgI87Wvfc0cPHiwzevs3bvXXHnllSY8PNwkJiaan/zkJ6apqalNmw8++MBMmDDBuFwuM3jw4DbvEQq+853vmPT0dONyuUzfvn3N5ZdfHggixtBPZ3J8GKG/jpoxY4ZJTU01LpfL9O/f38yYMaPNuhn0VVv/+te/zJgxY4zb7TYjR440TzzxRJv9wfwdbzPGmLM/rwIAAHBueuWYEQAAEDwIIwAAwFKEEQAAYCnCCAAAsBRhBAAAWIowAgAALEUYAQAAliKMAAAASxFGAACApQgjAADAUoQRAABgKcIIAACw1P8HR3mojIhz5dAAAAAASUVORK5CYII=\n"
296 | },
297 | "metadata": {}
298 | }
299 | ]
300 | },
301 | {
302 | "cell_type": "code",
303 | "source": [
304 | "steps_done = 0\n",
305 | "\n",
306 | "def select_action(state):\n",
307 | " global steps_done\n",
308 | "\n",
309 | " eps = EPS_END + (EPS_START - EPS_END) * math.exp(-1 * steps_done / EPS_DECAY)\n",
310 | " steps_done += 1\n",
311 | "\n",
312 | " if random.random() > eps:\n",
313 | " with torch.no_grad():\n",
314 | " action = policy_net(state).max(1).indices.view(1, 1)\n",
315 | " else:\n",
316 | " action = torch.tensor([[env.action_space.sample()]], device=DEVICE, dtype=torch.long)\n",
317 | "\n",
318 | " return action"
319 | ],
320 | "metadata": {
321 | "id": "YijGFqvN6b6E"
322 | },
323 | "execution_count": 13,
324 | "outputs": []
325 | },
326 | {
327 | "cell_type": "code",
328 | "source": [
329 | "def optimize_model():\n",
330 | " if len(memory) < BATCH_SIZE:\n",
331 | " return\n",
332 | "\n",
333 | " optimizer.zero_grad()\n",
334 | "\n",
335 | " history = memory.sample(BATCH_SIZE)\n",
336 | " batch = MemoryBlock(*zip(*history))\n",
337 | "\n",
338 | " state_batch = torch.cat(batch.state)\n",
339 | " action_batch = torch.cat(batch.action)\n",
340 | " reward_batch = torch.cat(batch.reward)\n",
341 | "\n",
342 | " state_action_values = policy_net(state_batch).gather(1, action_batch)\n",
343 | "\n",
344 | " non_final_mask = torch.tensor(tuple(map(lambda s: s is not None, batch.next_state)), device=DEVICE, dtype=torch.bool)\n",
345 | " non_final_next_state = torch.cat([s for s in batch.next_state if s is not None])\n",
346 | " next_state_values = torch.zeros(BATCH_SIZE, device=DEVICE)\n",
347 | "\n",
348 | " with torch.no_grad():\n",
349 | " next_state_values[non_final_mask] = target_net(non_final_next_state).max(1).values\n",
350 | "\n",
351 | " expected_state_action_values = (next_state_values * GAMMA) + reward_batch\n",
352 | " loss = criterion(state_action_values, expected_state_action_values.unsqueeze(1))\n",
353 | "\n",
354 | " loss.backward()\n",
355 | "\n",
356 | " nn.utils.clip_grad_value_(policy_net.parameters(), CLIP_VALUE)\n",
357 | " optimizer.step()"
358 | ],
359 | "metadata": {
360 | "id": "KtBs3WkB79yg"
361 | },
362 | "execution_count": 14,
363 | "outputs": []
364 | },
365 | {
366 | "cell_type": "code",
367 | "source": [
368 | "episode_durations = []"
369 | ],
370 | "metadata": {
371 | "id": "WsKcEq4u6_5T"
372 | },
373 | "execution_count": 15,
374 | "outputs": []
375 | },
376 | {
377 | "cell_type": "code",
378 | "source": [
379 | "for epoch in range(1, NUM_EPISODES + 1):\n",
380 | " state, _ = env.reset()\n",
381 | " state = torch.tensor(state, dtype=torch.float32, device=DEVICE).unsqueeze(0)\n",
382 | "\n",
383 | " for t in count():\n",
384 | " action = select_action(state)\n",
385 | "\n",
386 | " observation, reward, terminated, truncated, _ = env.step(action.item())\n",
387 | " reward = torch.tensor([reward], device=DEVICE)\n",
388 | "\n",
389 | " if terminated:\n",
390 | " next_state = None\n",
391 | " else:\n",
392 | " next_state = torch.tensor(observation, dtype=torch.float32, device=DEVICE).unsqueeze(0)\n",
393 | "\n",
394 | " memory.push(state, action, reward, next_state)\n",
395 | " state = next_state\n",
396 | "\n",
397 | " optimize_model()\n",
398 | "\n",
399 | " target_state_dict = target_net.state_dict()\n",
400 | " policy_state_dict = policy_net.state_dict()\n",
401 | "\n",
402 | " for key in policy_state_dict:\n",
403 | " target_state_dict[key] = policy_state_dict[key] * TAU + target_state_dict[key] * (1 - TAU)\n",
404 | "\n",
405 | " target_net.load_state_dict(target_state_dict)\n",
406 | "\n",
407 | " if terminated or truncated:\n",
408 | " episode_durations.append(t + 1)\n",
409 | "\n",
410 | " if epoch % 50 == 0:\n",
411 | " print(f'Episode {epoch} duration: {t + 1}')\n",
412 | "\n",
413 | " break"
414 | ],
415 | "metadata": {
416 | "colab": {
417 | "base_uri": "https://localhost:8080/"
418 | },
419 | "id": "wO7NprE-_TQa",
420 | "outputId": "8ab15210-408f-452b-f081-926f7d4679e3"
421 | },
422 | "execution_count": 16,
423 | "outputs": [
424 | {
425 | "output_type": "stream",
426 | "name": "stdout",
427 | "text": [
428 | "Episode 50 duration: 10\n",
429 | "Episode 100 duration: 17\n",
430 | "Episode 150 duration: 8\n",
431 | "Episode 200 duration: 74\n",
432 | "Episode 250 duration: 119\n",
433 | "Episode 300 duration: 120\n",
434 | "Episode 350 duration: 145\n",
435 | "Episode 400 duration: 181\n",
436 | "Episode 450 duration: 318\n",
437 | "Episode 500 duration: 500\n",
438 | "Episode 550 duration: 500\n",
439 | "Episode 600 duration: 500\n"
440 | ]
441 | }
442 | ]
443 | },
444 | {
445 | "cell_type": "code",
446 | "source": [
447 | "plt.plot(episode_durations)\n",
448 | "\n",
449 | "plt.show()"
450 | ],
451 | "metadata": {
452 | "colab": {
453 | "base_uri": "https://localhost:8080/",
454 | "height": 430
455 | },
456 | "id": "s7t56VlbBr60",
457 | "outputId": "227e4320-e867-4da1-aedc-450b397db796"
458 | },
459 | "execution_count": 17,
460 | "outputs": [
461 | {
462 | "output_type": "display_data",
463 | "data": {
464 | "text/plain": [
465 | ""
466 | ],
467 | "image/png": "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dXWorKwUj/nkk0/g9XoxadKkbr/maBIEAfPmzcNbb72FTz75BIMHD5btnzBhAmw2m+z92rNnD6qqqmTv1/bt22X/w69atQoOhyPgF0mi8Xq9cDqdfJ8Upk6diu3bt2Pr1q3iv4kTJ2L27Nni53y/tDU1NeG7775D3759+bOlcO655wa0Qvj2228xcOBAAHH4Oz6iJbc92LJly4SUlBRh6dKlwq5du4TbbrtNyMnJkVV2J4PGxkZhy5YtwpYtWwQAwjPPPCNs2bJF+OGHHwRB8E1By8nJEd555x1h27ZtwhVXXKE6BW38+PHChg0bhC+++EIYOnRoQk4znjt3rpCdnS189tlnsimOLS0t4jG33367UFxcLHzyySfC5s2bhdLSUqG0tFTc75/iOG3aNGHr1q3CypUrhT59+iTcFMdf//rXwpo1a4QDBw4I27ZtE379618LJpNJ+OijjwRB4PsUjHQWjyDw/ZL65S9/KXz22WfCgQMHhC+//FIoKysTevfuLdTW1gqCwPdKauPGjYLVahWeeOIJYe/evcLf/vY3IT09XXjttdfEY+LpdzwDFIkXXnhBKC4uFux2u3D22WcL69evj/UldbtPP/1UABDwb86cOYIg+KahPfjgg0JBQYGQkpIiTJ06VdizZ4/sMU6cOCFcf/31QmZmpuBwOISbb75ZaGxsjMGriS619wmAsGTJEvGY1tZW4f/9v/8n9OrVS0hPTxeuuuoq4ejRo7LH+f7774UZM2YIaWlpQu/evYVf/vKXQnt7eze/muj6+c9/LgwcOFCw2+1Cnz59hKlTp4rBiSDwfQpGGaDw/ep07bXXCn379hXsdrvQr18/4dprr5X19eB7Jffee+8JZ5xxhpCSkiKMGDFC+OMf/yjbH0+/402CIAiRzckQERERhYc1KERERBR3GKAQERFR3GGAQkRERHGHAQoRERHFHQYoREREFHcYoBAREVHcYYBCREREcYcBChEREcUdBihEREQUdxigEBERUdxhgEJERERxhwEKERERxZ3/D1EzuVhd/PloAAAAAElFTkSuQmCC\n"
468 | },
469 | "metadata": {}
470 | }
471 | ]
472 | },
473 | {
474 | "cell_type": "code",
475 | "source": [],
476 | "metadata": {
477 | "id": "SkiYqlimB-lB"
478 | },
479 | "execution_count": 17,
480 | "outputs": []
481 | }
482 | ]
483 | }
--------------------------------------------------------------------------------
/5_Pytorch_Introdution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "nbformat": 4,
3 | "nbformat_minor": 0,
4 | "metadata": {
5 | "colab": {
6 | "provenance": [],
7 | "authorship_tag": "ABX9TyMa4UQgnjr1l61FgngsPT2O",
8 | "include_colab_link": true
9 | },
10 | "kernelspec": {
11 | "name": "python3",
12 | "display_name": "Python 3"
13 | },
14 | "language_info": {
15 | "name": "python"
16 | }
17 | },
18 | "cells": [
19 | {
20 | "cell_type": "markdown",
21 | "metadata": {
22 | "id": "view-in-github",
23 | "colab_type": "text"
24 | },
25 | "source": [
26 | " "
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 2,
32 | "metadata": {
33 | "id": "wqWzgaihwob-"
34 | },
35 | "outputs": [],
36 | "source": [
37 | "import torch\n",
38 | "import torch.nn as nn\n",
39 | "import torch.nn.functional as F\n",
40 | "import torch.optim as optim"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "source": [
46 | "scaler = torch.tensor([1.])"
47 | ],
48 | "metadata": {
49 | "id": "fSQwTeFAxRPu"
50 | },
51 | "execution_count": 4,
52 | "outputs": []
53 | },
54 | {
55 | "cell_type": "code",
56 | "source": [
57 | "scaler"
58 | ],
59 | "metadata": {
60 | "colab": {
61 | "base_uri": "https://localhost:8080/"
62 | },
63 | "id": "JbmosPEXxwBI",
64 | "outputId": "a4a5fcdc-a0b6-4c41-f084-7d18cdd0525b"
65 | },
66 | "execution_count": 5,
67 | "outputs": [
68 | {
69 | "output_type": "execute_result",
70 | "data": {
71 | "text/plain": [
72 | "tensor([1.])"
73 | ]
74 | },
75 | "metadata": {},
76 | "execution_count": 5
77 | }
78 | ]
79 | },
80 | {
81 | "cell_type": "code",
82 | "source": [
83 | "scaler.ndim"
84 | ],
85 | "metadata": {
86 | "colab": {
87 | "base_uri": "https://localhost:8080/"
88 | },
89 | "id": "HjeDdpDOxy11",
90 | "outputId": "94029959-2384-4e69-c806-971e23e97bf1"
91 | },
92 | "execution_count": 6,
93 | "outputs": [
94 | {
95 | "output_type": "execute_result",
96 | "data": {
97 | "text/plain": [
98 | "1"
99 | ]
100 | },
101 | "metadata": {},
102 | "execution_count": 6
103 | }
104 | ]
105 | },
106 | {
107 | "cell_type": "code",
108 | "source": [
109 | "scaler.dtype"
110 | ],
111 | "metadata": {
112 | "colab": {
113 | "base_uri": "https://localhost:8080/"
114 | },
115 | "id": "87I5lTcLx0D1",
116 | "outputId": "ae93d0d4-db54-4f30-99c4-edafb9d0d47e"
117 | },
118 | "execution_count": 7,
119 | "outputs": [
120 | {
121 | "output_type": "execute_result",
122 | "data": {
123 | "text/plain": [
124 | "torch.float32"
125 | ]
126 | },
127 | "metadata": {},
128 | "execution_count": 7
129 | }
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "source": [
135 | "scaler + 2"
136 | ],
137 | "metadata": {
138 | "colab": {
139 | "base_uri": "https://localhost:8080/"
140 | },
141 | "id": "3HELsLg5x1Jl",
142 | "outputId": "dc28f56f-5cb3-422a-c930-d0c17fadd0f4"
143 | },
144 | "execution_count": 8,
145 | "outputs": [
146 | {
147 | "output_type": "execute_result",
148 | "data": {
149 | "text/plain": [
150 | "tensor([3.])"
151 | ]
152 | },
153 | "metadata": {},
154 | "execution_count": 8
155 | }
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "source": [
161 | "scaler.requires_grad"
162 | ],
163 | "metadata": {
164 | "colab": {
165 | "base_uri": "https://localhost:8080/"
166 | },
167 | "id": "JQSUrajux7ZN",
168 | "outputId": "376f1b1c-e46b-49a8-b41f-9c1580feff32"
169 | },
170 | "execution_count": 9,
171 | "outputs": [
172 | {
173 | "output_type": "execute_result",
174 | "data": {
175 | "text/plain": [
176 | "False"
177 | ]
178 | },
179 | "metadata": {},
180 | "execution_count": 9
181 | }
182 | ]
183 | },
184 | {
185 | "cell_type": "code",
186 | "source": [
187 | "scaler.device"
188 | ],
189 | "metadata": {
190 | "colab": {
191 | "base_uri": "https://localhost:8080/"
192 | },
193 | "id": "wWIFoa5xyGCB",
194 | "outputId": "d702ab3d-9f86-423d-ce53-f58da116e6fd"
195 | },
196 | "execution_count": 10,
197 | "outputs": [
198 | {
199 | "output_type": "execute_result",
200 | "data": {
201 | "text/plain": [
202 | "device(type='cpu')"
203 | ]
204 | },
205 | "metadata": {},
206 | "execution_count": 10
207 | }
208 | ]
209 | },
210 | {
211 | "cell_type": "code",
212 | "source": [
213 | "torch.cuda.is_available()"
214 | ],
215 | "metadata": {
216 | "colab": {
217 | "base_uri": "https://localhost:8080/"
218 | },
219 | "id": "kTm0UlECzZCp",
220 | "outputId": "ebf469e0-95c2-4e89-ce60-1290abdd3b79"
221 | },
222 | "execution_count": 15,
223 | "outputs": [
224 | {
225 | "output_type": "execute_result",
226 | "data": {
227 | "text/plain": [
228 | "False"
229 | ]
230 | },
231 | "metadata": {},
232 | "execution_count": 15
233 | }
234 | ]
235 | },
236 | {
237 | "cell_type": "code",
238 | "source": [
239 | "device = 'cuda' if torch.cuda.is_available() else 'cpu'"
240 | ],
241 | "metadata": {
242 | "id": "l1lqFQnVyNXF"
243 | },
244 | "execution_count": 12,
245 | "outputs": []
246 | },
247 | {
248 | "cell_type": "code",
249 | "source": [
250 | "device"
251 | ],
252 | "metadata": {
253 | "colab": {
254 | "base_uri": "https://localhost:8080/",
255 | "height": 36
256 | },
257 | "id": "XZLSWKHmyW4I",
258 | "outputId": "d09aa7bf-a53c-44cc-9bd2-fd129e2fa0ec"
259 | },
260 | "execution_count": 13,
261 | "outputs": [
262 | {
263 | "output_type": "execute_result",
264 | "data": {
265 | "text/plain": [
266 | "'cpu'"
267 | ],
268 | "application/vnd.google.colaboratory.intrinsic+json": {
269 | "type": "string"
270 | }
271 | },
272 | "metadata": {},
273 | "execution_count": 13
274 | }
275 | ]
276 | },
277 | {
278 | "cell_type": "code",
279 | "source": [
280 | "scaler = scaler.to(device)"
281 | ],
282 | "metadata": {
283 | "id": "F5Ekj_ITydS-"
284 | },
285 | "execution_count": 14,
286 | "outputs": []
287 | },
288 | {
289 | "cell_type": "code",
290 | "source": [
291 | "class Network(nn.Module):\n",
292 | " def __init__(self):\n",
293 | " super().__init__()\n",
294 | "\n",
295 | " self.fc1 = nn.Linear(in_features=2, out_features=10)\n",
296 | " self.fc2 = nn.Linear(in_features=10, out_features=10)\n",
297 | " self.fc3 = nn.Linear(in_features=10, out_features=10)\n",
298 | " self.fc4 = nn.Linear(in_features=10, out_features=1)\n",
299 | "\n",
300 | " def forward(self, x):\n",
301 | " x = F.relu(self.fc1(x))\n",
302 | " x = F.relu(self.fc2(x))\n",
303 | " x = F.relu(self.fc3(x))\n",
304 | " x = self.fc4(x)\n",
305 | "\n",
306 | " return x"
307 | ],
308 | "metadata": {
309 | "id": "tC8YnzIwyf6n"
310 | },
311 | "execution_count": 22,
312 | "outputs": []
313 | },
314 | {
315 | "cell_type": "code",
316 | "source": [
317 | "net = Network().to(device)"
318 | ],
319 | "metadata": {
320 | "id": "jmt6SYAZ0wPa"
321 | },
322 | "execution_count": 23,
323 | "outputs": []
324 | },
325 | {
326 | "cell_type": "code",
327 | "source": [
328 | "test_input = torch.rand((3, 2))\n",
329 | "test_input"
330 | ],
331 | "metadata": {
332 | "colab": {
333 | "base_uri": "https://localhost:8080/"
334 | },
335 | "id": "dT8GYeRl00ZX",
336 | "outputId": "9990a297-41e1-4512-c15f-9f29e2b0e1bc"
337 | },
338 | "execution_count": 24,
339 | "outputs": [
340 | {
341 | "output_type": "execute_result",
342 | "data": {
343 | "text/plain": [
344 | "tensor([[0.7418, 0.8436],\n",
345 | " [0.8179, 0.3327],\n",
346 | " [0.5869, 0.7119]])"
347 | ]
348 | },
349 | "metadata": {},
350 | "execution_count": 24
351 | }
352 | ]
353 | },
354 | {
355 | "cell_type": "code",
356 | "source": [
357 | "test_output = net(test_input)\n",
358 | "test_output"
359 | ],
360 | "metadata": {
361 | "colab": {
362 | "base_uri": "https://localhost:8080/"
363 | },
364 | "id": "D0BmAZwc0_rJ",
365 | "outputId": "6aa5025c-71ad-4de5-d711-190eb2f76ada"
366 | },
367 | "execution_count": 25,
368 | "outputs": [
369 | {
370 | "output_type": "execute_result",
371 | "data": {
372 | "text/plain": [
373 | "tensor([[0.2814],\n",
374 | " [0.2967],\n",
375 | " [0.2830]], grad_fn=)"
376 | ]
377 | },
378 | "metadata": {},
379 | "execution_count": 25
380 | }
381 | ]
382 | },
383 | {
384 | "cell_type": "code",
385 | "source": [
386 | "net"
387 | ],
388 | "metadata": {
389 | "colab": {
390 | "base_uri": "https://localhost:8080/"
391 | },
392 | "id": "x6_FwU7R1E8B",
393 | "outputId": "9b217aa5-2416-45d6-96de-88f4dfe9511f"
394 | },
395 | "execution_count": 26,
396 | "outputs": [
397 | {
398 | "output_type": "execute_result",
399 | "data": {
400 | "text/plain": [
401 | "Network(\n",
402 | " (fc1): Linear(in_features=2, out_features=10, bias=True)\n",
403 | " (fc2): Linear(in_features=10, out_features=10, bias=True)\n",
404 | " (fc3): Linear(in_features=10, out_features=10, bias=True)\n",
405 | " (fc4): Linear(in_features=10, out_features=1, bias=True)\n",
406 | ")"
407 | ]
408 | },
409 | "metadata": {},
410 | "execution_count": 26
411 | }
412 | ]
413 | },
414 | {
415 | "cell_type": "code",
416 | "source": [
417 | "list(net.fc1.parameters())"
418 | ],
419 | "metadata": {
420 | "colab": {
421 | "base_uri": "https://localhost:8080/"
422 | },
423 | "id": "0Zidy5vm1McJ",
424 | "outputId": "b5fbf595-8a8a-458f-e533-f6e1601ac526"
425 | },
426 | "execution_count": 30,
427 | "outputs": [
428 | {
429 | "output_type": "execute_result",
430 | "data": {
431 | "text/plain": [
432 | "[Parameter containing:\n",
433 | " tensor([[-0.0678, 0.4129],\n",
434 | " [-0.2128, 0.5182],\n",
435 | " [ 0.3328, -0.5278],\n",
436 | " [-0.0189, 0.6389],\n",
437 | " [ 0.3837, 0.2405],\n",
438 | " [-0.2676, -0.2395],\n",
439 | " [ 0.2778, 0.0328],\n",
440 | " [-0.4963, 0.5281],\n",
441 | " [ 0.1273, -0.0240],\n",
442 | " [-0.4277, -0.5793]], requires_grad=True),\n",
443 | " Parameter containing:\n",
444 | " tensor([-0.5801, 0.0506, 0.2750, -0.6558, -0.2582, -0.3598, -0.5241, -0.0149,\n",
445 | " -0.2104, -0.5190], requires_grad=True)]"
446 | ]
447 | },
448 | "metadata": {},
449 | "execution_count": 30
450 | }
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "source": [],
456 | "metadata": {
457 | "id": "_Ai44HNl1PgN"
458 | },
459 | "execution_count": null,
460 | "outputs": []
461 | }
462 | ]
463 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | "# deep_learning_class_notebooks"
2 |
--------------------------------------------------------------------------------
|