├── repo.gitignore ├── README.md └── assignment_1 └── assignment_1.ipynb /repo.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A-Collection-of-important-tasks-in-pytorch 2 | Everyday things people use in Pytorch. No need to spend hours reading Pytorch forums trying to find them! 3 | 4 | # Link to Tutorial - 5 | https://goo.gl/5Q72ER 6 | -------------------------------------------------------------------------------- /assignment_1/assignment_1.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "kernelspec": { 6 | "display_name": "bai", 7 | "language": "python", 8 | "name": "bai" 9 | }, 10 | "language_info": { 11 | "codemirror_mode": { 12 | "name": "ipython", 13 | "version": 3 14 | }, 15 | "file_extension": ".py", 16 | "mimetype": "text/x-python", 17 | "name": "python", 18 | "nbconvert_exporter": "python", 19 | "pygments_lexer": "ipython3", 20 | "version": "3.5.6" 21 | }, 22 | "colab": { 23 | "name": "assignment_1.ipynb", 24 | "provenance": [], 25 | "collapsed_sections": [], 26 | "toc_visible": true 27 | }, 28 | "widgets": { 29 | "application/vnd.jupyter.widget-state+json": { 30 | "fca4a46c3e954e9ca38032fe64608be4": { 31 | "model_module": "@jupyter-widgets/controls", 32 | "model_name": "ButtonModel", 33 | "state": { 34 | "_view_name": "ButtonView", 35 | "style": "IPY_MODEL_88489a8378ff42acbc9be683412fe6dd", 36 | "_dom_classes": [], 37 | "description": "Read the function?\n Click me!", 38 | "_model_name": "ButtonModel", 39 | "button_style": "", 40 | "_view_module": "@jupyter-widgets/controls", 41 | "_model_module_version": "1.5.0", 42 | "tooltip": "", 43 | "_view_count": null, 44 | "disabled": false, 45 | "_view_module_version": "1.5.0", 46 | "layout": "IPY_MODEL_b66deffcc82643a6814dd6f018d0f008", 47 | "_model_module": "@jupyter-widgets/controls", 48 | "icon": "" 49 | } 50 | }, 51 | "88489a8378ff42acbc9be683412fe6dd": { 52 | "model_module": "@jupyter-widgets/controls", 53 | "model_name": "ButtonStyleModel", 54 | "state": { 55 | "_view_name": "StyleView", 56 | "_model_name": "ButtonStyleModel", 57 | "_view_module": "@jupyter-widgets/base", 58 | "_model_module_version": "1.5.0", 59 | "_view_count": null, 60 | "button_color": null, 61 | "font_weight": "", 62 | "_view_module_version": "1.2.0", 63 | "_model_module": "@jupyter-widgets/controls" 64 | } 65 | }, 66 | "b66deffcc82643a6814dd6f018d0f008": { 67 | "model_module": "@jupyter-widgets/base", 68 | "model_name": "LayoutModel", 69 | "state": { 70 | "_view_name": "LayoutView", 71 | "grid_template_rows": null, 72 | "right": null, 73 | "justify_content": null, 74 | "_view_module": "@jupyter-widgets/base", 75 | "overflow": null, 76 | "_model_module_version": "1.2.0", 77 | "_view_count": null, 78 | "flex_flow": null, 79 | "width": "auto", 80 | "min_width": null, 81 | "border": null, 82 | "align_items": null, 83 | "bottom": null, 84 | "_model_module": "@jupyter-widgets/base", 85 | "top": null, 86 | "grid_column": null, 87 | "overflow_y": null, 88 | "overflow_x": null, 89 | "grid_auto_flow": null, 90 | "grid_area": null, 91 | "grid_template_columns": null, 92 | "flex": null, 93 | "_model_name": "LayoutModel", 94 | "justify_items": null, 95 | "grid_row": null, 96 | "max_height": null, 97 | "align_content": null, 98 | "visibility": null, 99 | "align_self": null, 100 | "height": "90px", 101 | "min_height": null, 102 | "padding": null, 103 | "grid_auto_rows": null, 104 | "grid_gap": null, 105 | "max_width": null, 106 | "order": null, 107 | "_view_module_version": "1.2.0", 108 | "grid_template_areas": null, 109 | "object_position": null, 110 | "object_fit": null, 111 | "grid_auto_columns": null, 112 | "margin": null, 113 | "display": null, 114 | "left": null 115 | } 116 | }, 117 | "922e59fd27c149a39987451c02477453": { 118 | "model_module": "@jupyter-widgets/output", 119 | "model_name": "OutputModel", 120 | "state": { 121 | "_view_name": "OutputView", 122 | "msg_id": "", 123 | "_dom_classes": [], 124 | "_model_name": "OutputModel", 125 | "outputs": [], 126 | "_view_module": "@jupyter-widgets/output", 127 | "_model_module_version": "1.0.0", 128 | "_view_count": null, 129 | "_view_module_version": "1.0.0", 130 | "layout": "IPY_MODEL_c8accc853b4c4e9f8b1a5b4b976b4e23", 131 | "_model_module": "@jupyter-widgets/output" 132 | } 133 | }, 134 | "c8accc853b4c4e9f8b1a5b4b976b4e23": { 135 | "model_module": "@jupyter-widgets/base", 136 | "model_name": "LayoutModel", 137 | "state": { 138 | "_view_name": "LayoutView", 139 | "grid_template_rows": null, 140 | "right": null, 141 | "justify_content": null, 142 | "_view_module": "@jupyter-widgets/base", 143 | "overflow": null, 144 | "_model_module_version": "1.2.0", 145 | "_view_count": null, 146 | "flex_flow": null, 147 | "width": null, 148 | "min_width": null, 149 | "border": null, 150 | "align_items": null, 151 | "bottom": null, 152 | "_model_module": "@jupyter-widgets/base", 153 | "top": null, 154 | "grid_column": null, 155 | "overflow_y": null, 156 | "overflow_x": null, 157 | "grid_auto_flow": null, 158 | "grid_area": null, 159 | "grid_template_columns": null, 160 | "flex": null, 161 | "_model_name": "LayoutModel", 162 | "justify_items": null, 163 | "grid_row": null, 164 | "max_height": null, 165 | "align_content": null, 166 | "visibility": null, 167 | "align_self": null, 168 | "height": null, 169 | "min_height": null, 170 | "padding": null, 171 | "grid_auto_rows": null, 172 | "grid_gap": null, 173 | "max_width": null, 174 | "order": null, 175 | "_view_module_version": "1.2.0", 176 | "grid_template_areas": null, 177 | "object_position": null, 178 | "object_fit": null, 179 | "grid_auto_columns": null, 180 | "margin": null, 181 | "display": null, 182 | "left": null 183 | } 184 | }, 185 | "dbeb947a70814510976ef5fd8e34f295": { 186 | "model_module": "@jupyter-widgets/controls", 187 | "model_name": "HBoxModel", 188 | "state": { 189 | "_view_name": "HBoxView", 190 | "_dom_classes": [], 191 | "_model_name": "HBoxModel", 192 | "_view_module": "@jupyter-widgets/controls", 193 | "_model_module_version": "1.5.0", 194 | "_view_count": null, 195 | "_view_module_version": "1.5.0", 196 | "box_style": "", 197 | "layout": "IPY_MODEL_45d3b0afa0f14a07b20fc371acd3ba6b", 198 | "_model_module": "@jupyter-widgets/controls", 199 | "children": [ 200 | "IPY_MODEL_52abe6174af24061831094b1207cd843", 201 | "IPY_MODEL_e1d9b05fed70487a93aeb75e81726e4c" 202 | ] 203 | } 204 | }, 205 | "45d3b0afa0f14a07b20fc371acd3ba6b": { 206 | "model_module": "@jupyter-widgets/base", 207 | "model_name": "LayoutModel", 208 | "state": { 209 | "_view_name": "LayoutView", 210 | "grid_template_rows": null, 211 | "right": null, 212 | "justify_content": null, 213 | "_view_module": "@jupyter-widgets/base", 214 | "overflow": null, 215 | "_model_module_version": "1.2.0", 216 | "_view_count": null, 217 | "flex_flow": null, 218 | "width": null, 219 | "min_width": null, 220 | "border": null, 221 | "align_items": null, 222 | "bottom": null, 223 | "_model_module": "@jupyter-widgets/base", 224 | "top": null, 225 | "grid_column": null, 226 | "overflow_y": null, 227 | "overflow_x": null, 228 | "grid_auto_flow": null, 229 | "grid_area": null, 230 | "grid_template_columns": null, 231 | "flex": null, 232 | "_model_name": "LayoutModel", 233 | "justify_items": null, 234 | "grid_row": null, 235 | "max_height": null, 236 | "align_content": null, 237 | "visibility": null, 238 | "align_self": null, 239 | "height": null, 240 | "min_height": null, 241 | "padding": null, 242 | "grid_auto_rows": null, 243 | "grid_gap": null, 244 | "max_width": null, 245 | "order": null, 246 | "_view_module_version": "1.2.0", 247 | "grid_template_areas": null, 248 | "object_position": null, 249 | "object_fit": null, 250 | "grid_auto_columns": null, 251 | "margin": null, 252 | "display": null, 253 | "left": null 254 | } 255 | }, 256 | "52abe6174af24061831094b1207cd843": { 257 | "model_module": "@jupyter-widgets/controls", 258 | "model_name": "FloatProgressModel", 259 | "state": { 260 | "_view_name": "ProgressView", 261 | "style": "IPY_MODEL_bcdfb20486404cd8aac5efaa70b8ba2b", 262 | "_dom_classes": [], 263 | "description": " 0%", 264 | "_model_name": "FloatProgressModel", 265 | "bar_style": "", 266 | "max": 6000, 267 | "_view_module": "@jupyter-widgets/controls", 268 | "_model_module_version": "1.5.0", 269 | "value": 0, 270 | "_view_count": null, 271 | "_view_module_version": "1.5.0", 272 | "orientation": "horizontal", 273 | "min": 0, 274 | "description_tooltip": null, 275 | "_model_module": "@jupyter-widgets/controls", 276 | "layout": "IPY_MODEL_55a8da2af315484cbee80493aa0a2d34" 277 | } 278 | }, 279 | "e1d9b05fed70487a93aeb75e81726e4c": { 280 | "model_module": "@jupyter-widgets/controls", 281 | "model_name": "HTMLModel", 282 | "state": { 283 | "_view_name": "HTMLView", 284 | "style": "IPY_MODEL_8ed09a2afd9b4dc59ecf92df757d1b53", 285 | "_dom_classes": [], 286 | "description": "", 287 | "_model_name": "HTMLModel", 288 | "placeholder": "​", 289 | "_view_module": "@jupyter-widgets/controls", 290 | "_model_module_version": "1.5.0", 291 | "value": " 0/6000 [00:00<?, ?it/s]", 292 | "_view_count": null, 293 | "_view_module_version": "1.5.0", 294 | "description_tooltip": null, 295 | "_model_module": "@jupyter-widgets/controls", 296 | "layout": "IPY_MODEL_021623db8dbb48328ee893b3794886b1" 297 | } 298 | }, 299 | "bcdfb20486404cd8aac5efaa70b8ba2b": { 300 | "model_module": "@jupyter-widgets/controls", 301 | "model_name": "ProgressStyleModel", 302 | "state": { 303 | "_view_name": "StyleView", 304 | "_model_name": "ProgressStyleModel", 305 | "description_width": "initial", 306 | "_view_module": "@jupyter-widgets/base", 307 | "_model_module_version": "1.5.0", 308 | "_view_count": null, 309 | "_view_module_version": "1.2.0", 310 | "bar_color": null, 311 | "_model_module": "@jupyter-widgets/controls" 312 | } 313 | }, 314 | "55a8da2af315484cbee80493aa0a2d34": { 315 | "model_module": "@jupyter-widgets/base", 316 | "model_name": "LayoutModel", 317 | "state": { 318 | "_view_name": "LayoutView", 319 | "grid_template_rows": null, 320 | "right": null, 321 | "justify_content": null, 322 | "_view_module": "@jupyter-widgets/base", 323 | "overflow": null, 324 | "_model_module_version": "1.2.0", 325 | "_view_count": null, 326 | "flex_flow": null, 327 | "width": null, 328 | "min_width": null, 329 | "border": null, 330 | "align_items": null, 331 | "bottom": null, 332 | "_model_module": "@jupyter-widgets/base", 333 | "top": null, 334 | "grid_column": null, 335 | "overflow_y": null, 336 | "overflow_x": null, 337 | "grid_auto_flow": null, 338 | "grid_area": null, 339 | "grid_template_columns": null, 340 | "flex": null, 341 | "_model_name": "LayoutModel", 342 | "justify_items": null, 343 | "grid_row": null, 344 | "max_height": null, 345 | "align_content": null, 346 | "visibility": null, 347 | "align_self": null, 348 | "height": null, 349 | "min_height": null, 350 | "padding": null, 351 | "grid_auto_rows": null, 352 | "grid_gap": null, 353 | "max_width": null, 354 | "order": null, 355 | "_view_module_version": "1.2.0", 356 | "grid_template_areas": null, 357 | "object_position": null, 358 | "object_fit": null, 359 | "grid_auto_columns": null, 360 | "margin": null, 361 | "display": null, 362 | "left": null 363 | } 364 | }, 365 | "8ed09a2afd9b4dc59ecf92df757d1b53": { 366 | "model_module": "@jupyter-widgets/controls", 367 | "model_name": "DescriptionStyleModel", 368 | "state": { 369 | "_view_name": "StyleView", 370 | "_model_name": "DescriptionStyleModel", 371 | "description_width": "", 372 | "_view_module": "@jupyter-widgets/base", 373 | "_model_module_version": "1.5.0", 374 | "_view_count": null, 375 | "_view_module_version": "1.2.0", 376 | "_model_module": "@jupyter-widgets/controls" 377 | } 378 | }, 379 | "021623db8dbb48328ee893b3794886b1": { 380 | "model_module": "@jupyter-widgets/base", 381 | "model_name": "LayoutModel", 382 | "state": { 383 | "_view_name": "LayoutView", 384 | "grid_template_rows": null, 385 | "right": null, 386 | "justify_content": null, 387 | "_view_module": "@jupyter-widgets/base", 388 | "overflow": null, 389 | "_model_module_version": "1.2.0", 390 | "_view_count": null, 391 | "flex_flow": null, 392 | "width": null, 393 | "min_width": null, 394 | "border": null, 395 | "align_items": null, 396 | "bottom": null, 397 | "_model_module": "@jupyter-widgets/base", 398 | "top": null, 399 | "grid_column": null, 400 | "overflow_y": null, 401 | "overflow_x": null, 402 | "grid_auto_flow": null, 403 | "grid_area": null, 404 | "grid_template_columns": null, 405 | "flex": null, 406 | "_model_name": "LayoutModel", 407 | "justify_items": null, 408 | "grid_row": null, 409 | "max_height": null, 410 | "align_content": null, 411 | "visibility": null, 412 | "align_self": null, 413 | "height": null, 414 | "min_height": null, 415 | "padding": null, 416 | "grid_auto_rows": null, 417 | "grid_gap": null, 418 | "max_width": null, 419 | "order": null, 420 | "_view_module_version": "1.2.0", 421 | "grid_template_areas": null, 422 | "object_position": null, 423 | "object_fit": null, 424 | "grid_auto_columns": null, 425 | "margin": null, 426 | "display": null, 427 | "left": null 428 | } 429 | } 430 | } 431 | } 432 | }, 433 | "cells": [ 434 | { 435 | "cell_type": "markdown", 436 | "metadata": { 437 | "id": "KMd5XFEMpmkG" 438 | }, 439 | "source": [ 440 | "\n", 441 | "\n", 442 | "
\n", 443 | "

Assignment 1

\n", 444 | "

Quick intro + checking code works on your system

\n", 445 | "
\n", 446 | "\n", 447 | "" 448 | ] 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "metadata": { 453 | "id": "qvQQRsLvpmkM" 454 | }, 455 | "source": [ 456 | "### Learning Outcomes: The goal of this assignment is two-fold:\n", 457 | "\n", 458 | "- This code-base is designed to be easily extended for different research projects. Running this notebook to the end will ensure that the code runs on your system, and that you are set-up to start playing with machine learning code.\n", 459 | "- This notebook has one complete application: training a CNN classifier to predict the digit in MNIST Images. The code is written to familiarize you to a typical machine learning pipeline, and to the building blocks of code used to do ML. So, read on! " 460 | ] 461 | }, 462 | { 463 | "cell_type": "markdown", 464 | "metadata": { 465 | "id": "CIBmTQh_pmkN" 466 | }, 467 | "source": [ 468 | "### Please specify your Name, Email ID and forked repository url here:\n", 469 | "- Name: Spandan\n", 470 | "- Email:\n", 471 | "- Link to your forked github repository:" 472 | ] 473 | }, 474 | { 475 | "cell_type": "code", 476 | "metadata": { 477 | "id": "JLZ79lZUpmkN" 478 | }, 479 | "source": [ 480 | "### General libraries useful for python ###\n", 481 | "\n", 482 | "import os\n", 483 | "import sys\n", 484 | "from tqdm.notebook import tqdm\n", 485 | "import json\n", 486 | "import random\n", 487 | "import pickle\n", 488 | "import copy\n", 489 | "from IPython.display import display\n", 490 | "import ipywidgets as widgets" 491 | ], 492 | "execution_count": null, 493 | "outputs": [] 494 | }, 495 | { 496 | "cell_type": "code", 497 | "metadata": { 498 | "id": "yliO9WELTm_8" 499 | }, 500 | "source": [ 501 | "# !pip install scipy`" 502 | ], 503 | "execution_count": null, 504 | "outputs": [] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "metadata": { 509 | "colab": { 510 | "base_uri": "https://localhost:8080/" 511 | }, 512 | "id": "gLOqAsD4yTjn", 513 | "outputId": "28907227-3840-4be6-b7f7-f1b23ce2d1cf" 514 | }, 515 | "source": [ 516 | "from google.colab import drive\n", 517 | "drive.mount('/content/drive')" 518 | ], 519 | "execution_count": 1, 520 | "outputs": [ 521 | { 522 | "output_type": "stream", 523 | "text": [ 524 | "Mounted at /content/drive\n" 525 | ], 526 | "name": "stdout" 527 | } 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "metadata": { 533 | "id": "NBYo9vxspmkN", 534 | "colab": { 535 | "base_uri": "https://localhost:8080/" 536 | }, 537 | "outputId": "f3532660-43ee-4393-ebe8-75f04d71ec83" 538 | }, 539 | "source": [ 540 | "\n", 541 | "### Finding where you clone your repo, so that code upstream paths can be specified programmatically ####\n", 542 | "git_dir = '/content/drive/MyDrive/Harvard_BAI'\n", 543 | "print('Your github directory is :%s'%git_dir)" 544 | ], 545 | "execution_count": 2, 546 | "outputs": [ 547 | { 548 | "output_type": "stream", 549 | "text": [ 550 | "Your github directory is :/content/drive/MyDrive/Harvard_BAI\n" 551 | ], 552 | "name": "stdout" 553 | } 554 | ] 555 | }, 556 | { 557 | "cell_type": "code", 558 | "metadata": { 559 | "id": "L2vk8XYjpmkO" 560 | }, 561 | "source": [ 562 | "### Libraries for visualizing our results and data ###\n", 563 | "from PIL import Image\n", 564 | "import matplotlib.pyplot as plt" 565 | ], 566 | "execution_count": null, 567 | "outputs": [] 568 | }, 569 | { 570 | "cell_type": "code", 571 | "metadata": { 572 | "scrolled": false, 573 | "id": "stYTIO0EpmkP" 574 | }, 575 | "source": [ 576 | "### Import PyTorch and its components ###\n", 577 | "import torch\n", 578 | "import torchvision\n", 579 | "import torch.nn as nn\n", 580 | "import torch.optim as optim" 581 | ], 582 | "execution_count": null, 583 | "outputs": [] 584 | }, 585 | { 586 | "cell_type": "markdown", 587 | "metadata": { 588 | "id": "pw2HumdXpmkP" 589 | }, 590 | "source": [ 591 | "#### Let's load our flexible code-base which you will build on for your research projects in future assignments.\n", 592 | "\n", 593 | "Above we have imported modules (libraries for those familiar to programming languages other than python). These modules are of two kinds - (1) inbuilt python modules like `os`, `sys`, `random`, or (2) ones which we installed using conda (ex. `torch`).\n", 594 | "\n", 595 | "Below we will be importing our own written code which resides in the `res` folder in your github directory. This is structured to be easily expandable for different machine learning projects. Suppose that you want to do a project on object detection. You can easily add a few files to the sub-folders within `res`, and this script will then be flexibly do detection instead of classication (which is presented here). Expanding on this codebase will be the main subject matter of Assignment 2. For now, let's continue with importing." 596 | ] 597 | }, 598 | { 599 | "cell_type": "code", 600 | "metadata": { 601 | "colab": { 602 | "base_uri": "https://localhost:8080/", 603 | "height": 34 604 | }, 605 | "id": "2cMjuS3cUTsr", 606 | "outputId": "983db933-59db-43b9-b266-ab1e995eaee0" 607 | }, 608 | "source": [ 609 | "'%s/res/'%git_dir" 610 | ], 611 | "execution_count": null, 612 | "outputs": [ 613 | { 614 | "output_type": "execute_result", 615 | "data": { 616 | "application/vnd.google.colaboratory.intrinsic+json": { 617 | "type": "string" 618 | }, 619 | "text/plain": [ 620 | "'/res/'" 621 | ] 622 | }, 623 | "metadata": { 624 | "tags": [] 625 | }, 626 | "execution_count": 7 627 | } 628 | ] 629 | }, 630 | { 631 | "cell_type": "code", 632 | "metadata": { 633 | "id": "szMvs_vJpmkP", 634 | "colab": { 635 | "base_uri": "https://localhost:8080/", 636 | "height": 340 637 | }, 638 | "outputId": "e9fcfc04-bb6b-4dd2-f743-a22efae0b2f8" 639 | }, 640 | "source": [ 641 | "### Making helper code under the folder res available. This includes loaders, models, etc. ###\n", 642 | "sys.path.append('%s/res/'%git_dir)\n", 643 | "from models.models import get_model\n", 644 | "from loader.loader import get_loader" 645 | ], 646 | "execution_count": null, 647 | "outputs": [ 648 | { 649 | "output_type": "error", 650 | "ename": "ModuleNotFoundError", 651 | "evalue": "ignored", 652 | "traceback": [ 653 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 654 | "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", 655 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m### Making helper code under the folder res available. This includes loaders, models, etc. ###\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'%s/res/'\u001b[0m\u001b[0;34m%\u001b[0m\u001b[0mgit_dir\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mmodels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodels\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mget_model\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mloader\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mloader\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mget_loader\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 656 | "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'models'", 657 | "", 658 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0;32m\nNOTE: If your import is failing due to a missing package, you can\nmanually install dependencies using either !pip or !apt.\n\nTo view examples of installing some common dependencies, click the\n\"Open Examples\" button below.\n\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n" 659 | ] 660 | } 661 | ] 662 | }, 663 | { 664 | "cell_type": "markdown", 665 | "metadata": { 666 | "id": "nAVtuHh0pmkQ" 667 | }, 668 | "source": [ 669 | "#### See those paths printed above?" 670 | ] 671 | }, 672 | { 673 | "cell_type": "markdown", 674 | "metadata": { 675 | "id": "MV_MPAjxpmkQ" 676 | }, 677 | "source": [ 678 | "`res/models` holds different model files. So, if you want to load ResNet architecture or a transformers architecture, they will reside there as separate files. \n", 679 | "\n", 680 | "Similarly, `res/loader` holds programs which are designed to load different types of data. For example, you may want to load data differently for object classification and detection. For classification each image will have only a numerical label corresponding to its category. For detection, the labels for the same image would contain bounding boxes for different objects and the type of the object in the box. \n", 681 | "\n", 682 | "So, to expand further you will be adding files to the folders above." 683 | ] 684 | }, 685 | { 686 | "cell_type": "markdown", 687 | "metadata": { 688 | "scrolled": true, 689 | "id": "2ObKxhenpmkQ" 690 | }, 691 | "source": [ 692 | "### Setting up Weights and Biases for tracking your experiments. ###\n", 693 | "\n", 694 | "We have Weights and Biases (wandb.ai) integrated into the code for easy visualization of results and for tracking performance. `Please make an account at wandb.ai, and follow the steps to login to your account!`" 695 | ] 696 | }, 697 | { 698 | "cell_type": "code", 699 | "metadata": { 700 | "colab": { 701 | "base_uri": "https://localhost:8080/" 702 | }, 703 | "id": "nYp22bt7y14F", 704 | "outputId": "8412bc6c-4458-40b5-bfbd-a40f41cc9a1c" 705 | }, 706 | "source": [ 707 | "!pip install wandb" 708 | ], 709 | "execution_count": null, 710 | "outputs": [ 711 | { 712 | "output_type": "stream", 713 | "text": [ 714 | "Collecting wandb\n", 715 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/72/85/941042d55708fe30f95d799b5380ea5601ea6c50ab3cf06c0b2dad02129c/wandb-0.10.17-py2.py3-none-any.whl (2.0MB)\n", 716 | "\u001b[K |████████████████████████████████| 2.0MB 5.6MB/s \n", 717 | "\u001b[?25hRequirement already satisfied: requests<3,>=2.0.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (2.23.0)\n", 718 | "Collecting shortuuid>=0.5.0\n", 719 | " Downloading https://files.pythonhosted.org/packages/25/a6/2ecc1daa6a304e7f1b216f0896b26156b78e7c38e1211e9b798b4716c53d/shortuuid-1.0.1-py3-none-any.whl\n", 720 | "Requirement already satisfied: psutil>=5.0.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (5.4.8)\n", 721 | "Collecting docker-pycreds>=0.4.0\n", 722 | " Downloading https://files.pythonhosted.org/packages/f5/e8/f6bd1eee09314e7e6dee49cbe2c5e22314ccdb38db16c9fc72d2fa80d054/docker_pycreds-0.4.0-py2.py3-none-any.whl\n", 723 | "Requirement already satisfied: protobuf>=3.12.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (3.12.4)\n", 724 | "Collecting configparser>=3.8.1\n", 725 | " Downloading https://files.pythonhosted.org/packages/08/b2/ef713e0e67f6e7ec7d59aea3ee78d05b39c15930057e724cc6d362a8c3bb/configparser-5.0.1-py3-none-any.whl\n", 726 | "Requirement already satisfied: six>=1.13.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (1.15.0)\n", 727 | "Requirement already satisfied: Click>=7.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (7.1.2)\n", 728 | "Collecting subprocess32>=3.5.3\n", 729 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/32/c8/564be4d12629b912ea431f1a50eb8b3b9d00f1a0b1ceff17f266be190007/subprocess32-3.5.4.tar.gz (97kB)\n", 730 | "\u001b[K |████████████████████████████████| 102kB 6.3MB/s \n", 731 | "\u001b[?25hCollecting pathtools\n", 732 | " Downloading https://files.pythonhosted.org/packages/e7/7f/470d6fcdf23f9f3518f6b0b76be9df16dcc8630ad409947f8be2eb0ed13a/pathtools-0.1.2.tar.gz\n", 733 | "Requirement already satisfied: PyYAML in /usr/local/lib/python3.6/dist-packages (from wandb) (3.13)\n", 734 | "Requirement already satisfied: promise<3,>=2.0 in /usr/local/lib/python3.6/dist-packages (from wandb) (2.3)\n", 735 | "Collecting GitPython>=1.0.0\n", 736 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/d7/cb/ec98155c501b68dcb11314c7992cd3df6dce193fd763084338a117967d53/GitPython-3.1.12-py3-none-any.whl (159kB)\n", 737 | "\u001b[K |████████████████████████████████| 163kB 19.6MB/s \n", 738 | "\u001b[?25hCollecting sentry-sdk>=0.4.0\n", 739 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/b1/5c/018bf9a5c24343a664deaea70e61f33f53bb1bd3caf193110f827bfd07e2/sentry_sdk-0.19.5-py2.py3-none-any.whl (128kB)\n", 740 | "\u001b[K |████████████████████████████████| 133kB 16.9MB/s \n", 741 | "\u001b[?25hRequirement already satisfied: python-dateutil>=2.6.1 in /usr/local/lib/python3.6/dist-packages (from wandb) (2.8.1)\n", 742 | "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.0.0->wandb) (3.0.4)\n", 743 | "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.0.0->wandb) (2020.12.5)\n", 744 | "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.0.0->wandb) (1.24.3)\n", 745 | "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.6/dist-packages (from requests<3,>=2.0.0->wandb) (2.10)\n", 746 | "Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from protobuf>=3.12.0->wandb) (53.0.0)\n", 747 | "Collecting gitdb<5,>=4.0.1\n", 748 | "\u001b[?25l Downloading https://files.pythonhosted.org/packages/48/11/d1800bca0a3bae820b84b7d813ad1eff15a48a64caea9c823fc8c1b119e8/gitdb-4.0.5-py3-none-any.whl (63kB)\n", 749 | "\u001b[K |████████████████████████████████| 71kB 7.0MB/s \n", 750 | "\u001b[?25hCollecting smmap<4,>=3.0.1\n", 751 | " Downloading https://files.pythonhosted.org/packages/d5/1e/6130925131f639b2acde0f7f18b73e33ce082ff2d90783c436b52040af5a/smmap-3.0.5-py2.py3-none-any.whl\n", 752 | "Building wheels for collected packages: subprocess32, pathtools\n", 753 | " Building wheel for subprocess32 (setup.py) ... \u001b[?25l\u001b[?25hdone\n", 754 | " Created wheel for subprocess32: filename=subprocess32-3.5.4-cp36-none-any.whl size=6490 sha256=16e1ae8c88fa2a9fb6840e80cd3196a997f52304d443308733a3c7a0bb8c28b6\n", 755 | " Stored in directory: /root/.cache/pip/wheels/68/39/1a/5e402bdfdf004af1786c8b853fd92f8c4a04f22aad179654d1\n", 756 | " Building wheel for pathtools (setup.py) ... \u001b[?25l\u001b[?25hdone\n", 757 | " Created wheel for pathtools: filename=pathtools-0.1.2-cp36-none-any.whl size=8785 sha256=590b35c4bb00cf71c7db764754763a86656593e6cafe068e64dd1595a091b692\n", 758 | " Stored in directory: /root/.cache/pip/wheels/0b/04/79/c3b0c3a0266a3cb4376da31e5bfe8bba0c489246968a68e843\n", 759 | "Successfully built subprocess32 pathtools\n", 760 | "Installing collected packages: shortuuid, docker-pycreds, configparser, subprocess32, pathtools, smmap, gitdb, GitPython, sentry-sdk, wandb\n", 761 | "Successfully installed GitPython-3.1.12 configparser-5.0.1 docker-pycreds-0.4.0 gitdb-4.0.5 pathtools-0.1.2 sentry-sdk-0.19.5 shortuuid-1.0.1 smmap-3.0.5 subprocess32-3.5.4 wandb-0.10.17\n" 762 | ], 763 | "name": "stdout" 764 | } 765 | ] 766 | }, 767 | { 768 | "cell_type": "code", 769 | "metadata": { 770 | "scrolled": true, 771 | "id": "k8aPRoLWpmkQ", 772 | "colab": { 773 | "base_uri": "https://localhost:8080/", 774 | "height": 98 775 | }, 776 | "outputId": "9815b050-75bf-4451-aa85-796816f4060d" 777 | }, 778 | "source": [ 779 | "import wandb\n", 780 | "wandb.login()" 781 | ], 782 | "execution_count": null, 783 | "outputs": [ 784 | { 785 | "output_type": "display_data", 786 | "data": { 787 | "application/javascript": [ 788 | "\n", 789 | " window._wandbApiKey = new Promise((resolve, reject) => {\n", 790 | " function loadScript(url) {\n", 791 | " return new Promise(function(resolve, reject) {\n", 792 | " let newScript = document.createElement(\"script\");\n", 793 | " newScript.onerror = reject;\n", 794 | " newScript.onload = resolve;\n", 795 | " document.body.appendChild(newScript);\n", 796 | " newScript.src = url;\n", 797 | " });\n", 798 | " }\n", 799 | " loadScript(\"https://cdn.jsdelivr.net/npm/postmate/build/postmate.min.js\").then(() => {\n", 800 | " const iframe = document.createElement('iframe')\n", 801 | " iframe.style.cssText = \"width:0;height:0;border:none\"\n", 802 | " document.body.appendChild(iframe)\n", 803 | " const handshake = new Postmate({\n", 804 | " container: iframe,\n", 805 | " url: 'https://wandb.ai/authorize'\n", 806 | " });\n", 807 | " const timeout = setTimeout(() => reject(\"Couldn't auto authenticate\"), 5000)\n", 808 | " handshake.then(function(child) {\n", 809 | " child.on('authorize', data => {\n", 810 | " clearTimeout(timeout)\n", 811 | " resolve(data)\n", 812 | " });\n", 813 | " });\n", 814 | " })\n", 815 | " });\n", 816 | " " 817 | ], 818 | "text/plain": [ 819 | "" 820 | ] 821 | }, 822 | "metadata": { 823 | "tags": [] 824 | } 825 | }, 826 | { 827 | "output_type": "stream", 828 | "text": [ 829 | "\u001b[34m\u001b[1mwandb\u001b[0m: You can find your API key in your browser here: https://wandb.ai/authorize\n" 830 | ], 831 | "name": "stderr" 832 | }, 833 | { 834 | "output_type": "stream", 835 | "text": [ 836 | "wandb: Paste an API key from your profile and hit enter: ··········\n" 837 | ], 838 | "name": "stdout" 839 | }, 840 | { 841 | "output_type": "stream", 842 | "text": [ 843 | "\u001b[34m\u001b[1mwandb\u001b[0m: Appending key for api.wandb.ai to your netrc file: /root/.netrc\n" 844 | ], 845 | "name": "stderr" 846 | }, 847 | { 848 | "output_type": "execute_result", 849 | "data": { 850 | "text/plain": [ 851 | "True" 852 | ] 853 | }, 854 | "metadata": { 855 | "tags": [] 856 | }, 857 | "execution_count": 19 858 | } 859 | ] 860 | }, 861 | { 862 | "cell_type": "markdown", 863 | "metadata": { 864 | "id": "wgpN78WapmkR" 865 | }, 866 | "source": [ 867 | "### Specifying settings/hyperparameters for our code below ###" 868 | ] 869 | }, 870 | { 871 | "cell_type": "code", 872 | "metadata": { 873 | "id": "0Rp-0B0opmkR" 874 | }, 875 | "source": [ 876 | "wandb_config = {}\n", 877 | "wandb_config['batch_size'] = 10\n", 878 | "wandb_config['base_lr'] = 0.01\n", 879 | "wandb_config['model_arch'] = 'CustomCNN'\n", 880 | "wandb_config['num_classes'] = 10\n", 881 | "wandb_config['run_name'] = 'assignment_1'\n", 882 | "\n", 883 | "### If you are using a CPU, please set wandb_config['use_gpu'] = 0 below. However, if you are using a GPU, leave it unchanged ####\n", 884 | "wandb_config['use_gpu'] = 1\n", 885 | "\n", 886 | "wandb_config['num_epochs'] = 2\n", 887 | "wandb_config['git_dir'] = git_dir" 888 | ], 889 | "execution_count": null, 890 | "outputs": [] 891 | }, 892 | { 893 | "cell_type": "markdown", 894 | "metadata": { 895 | "id": "pAONDMnApmkR" 896 | }, 897 | "source": [ 898 | "By changing above, different experiments can be run. For example, you can specify which model architecture to load, which dataset you will be loading, and so on." 899 | ] 900 | }, 901 | { 902 | "cell_type": "markdown", 903 | "metadata": { 904 | "id": "cdgYVaVppmkR" 905 | }, 906 | "source": [ 907 | "### Data Loading ###" 908 | ] 909 | }, 910 | { 911 | "cell_type": "markdown", 912 | "metadata": { 913 | "id": "rSeW7ZgopmkS" 914 | }, 915 | "source": [ 916 | "The most common task many of you will be doing in your projects will be running a script on a new dataset. In PyTorch this is done using data loaders, and it is extremely important to understand this works. In next assignment, you will be writing your own dataloader. For now, we only expose you to basic data loading which for the MNIST dataset for which PyTorch provides easy functions." 917 | ] 918 | }, 919 | { 920 | "cell_type": "markdown", 921 | "metadata": { 922 | "id": "fROn07mNpmkS" 923 | }, 924 | "source": [ 925 | "### Let's load MNIST. The first time you run it, the dataset gets downloaded.\n" 926 | ] 927 | }, 928 | { 929 | "cell_type": "markdown", 930 | "metadata": { 931 | "id": "A_f4QqhkpmkT" 932 | }, 933 | "source": [ 934 | "Data Transforms tell PyTorch how to pre-process your data. Recall that images are stored with values between 0-255 usually. One very common pre-processing for images is to normalize to be 0 mean and 1 standard deviation. This pre-processing makes the task easier for neural networks. There are many, many kinds of normalization in deep learning, the most basic one being those imposed on the image data while loading it." 935 | ] 936 | }, 937 | { 938 | "cell_type": "code", 939 | "metadata": { 940 | "id": "1EMBEhsqpmkT" 941 | }, 942 | "source": [ 943 | "data_transforms = {}\n", 944 | "data_transforms['train'] = torchvision.transforms.Compose([\n", 945 | " torchvision.transforms.ToTensor(),\n", 946 | " torchvision.transforms.Normalize(\n", 947 | " (0.1307,), (0.3081,))])\n", 948 | "\n", 949 | "data_transforms['test'] = torchvision.transforms.Compose([\n", 950 | " torchvision.transforms.ToTensor(),\n", 951 | " torchvision.transforms.Normalize(\n", 952 | " (0.1307,), (0.3081,))])" 953 | ], 954 | "execution_count": null, 955 | "outputs": [] 956 | }, 957 | { 958 | "cell_type": "markdown", 959 | "metadata": { 960 | "id": "JuzzYUmjpmkT" 961 | }, 962 | "source": [ 963 | "`torchvision.datasets.MNIST` allows you to load MNIST data. In future, we will be using our own `get_loader` function from above to load custom data. Notice that data_transforms are passed as argument while loading the data below." 964 | ] 965 | }, 966 | { 967 | "cell_type": "code", 968 | "metadata": { 969 | "id": "Cxk66XMTpmkT" 970 | }, 971 | "source": [ 972 | "mnist_dataset = {}\n", 973 | "mnist_dataset['train'] = torchvision.datasets.MNIST('%s/datasets'%wandb_config['git_dir'], train = True, download = True, transform = data_transforms['train'])\n", 974 | "mnist_dataset['test'] = torchvision.datasets.MNIST('%s/datasets'%wandb_config['git_dir'], train = False, download = True, transform = data_transforms['test'])" 975 | ], 976 | "execution_count": null, 977 | "outputs": [] 978 | }, 979 | { 980 | "cell_type": "markdown", 981 | "metadata": { 982 | "id": "5x1f5i2GpmkU" 983 | }, 984 | "source": [ 985 | "#### Dataset vs Dataloader" 986 | ] 987 | }, 988 | { 989 | "cell_type": "markdown", 990 | "metadata": { 991 | "id": "Iv1WGMdfpmkU" 992 | }, 993 | "source": [ 994 | "Most deep learning datasets are huge. Can be as large as million data points. We want to keep our GPUs free to store intermediate calculations for neural networks, like gradients. We would not be able to load a million samples into the GPU (or even CPU) and do forward or backward passes on the network. \n", 995 | "\n", 996 | "So, samples are loaded in batches, and this method of gradient descent is called mini-batch gradient descent. `torch.utils.data.DataLoader` allows you to specify a pytorch dataset, and makes it easy to loop over it in batches. So, we leverage this to create a data loader from our above loaded MNIST dataset. \n", 997 | "\n", 998 | "The dataset itself only contains lists of where to find the inputs and outputs i.e. paths. The data loader defines the logic on loading this information into the GPU/CPU and so it can be passed into the neural net." 999 | ] 1000 | }, 1001 | { 1002 | "cell_type": "code", 1003 | "metadata": { 1004 | "id": "IzAdKbw2pmkU" 1005 | }, 1006 | "source": [ 1007 | "data_loaders = {}\n", 1008 | "data_loaders['train'] = torch.utils.data.DataLoader(mnist_dataset['train'], batch_size = wandb_config['batch_size'], shuffle = True)\n", 1009 | "data_loaders['test'] = torch.utils.data.DataLoader(mnist_dataset['test'], batch_size = wandb_config['batch_size'], shuffle = False)\n", 1010 | "\n", 1011 | "data_sizes = {}\n", 1012 | "data_sizes['train'] = len(mnist_dataset['train'])\n", 1013 | "data_sizes['test'] = len(mnist_dataset['test'])" 1014 | ], 1015 | "execution_count": null, 1016 | "outputs": [] 1017 | }, 1018 | { 1019 | "cell_type": "markdown", 1020 | "metadata": { 1021 | "id": "-39kO7WjpmkU" 1022 | }, 1023 | "source": [ 1024 | "### We will use the `get_model` functionality to load a CNN architecture." 1025 | ] 1026 | }, 1027 | { 1028 | "cell_type": "code", 1029 | "metadata": { 1030 | "id": "4Efu0PhfpmkV" 1031 | }, 1032 | "source": [ 1033 | "model = get_model(wandb_config['model_arch'], wandb_config['num_classes'])" 1034 | ], 1035 | "execution_count": null, 1036 | "outputs": [] 1037 | }, 1038 | { 1039 | "cell_type": "markdown", 1040 | "metadata": { 1041 | "id": "TR9UeMmvpmkV" 1042 | }, 1043 | "source": [ 1044 | "### Curious what the model architecture looks like?\n", 1045 | "\n", 1046 | "`get_model` is just a function in the file `res/models/models.py`. Stop here, open this file, and see what the function does." 1047 | ] 1048 | }, 1049 | { 1050 | "cell_type": "code", 1051 | "metadata": { 1052 | "id": "Ibdp07pSpmkV", 1053 | "colab": { 1054 | "base_uri": "https://localhost:8080/", 1055 | "height": 110, 1056 | "referenced_widgets": [ 1057 | "fca4a46c3e954e9ca38032fe64608be4", 1058 | "88489a8378ff42acbc9be683412fe6dd", 1059 | "b66deffcc82643a6814dd6f018d0f008", 1060 | "922e59fd27c149a39987451c02477453", 1061 | "c8accc853b4c4e9f8b1a5b4b976b4e23" 1062 | ] 1063 | }, 1064 | "outputId": "9417d999-4d49-441d-853f-b33eeb648649" 1065 | }, 1066 | "source": [ 1067 | "layout = widgets.Layout(width='auto', height='90px') #set width and height\n", 1068 | "\n", 1069 | "button = widgets.Button(description=\"Read the function?\\n Click me!\", layout=layout)\n", 1070 | "output = widgets.Output()\n", 1071 | "\n", 1072 | "display(button, output)\n", 1073 | "\n", 1074 | "def on_button_clicked(b):\n", 1075 | " with output:\n", 1076 | " print(\"As you can see, the function simply returns an object of the class CustomCNN, which is defined in res/models/CustomCNN.py\")\n", 1077 | " print(\"This is our neural network model.\")\n", 1078 | "button.on_click(on_button_clicked)" 1079 | ], 1080 | "execution_count": null, 1081 | "outputs": [ 1082 | { 1083 | "output_type": "display_data", 1084 | "data": { 1085 | "application/vnd.jupyter.widget-view+json": { 1086 | "model_id": "fca4a46c3e954e9ca38032fe64608be4", 1087 | "version_minor": 0, 1088 | "version_major": 2 1089 | }, 1090 | "text/plain": [ 1091 | "Button(description='Read the function?\\n Click me!', layout=Layout(height='90px', width='auto'), style=ButtonS…" 1092 | ] 1093 | }, 1094 | "metadata": { 1095 | "tags": [] 1096 | } 1097 | }, 1098 | { 1099 | "output_type": "display_data", 1100 | "data": { 1101 | "application/vnd.jupyter.widget-view+json": { 1102 | "model_id": "922e59fd27c149a39987451c02477453", 1103 | "version_minor": 0, 1104 | "version_major": 2 1105 | }, 1106 | "text/plain": [ 1107 | "Output()" 1108 | ] 1109 | }, 1110 | "metadata": { 1111 | "tags": [] 1112 | } 1113 | } 1114 | ] 1115 | }, 1116 | { 1117 | "cell_type": "markdown", 1118 | "metadata": { 1119 | "id": "UrUbaQqgpmkV" 1120 | }, 1121 | "source": [ 1122 | "#### Below we have the function which trains, tests and returns the best model weights." 1123 | ] 1124 | }, 1125 | { 1126 | "cell_type": "code", 1127 | "metadata": { 1128 | "id": "1baRVJnOpmkV" 1129 | }, 1130 | "source": [ 1131 | "def model_pipeline(model, criterion, optimizer, dset_loaders, dset_sizes, hyperparameters):\n", 1132 | " with wandb.init(project=\"HARVAR_BAI\", config=hyperparameters):\n", 1133 | " if hyperparameters['run_name']:\n", 1134 | " wandb.run.name = hyperparameters['run_name']\n", 1135 | " config = wandb.config\n", 1136 | " best_model = model\n", 1137 | " best_acc = 0.0\n", 1138 | " \n", 1139 | " print(config)\n", 1140 | " \n", 1141 | " print(config.num_epochs)\n", 1142 | " for epoch_num in range(config.num_epochs):\n", 1143 | " wandb.log({\"Current Epoch\": epoch_num})\n", 1144 | " model = train_model(model, criterion, optimizer, dset_loaders, dset_sizes, config)\n", 1145 | " best_acc, best_model = test_model(model, best_acc, best_model, dset_loaders, dset_sizes, config)\n", 1146 | " \n", 1147 | " return best_model" 1148 | ], 1149 | "execution_count": null, 1150 | "outputs": [] 1151 | }, 1152 | { 1153 | "cell_type": "markdown", 1154 | "metadata": { 1155 | "id": "1e7k8r9ypmkW" 1156 | }, 1157 | "source": [ 1158 | "#### The different steps of the train model function are annotated below inside the function. Read them step by step" 1159 | ] 1160 | }, 1161 | { 1162 | "cell_type": "code", 1163 | "metadata": { 1164 | "id": "z_8fxYJ_pmkW" 1165 | }, 1166 | "source": [ 1167 | "def train_model(model, criterion, optimizer, dset_loaders, dset_sizes, configs):\n", 1168 | " print('Starting training epoch...')\n", 1169 | " best_model = model\n", 1170 | " best_acc = 0.0\n", 1171 | "\n", 1172 | " \n", 1173 | " ### This tells python to track gradients. While testing weights aren't updated hence they are not stored.\n", 1174 | " model.train() \n", 1175 | " running_loss = 0.0\n", 1176 | " running_corrects = 0\n", 1177 | " iters = 0\n", 1178 | " \n", 1179 | " \n", 1180 | " ### We loop over the data loader we created above. Simply using a for loop.\n", 1181 | " for data in tqdm(dset_loaders['train']):\n", 1182 | " inputs, labels = data\n", 1183 | " \n", 1184 | " ### If you are using a gpu, then script will move the loaded data to the GPU. \n", 1185 | " ### If you are not using a gpu, ensure that wandb_configs['use_gpu'] is set to False above.\n", 1186 | " if configs.use_gpu:\n", 1187 | " inputs = inputs.float().cuda()\n", 1188 | " labels = labels.long().cuda()\n", 1189 | " else:\n", 1190 | " print('WARNING: NOT USING GPU!')\n", 1191 | " inputs = inputs.float()\n", 1192 | " labels = labels.long()\n", 1193 | "\n", 1194 | " \n", 1195 | " ### We set the gradients to zero, then calculate the outputs, and the loss function. \n", 1196 | " ### Gradients for this process are automatically calculated by PyTorch.\n", 1197 | " \n", 1198 | " optimizer.zero_grad()\n", 1199 | " outputs = model(inputs)\n", 1200 | " _, preds = torch.max(outputs.data, 1)\n", 1201 | "\n", 1202 | " loss = criterion(outputs, labels)\n", 1203 | " \n", 1204 | " \n", 1205 | " ### At this point, the program has calculated gradient of loss w.r.t. weights of our NN model.\n", 1206 | " loss.backward()\n", 1207 | " optimizer.step()\n", 1208 | " \n", 1209 | " ### optimizer.step() updated the models weights using calculated gradients.\n", 1210 | " \n", 1211 | " ### Let's store these and log them using wandb. They will be displayed in a nice online\n", 1212 | " ### dashboard for you to see.\n", 1213 | " \n", 1214 | " iters += 1\n", 1215 | " running_loss += loss.item()\n", 1216 | " running_corrects += torch.sum(preds == labels.data)\n", 1217 | " wandb.log({\"train_running_loss\": running_loss/float(iters*len(labels.data))})\n", 1218 | " wandb.log({\"train_running_corrects\": running_corrects/float(iters*len(labels.data))})\n", 1219 | "\n", 1220 | " epoch_loss = float(running_loss) / dset_sizes['train']\n", 1221 | " epoch_acc = float(running_corrects) / float(dset_sizes['train'])\n", 1222 | " wandb.log({\"train_accuracy\": epoch_acc})\n", 1223 | " wandb.log({\"train_loss\": epoch_loss})\n", 1224 | " return model\n", 1225 | "\n" 1226 | ], 1227 | "execution_count": null, 1228 | "outputs": [] 1229 | }, 1230 | { 1231 | "cell_type": "code", 1232 | "metadata": { 1233 | "id": "qunChCjtpmkW" 1234 | }, 1235 | "source": [ 1236 | "def test_model(model, best_acc, best_model, dset_loaders, dset_sizes, configs):\n", 1237 | " print('Starting testing epoch...')\n", 1238 | " model.eval() ### tells pytorch to not store gradients as we won't be updating weights while testing.\n", 1239 | "\n", 1240 | " running_corrects = 0\n", 1241 | " iters = 0 \n", 1242 | " for data in tqdm(dset_loaders['test']):\n", 1243 | " inputs, labels = data\n", 1244 | " if configs.use_gpu:\n", 1245 | " inputs = inputs.float().cuda()\n", 1246 | " labels = labels.long().cuda()\n", 1247 | " else:\n", 1248 | " print('WARNING: NOT USING GPU!')\n", 1249 | " inputs = inputs.float()\n", 1250 | " labels = labels.long()\n", 1251 | "\n", 1252 | " \n", 1253 | " outputs = model(inputs)\n", 1254 | " _, preds = torch.max(outputs.data, 1)\n", 1255 | " \n", 1256 | " iters += 1\n", 1257 | " running_corrects += torch.sum(preds == labels.data)\n", 1258 | " wandb.log({\"train_running_corrects\": running_corrects/float(iters*len(labels.data))})\n", 1259 | "\n", 1260 | "\n", 1261 | " epoch_acc = float(running_corrects) / float(dset_sizes['test'])\n", 1262 | "\n", 1263 | " wandb.log({\"test_accuracy\": epoch_acc})\n", 1264 | " \n", 1265 | " ### Code is very similar to train set. One major difference, we don't update weights. \n", 1266 | " ### We only check the performance is best so far, if so, we save this model as the best model so far.\n", 1267 | " \n", 1268 | " if epoch_acc > best_acc:\n", 1269 | " best_acc = epoch_acc\n", 1270 | " best_model = copy.deepcopy(model)\n", 1271 | " wandb.log({\"best_accuracy\": best_acc})\n", 1272 | " \n", 1273 | " return best_acc, best_model\n", 1274 | " " 1275 | ], 1276 | "execution_count": null, 1277 | "outputs": [] 1278 | }, 1279 | { 1280 | "cell_type": "markdown", 1281 | "metadata": { 1282 | "id": "3MTFyOmoL1Tu" 1283 | }, 1284 | "source": [ 1285 | "# Make sure your runtime is GPU. If you changed your run time, make sure to run your code again from the top." 1286 | ] 1287 | }, 1288 | { 1289 | "cell_type": "code", 1290 | "metadata": { 1291 | "id": "91_E7yQ8pmkY", 1292 | "colab": { 1293 | "base_uri": "https://localhost:8080/", 1294 | "height": 331 1295 | }, 1296 | "outputId": "6b6a18bd-58c1-4eff-95e3-e4b028ac3c8c" 1297 | }, 1298 | "source": [ 1299 | "### Criterion is simply specifying what loss to use. Here we choose cross entropy loss. \n", 1300 | "criterion = nn.CrossEntropyLoss()\n", 1301 | "\n", 1302 | "### tells what optimizer to use. There are many options, we here choose Adam.\n", 1303 | "### the main difference between optimizers is that they vary in how weights are updated based on calculated gradients.\n", 1304 | "optimizer_ft = optim.Adam(model.parameters(), lr = wandb_config['base_lr'])\n", 1305 | "\n", 1306 | "if wandb_config['use_gpu']:\n", 1307 | " criterion.cuda()\n", 1308 | " model.cuda()" 1309 | ], 1310 | "execution_count": null, 1311 | "outputs": [ 1312 | { 1313 | "output_type": "error", 1314 | "ename": "RuntimeError", 1315 | "evalue": "ignored", 1316 | "traceback": [ 1317 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 1318 | "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", 1319 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mwandb_config\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'use_gpu'\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 9\u001b[0m \u001b[0mcriterion\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\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[0;32m---> 10\u001b[0;31m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\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", 1320 | "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36mcuda\u001b[0;34m(self, device)\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mModule\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 462\u001b[0m \"\"\"\n\u001b[0;32m--> 463\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\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 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 465\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcpu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mT\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mT\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 1321 | "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, fn)\u001b[0m\n\u001b[1;32m 357\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn\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 358\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mmodule\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mchildren\u001b[0m\u001b[0;34m(\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[0;32m--> 359\u001b[0;31m \u001b[0mmodule\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfn\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 360\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcompute_should_use_set_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtensor\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtensor_applied\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", 1322 | "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_apply\u001b[0;34m(self, fn)\u001b[0m\n\u001b[1;32m 379\u001b[0m \u001b[0;31m# `with torch.no_grad():`\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 380\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mno_grad\u001b[0m\u001b[0;34m(\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[0;32m--> 381\u001b[0;31m \u001b[0mparam_applied\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam\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 382\u001b[0m \u001b[0mshould_use_set_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompute_should_use_set_data\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparam_applied\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 383\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mshould_use_set_data\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 1323 | "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m\u001b[0;34m(t)\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mModule\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 462\u001b[0m \"\"\"\n\u001b[0;32m--> 463\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_apply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcuda\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdevice\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 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 465\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcpu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mT\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0mT\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 1324 | "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/torch/cuda/__init__.py\u001b[0m in \u001b[0;36m_lazy_init\u001b[0;34m()\u001b[0m\n\u001b[1;32m 170\u001b[0m \u001b[0;31m# This function throws if there's a driver initialization error, no GPUs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 171\u001b[0m \u001b[0;31m# are found or any other error occurs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 172\u001b[0;31m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_C\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cuda_init\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 173\u001b[0m \u001b[0;31m# Some of the queued calls may reentrantly call _lazy_init();\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 174\u001b[0m \u001b[0;31m# we need to just return without initializing in that case.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 1325 | "\u001b[0;31mRuntimeError\u001b[0m: No CUDA GPUs are available" 1326 | ] 1327 | } 1328 | ] 1329 | }, 1330 | { 1331 | "cell_type": "code", 1332 | "metadata": { 1333 | "id": "Yt5ctNudpmkY" 1334 | }, 1335 | "source": [ 1336 | "### Creating the folder where our models will be saved.\n", 1337 | "if not os.path.isdir(\"%s/saved_models/\"%wandb_config['git_dir']):\n", 1338 | " os.mkdir(\"%s/saved_models/\"%wandb_config['git_dir'])" 1339 | ], 1340 | "execution_count": null, 1341 | "outputs": [] 1342 | }, 1343 | { 1344 | "cell_type": "code", 1345 | "metadata": { 1346 | "id": "accYgj_-pmkY", 1347 | "colab": { 1348 | "base_uri": "https://localhost:8080/", 1349 | "height": 214, 1350 | "referenced_widgets": [ 1351 | "dbeb947a70814510976ef5fd8e34f295", 1352 | "45d3b0afa0f14a07b20fc371acd3ba6b", 1353 | "52abe6174af24061831094b1207cd843", 1354 | "e1d9b05fed70487a93aeb75e81726e4c", 1355 | "bcdfb20486404cd8aac5efaa70b8ba2b", 1356 | "55a8da2af315484cbee80493aa0a2d34", 1357 | "8ed09a2afd9b4dc59ecf92df757d1b53", 1358 | "021623db8dbb48328ee893b3794886b1" 1359 | ] 1360 | }, 1361 | "outputId": "526c3436-219d-435d-ce45-ad96a1162b7b" 1362 | }, 1363 | "source": [ 1364 | "### Let's run it all, and save the final best model.\n", 1365 | "\n", 1366 | "\n", 1367 | "best_final_model = model_pipeline(model, criterion, optimizer_ft, data_loaders, data_sizes, wandb_config)\n", 1368 | "\n", 1369 | "\n", 1370 | "save_path = '%s/saved_models/%s_final.pt'%(wandb_config['git_dir'], wandb_config['run_name'])\n", 1371 | "with open(save_path,'wb') as F:\n", 1372 | " torch.save(best_final_model,F)" 1373 | ], 1374 | "execution_count": null, 1375 | "outputs": [ 1376 | { 1377 | "output_type": "stream", 1378 | "text": [ 1379 | "\u001b[34m\u001b[1mwandb\u001b[0m: Currently logged in as: \u001b[33mspandanmadan\u001b[0m (use `wandb login --relogin` to force relogin)\n" 1380 | ], 1381 | "name": "stderr" 1382 | }, 1383 | { 1384 | "output_type": "display_data", 1385 | "data": { 1386 | "text/html": [ 1387 | "\n", 1388 | " Tracking run with wandb version 0.10.17
\n", 1389 | " Syncing run morning-frog-7 to Weights & Biases (Documentation).
\n", 1390 | " Project page: https://wandb.ai/spandanmadan/HARVAR_BAI
\n", 1391 | " Run page: https://wandb.ai/spandanmadan/HARVAR_BAI/runs/1aluism0
\n", 1392 | " Run data is saved locally in /content/wandb/run-20210203_235533-1aluism0

\n", 1393 | " " 1394 | ], 1395 | "text/plain": [ 1396 | "" 1397 | ] 1398 | }, 1399 | "metadata": { 1400 | "tags": [] 1401 | } 1402 | }, 1403 | { 1404 | "output_type": "stream", 1405 | "text": [ 1406 | "{'batch_size': 10, 'base_lr': 0.01, 'model_arch': 'CustomCNN', 'num_classes': 10, 'run_name': 'assignment_1', 'use_gpu': 1, 'num_epochs': 2, 'git_dir': '/content/drive/MyDrive/Harvard_BAI'}\n", 1407 | "2\n", 1408 | "Starting training epoch...\n" 1409 | ], 1410 | "name": "stdout" 1411 | }, 1412 | { 1413 | "output_type": "display_data", 1414 | "data": { 1415 | "application/vnd.jupyter.widget-view+json": { 1416 | "model_id": "dbeb947a70814510976ef5fd8e34f295", 1417 | "version_minor": 0, 1418 | "version_major": 2 1419 | }, 1420 | "text/plain": [ 1421 | "HBox(children=(FloatProgress(value=0.0, max=6000.0), HTML(value='')))" 1422 | ] 1423 | }, 1424 | "metadata": { 1425 | "tags": [] 1426 | } 1427 | } 1428 | ] 1429 | }, 1430 | { 1431 | "cell_type": "markdown", 1432 | "metadata": { 1433 | "id": "zcxInTMApmkZ" 1434 | }, 1435 | "source": [ 1436 | "### Congratulations!\n", 1437 | "\n", 1438 | "You just completed your first deep learning program - image classification for MNIST. This wraps up assignment 1. In the next assignment, we will see how you can make changes to above mentioned folders/files to adapt this code-base to your own research project." 1439 | ] 1440 | }, 1441 | { 1442 | "cell_type": "markdown", 1443 | "metadata": { 1444 | "id": "tUC8UOzYpmkZ" 1445 | }, 1446 | "source": [ 1447 | "# Deliverables for Assignment 1: \n", 1448 | "\n", 1449 | "### Please run this assignment through to the end, and then make two submissions:\n", 1450 | "\n", 1451 | "- Download this notebook as an HTML file. Click File ---> Download as ---> HTML. Submit this on canvas.\n", 1452 | "- Add, commit and push these changes to your github repository." 1453 | ] 1454 | } 1455 | ] 1456 | } --------------------------------------------------------------------------------