├── README.md ├── Week1 ├── READMe.txt ├── W1.1_Introduction.pptx └── W1.2_Introduction.pptx ├── Week12 ├── GNN.png └── WOA7015_Wk12.ipynb ├── Week2 ├── CoinFlip.png ├── EstimatePiFromCircleSquare.png ├── Exercise3_Multivariate_Image.png ├── READMe.txt ├── W2_FoundationI.pptx └── WOA7015_Wk2.ipynb ├── Week3 ├── READMe.txt ├── W3.pptx ├── WOA7015_Wk3.ipynb └── XOR.jpg ├── Week4 ├── MnistExamples.png ├── README ├── W4.pptx └── WOA7015_Wk4.ipynb ├── Week5 ├── CV.png ├── CV_test.png ├── W5.pptx ├── WOA7015_Wk5.ipynb ├── iris.PNG └── train_test.png ├── Week6 ├── W6.pptx └── WOA7015_Wk6.ipynb ├── Week7 └── W7.pptx ├── Week8 └── W8.pptx └── Week9 ├── Adj_matrix.PNG ├── Message_passing.PNG ├── W9.pptx ├── WOA7015_Wk9.ipynb └── WOA7015_Wk9_Extra.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # Advanced_ML 2 | 3 | The teaching materials developed here is inspired from 4 | 1. Kevin Murphy - https://probml.github.io/pml-book/book1.html 5 | 6 | -------------------------------------------------------------------------------- /Week1/READMe.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Week1/W1.1_Introduction.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week1/W1.1_Introduction.pptx -------------------------------------------------------------------------------- /Week1/W1.2_Introduction.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week1/W1.2_Introduction.pptx -------------------------------------------------------------------------------- /Week12/GNN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week12/GNN.png -------------------------------------------------------------------------------- /Week2/CoinFlip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week2/CoinFlip.png -------------------------------------------------------------------------------- /Week2/EstimatePiFromCircleSquare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week2/EstimatePiFromCircleSquare.png -------------------------------------------------------------------------------- /Week2/Exercise3_Multivariate_Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week2/Exercise3_Multivariate_Image.png -------------------------------------------------------------------------------- /Week2/READMe.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Week2/W2_FoundationI.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week2/W2_FoundationI.pptx -------------------------------------------------------------------------------- /Week2/WOA7015_Wk2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "provenance": [], 7 | "collapsed_sections": [], 8 | "authorship_tag": "ABX9TyMPAj70b1tfVLCW+dBMWfV9", 9 | "include_colab_link": true 10 | }, 11 | "kernelspec": { 12 | "display_name": "Python 3", 13 | "name": "python3" 14 | }, 15 | "language_info": { 16 | "name": "python" 17 | } 18 | }, 19 | "cells": [ 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "id": "view-in-github", 24 | "colab_type": "text" 25 | }, 26 | "source": [ 27 | "\"Open" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": { 33 | "id": "HLjtuMaImRla" 34 | }, 35 | "source": [ 36 | "# Welcome to WOA7015 Advance Machine Learning Lab - Week 2 \n", 37 | "This code is generated for the purpose of WOA7015 module.\n", 38 | "The code is available in github https://github.com/shiernee/Advanced_ML \n" 39 | ] 40 | }, 41 | { 42 | "cell_type": "markdown", 43 | "metadata": { 44 | "id": "Jxdp_95lYsoV" 45 | }, 46 | "source": [ 47 | "# The Gaussian Distribution\n", 48 | "\n", 49 | "The p.d.f of random variable $Z$ with a gaussian / normal distribution is shown below\n", 50 | "\n", 51 | "$$ p(z) = \\frac{1}{\\sqrt{2\\pi}} e^{-z^2 / 2}. $$\n", 52 | "\n", 53 | "It is defined for all real values $z$, from $-\\infty$ to $\\infty$.\n", 54 | "\n", 55 | "The distribution looks like this:" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "metadata": { 61 | "colab": { 62 | "background_save": true 63 | }, 64 | "id": "MPLuZCPQZ9cK" 65 | }, 66 | "source": [ 67 | "# import symbulate https://dlsun.github.io/symbulate/index.html \n", 68 | "\n", 69 | "!pip install -q symbulate\n", 70 | "from symbulate import *" 71 | ], 72 | "execution_count": null, 73 | "outputs": [] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "metadata": { 78 | "colab": { 79 | "base_uri": "https://localhost:8080/", 80 | "height": 257 81 | }, 82 | "id": "QBS_72HxYozq", 83 | "outputId": "f571f724-7a9b-418e-b1f8-843cd5ce2c77" 84 | }, 85 | "source": [ 86 | "Normal().plot()" 87 | ], 88 | "execution_count": null, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "image/png": "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\n", 93 | "text/plain": [ 94 | "
" 95 | ] 96 | }, 97 | "metadata": {}, 98 | "output_type": "display_data" 99 | } 100 | ] 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "metadata": { 105 | "id": "4jjeZ6B4ZNfI" 106 | }, 107 | "source": [ 108 | "### Expected Value\n", 109 | "\n", 110 | "The expected value of a standard normal random variable, $E[Z]$, is...\n" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "metadata": { 116 | "colab": { 117 | "background_save": true 118 | }, 119 | "id": "mt-8KUGKZRct", 120 | "outputId": "34924efb-6deb-49a2-ca0c-4f0db325cc53" 121 | }, 122 | "source": [ 123 | "Normal().mean()" 124 | ], 125 | "execution_count": null, 126 | "outputs": [ 127 | { 128 | "data": { 129 | "text/plain": [ 130 | "0.0" 131 | ] 132 | }, 133 | "execution_count": null, 134 | "metadata": {}, 135 | "output_type": "execute_result" 136 | } 137 | ] 138 | }, 139 | { 140 | "cell_type": "markdown", 141 | "metadata": { 142 | "id": "IR_V8vj5ZS5s" 143 | }, 144 | "source": [ 145 | "### Variance\n", 146 | "\n", 147 | "The variance of a standard normal random variable, $\\text{Var}[Z]$, is..." 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "metadata": { 153 | "id": "hcrji_ZGZU-u" 154 | }, 155 | "source": [ 156 | "Normal().var()" 157 | ], 158 | "execution_count": null, 159 | "outputs": [] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "metadata": { 164 | "id": "K0RWPxPoZYT1" 165 | }, 166 | "source": [ 167 | "## The (General) Normal Distribution\n", 168 | "\n", 169 | "The standard normal distribution is centered at 0 with a variance of 1. In general, we can\n", 170 | "- scale the bell shape to be as wide as we want, \n", 171 | "- shift the bell shape to be centered wherever we want.\n", 172 | "\n", 173 | "If $Z$ is standard normal, then \n", 174 | "$$ X = \\mu + \\sigma Z $$\n", 175 | "is $\\text{Normal}(\\mu, \\sigma)$. The parameter $\\mu$ is the expected value, and the parameter $\\sigma$ is the standard deviation. (So $\\sigma^2$ is the variance.)" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": { 181 | "id": "-vWADOjsbZ4i" 182 | }, 183 | "source": [ 184 | "## Exercise 1\n", 185 | "Generate a normal distribution with \n", 186 | "1. mean=1, stdev=0.25\n", 187 | "2. mean=1, stdev=0.5\n", 188 | "3. mean=1, stdev=0.75\n", 189 | "4. mean=3, stdev=0.25\n", 190 | "5. mean=3, stdev=0.5\n", 191 | "6. mean=3, stdev=0.75\n", 192 | "\n", 193 | "in the same plot with different colors with legends." 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "metadata": { 199 | "id": "R6kAL_mAekJp" 200 | }, 201 | "source": [ 202 | "# Your code here" 203 | ], 204 | "execution_count": null, 205 | "outputs": [] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "metadata": { 210 | "cellView": "form", 211 | "id": "3Hyw2KPXfobM" 212 | }, 213 | "source": [ 214 | "#@title ## Exercise 1 Solution - Try yourself first.\n", 215 | "\n", 216 | "legend_list = []\n", 217 | "for m in [1, 3]:\n", 218 | " for sd in [0.25, 0.5, 0.75]:\n", 219 | " Normal(mean=m, sd=sd).plot()\n", 220 | " legend_list.append([\"mean=%d sd=%0.2f\" %(m, sd)])\n", 221 | "\n", 222 | "\n", 223 | "import matplotlib.pyplot as plt\n", 224 | "plt.legend(legend_list)" 225 | ], 226 | "execution_count": null, 227 | "outputs": [] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": { 232 | "id": "70GimY8YZDsW" 233 | }, 234 | "source": [ 235 | "# Probability\n", 236 | "\n", 237 | "To calculate probabilities, we integrate the p.d.f. over the relevant region. For example,\n", 238 | "\n", 239 | "$$ P(Z \\leq 1) = \\int_{-\\infty}^1 \\frac{1}{\\sqrt{2\\pi}} e^{-z^2 / 2}\\,dz. $$\n", 240 | "\n", 241 | "Unlike other continuous distributions we have studied, the p.d.f. $p(z)$ has no elementary antiderivative. That means that you will not be able to evaluate this integral by paper and pencil, using techniques you learned in calculus. It has to be evaluated numerically. Fortunately, you can do this easily in Symbulate. \n", 242 | "\n", 243 | "For example, $P(Z \\leq 1)$ is just the c.d.f. evaluated at $1$. The c.d.f. of the standard normal distribution is often represented by $\\Phi(z)$. So we need to calculate $\\Phi(1)$." 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "metadata": { 249 | "id": "VdEJLbBhZJFx" 250 | }, 251 | "source": [ 252 | "Normal().cdf(1)" 253 | ], 254 | "execution_count": null, 255 | "outputs": [] 256 | }, 257 | { 258 | "cell_type": "markdown", 259 | "metadata": { 260 | "id": "SM7-6Y98ZK3f" 261 | }, 262 | "source": [ 263 | "## Exercise 2:\n", 264 | "How would you calculate $P(-2 < Z < 2)$?" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "metadata": { 270 | "id": "BJCxH08IZOBx" 271 | }, 272 | "source": [ 273 | "# YOUR CODE HERE\n" 274 | ], 275 | "execution_count": null, 276 | "outputs": [] 277 | }, 278 | { 279 | "cell_type": "code", 280 | "metadata": { 281 | "cellView": "form", 282 | "id": "7DJQ7MKMgLYs" 283 | }, 284 | "source": [ 285 | "#@title Solution 2 - Try yourself first \n", 286 | "# P(-2 < Z < 2) = P(Z < 2) - P(Z < -2)\n", 287 | "\n", 288 | "Normal().cdf([2]) - Normal().cdf([-2]) \n" 289 | ], 290 | "execution_count": null, 291 | "outputs": [] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "metadata": { 296 | "id": "qplX9C0R2xiO" 297 | }, 298 | "source": [ 299 | "# Monte Carlo Approximation \n", 300 | "\n", 301 | "## Example 1: Coin Flip Example\n", 302 | "\n", 303 | "The probability of head for a fair coin is 1/2. Monte-Carlo method to simulate the coin-flipping iteratively 5000 times to find out why the probability of a head or tail is always 1/2. \n", 304 | "\n", 305 | "" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "metadata": { 311 | "id": "VDZ8iQzRDetH" 312 | }, 313 | "source": [ 314 | "# import require libraries\n", 315 | "import random\n", 316 | "import numpy as np\n", 317 | "import matplotlib.pyplot as plt\n" 318 | ], 319 | "execution_count": null, 320 | "outputs": [] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "metadata": { 325 | "id": "E51dVvVuDlCv" 326 | }, 327 | "source": [ 328 | "# coin flip function:\n", 329 | "# 0 --> Head\n", 330 | "# 1 --> Tail\n", 331 | "\n", 332 | "def coin_flip():\n", 333 | " return random.randint(0, 1)\n", 334 | "\n", 335 | "# check the output of coin_flip\n", 336 | "for i in range(10):\n", 337 | " print('iteration' + str(i) + '--> ' + str(coin_flip()))" 338 | ], 339 | "execution_count": null, 340 | "outputs": [] 341 | }, 342 | { 343 | "cell_type": "code", 344 | "metadata": { 345 | "id": "FNTszy01EA7C" 346 | }, 347 | "source": [ 348 | "# Monte Carlo Simulation\n", 349 | "list1= []\n", 350 | "\n", 351 | "def monte_carlo(n):\n", 352 | " results = 0\n", 353 | " plt.axhline(y=0.5, color='r', linestyle='-')\n", 354 | "\n", 355 | " for i in range(n):\n", 356 | " flip_result = coin_flip()\n", 357 | " results = results + flip_result\n", 358 | "\n", 359 | " # calculate probabibility valuue\n", 360 | " prob_value = results / (i+1)\n", 361 | "\n", 362 | " # append probability to list1\n", 363 | " list1.append(prob_value)\n", 364 | "\n", 365 | " # plot results \n", 366 | " plt.xlabel('iteration')\n", 367 | " plt.ylabel('probability')\n", 368 | " plt.plot(list1)\n", 369 | "\n", 370 | " return results / n" 371 | ], 372 | "execution_count": null, 373 | "outputs": [] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "metadata": { 378 | "id": "OIgkm927Eiml" 379 | }, 380 | "source": [ 381 | "# call monte carlo functioin\n", 382 | "answer = monte_carlo(10000)\n", 383 | "print('final value of probability: ', answer)" 384 | ], 385 | "execution_count": null, 386 | "outputs": [] 387 | }, 388 | { 389 | "cell_type": "markdown", 390 | "metadata": { 391 | "id": "uq4nxGfCI5U9" 392 | }, 393 | "source": [ 394 | "# Example 2: Estimating Pi from Circle and Square\n", 395 | "\n", 396 | "To know about the history of pi - read https://www.scientificamerican.com/article/what-is-pi-and-how-did-it-originate/
\n", 397 | "\n", 398 | " To estimate the value of Pi, we can use the area of circle and square. \n", 399 | "$$ \\frac{Area \\ Circle}{Area \\ Square} = \\frac{\\pi*r^2}{2r * 2r} $$
\n", 400 | "$$ \\frac{Area \\ Circle}{Area \\ Square} = \\frac{\\pi}{4} $$
\n", 401 | "\n", 402 | "$\\pi$ value can be estimate using the following formula\n", 403 | "$$ \\pi = 4* \\frac{Area \\ Circle}{Area \\ Square} $$\n", 404 | "\n", 405 | "\n", 406 | " \n", 407 | "\n", 408 | "Assuming r = 0.5\n", 409 | "\n", 410 | "length_of_field = 2r = 1.0\n", 411 | "\n" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "metadata": { 417 | "id": "IDsUuJvXNsHl" 418 | }, 419 | "source": [ 420 | "import turtle\n", 421 | "from random import random \n", 422 | "import matplotlib.pyplot as plt\n", 423 | "import math" 424 | ], 425 | "execution_count": null, 426 | "outputs": [] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "metadata": { 431 | "id": "YC4A6swHNwUK" 432 | }, 433 | "source": [ 434 | "# simulate raindrop \n", 435 | "# return x and y coordinates of raindrop\n", 436 | "\n", 437 | "def rain_drop(length_of_field=1):\n", 438 | " \"\"\"\n", 439 | " Simulate a random rain drop\n", 440 | " \"\"\"\n", 441 | " return [(.5 - random()) * length_of_field, (.5 - random()) * length_of_field]\n" 442 | ], 443 | "execution_count": null, 444 | "outputs": [] 445 | }, 446 | { 447 | "cell_type": "code", 448 | "metadata": { 449 | "id": "FSjfm-qKOBo7" 450 | }, 451 | "source": [ 452 | "# check if raindrop fall in circle by using circle formula \n", 453 | "\n", 454 | "def is_point_in_circle(point, length_of_field=1):\n", 455 | " \"\"\"\n", 456 | " Return True if point is in inscribed circle\n", 457 | " Use circle formula --> x^2 + y^2 <= r^2\n", 458 | " \"\"\"\n", 459 | " return (point[0]) ** 2 + (point[1]) ** 2 <= (length_of_field / 2) ** 2" 460 | ], 461 | "execution_count": null, 462 | "outputs": [] 463 | }, 464 | { 465 | "cell_type": "code", 466 | "metadata": { 467 | "id": "Siq4wlDBOCf4" 468 | }, 469 | "source": [ 470 | "def plot_rain_drops(drops_in_circle, drops_out_of_circle, length_of_field=1, format='pdf'):\n", 471 | " \"\"\" Function to draw rain drops \"\"\"\n", 472 | " number_of_drops_in_circle = len(drops_in_circle)\n", 473 | " number_of_drops_out_of_circle = len(drops_out_of_circle)\n", 474 | " number_of_drops = number_of_drops_in_circle + number_of_drops_out_of_circle\n", 475 | " plt.figure()\n", 476 | " plt.xlim(-length_of_field / 2, length_of_field / 2)\n", 477 | " plt.ylim(-length_of_field / 2, length_of_field / 2)\n", 478 | " plt.scatter([e[0] for e in drops_in_circle], [e[1] for e in drops_in_circle], color='blue', label=\"Drops in circle\")\n", 479 | " plt.scatter([e[0] for e in drops_out_of_circle], [e[1] for e in drops_out_of_circle], color='black', label=\"Drops out of circle\")\n", 480 | " plt.legend(loc=\"center\")\n", 481 | " plt.title(\"%s drops: %s landed in circle, estimating $\\pi$ as %.4f.\" % (number_of_drops, number_of_drops_in_circle, 4 * number_of_drops_in_circle / number_of_drops))\n", 482 | " plt.savefig(\"%s_drops.%s\" % (number_of_drops, format))\n" 483 | ], 484 | "execution_count": null, 485 | "outputs": [] 486 | }, 487 | { 488 | "cell_type": "code", 489 | "metadata": { 490 | "id": "6J5qnEUKOFQS" 491 | }, 492 | "source": [ 493 | "# simulate raindrop \n", 494 | "# return total number of raindrop in circle and in square\n", 495 | "\n", 496 | "def rain(number_of_drops=1000, length_of_field=1, plot=True, format='pdf', dynamic=False):\n", 497 | " \"\"\"\n", 498 | " Function to make rain drops.\n", 499 | " \"\"\"\n", 500 | " number_of_drops_in_circle = 0\n", 501 | " drops_in_circle = []\n", 502 | " drops_out_of_circle = []\n", 503 | " pi_estimate = []\n", 504 | " for k in range(number_of_drops):\n", 505 | " d = (rain_drop(length_of_field))\n", 506 | " if is_point_in_circle(d, length_of_field):\n", 507 | " drops_in_circle.append(d)\n", 508 | " number_of_drops_in_circle += 1\n", 509 | " else:\n", 510 | " drops_out_of_circle.append(d)\n", 511 | " if dynamic: # The dynamic option if set to True will plot every new drop (this can be used to create animations of the simulation)\n", 512 | " print(\"Plotting drop number: %s\" % (k + 1))\n", 513 | " plot_rain_drops(drops_in_circle, drops_out_of_circle, length_of_field, format)\n", 514 | " pi_estimate.append(4 * number_of_drops_in_circle / (k + 1)) # This updates the list with the newest estimate for pi.\n", 515 | " # Plot the pi estimates\n", 516 | " plt.figure()\n", 517 | " plt.scatter(range(1, number_of_drops + 1), pi_estimate)\n", 518 | " max_x = plt.xlim()[1]\n", 519 | " plt.hlines(math.pi, 0, max_x, color='black')\n", 520 | " plt.xlim(0, max_x)\n", 521 | " plt.title(\"$\\pi$ estimate against number of rain drops\")\n", 522 | " plt.xlabel(\"Number of rain drops\")\n", 523 | " plt.ylabel(\"$\\pi$\")\n", 524 | " # plt.savefig(\"Pi_estimate_for_%s_drops_thrown.pdf\" % number_of_drops)\n", 525 | "\n", 526 | " if plot and not dynamic:\n", 527 | " # If the plot option is passed and matplotlib is installed this plots\n", 528 | " # the final set of drops\n", 529 | " plot_rain_drops(drops_in_circle, drops_out_of_circle, length_of_field, format)\n", 530 | "\n", 531 | " return [number_of_drops_in_circle, number_of_drops]\n" 532 | ], 533 | "execution_count": null, 534 | "outputs": [] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "metadata": { 539 | "colab": { 540 | "base_uri": "https://localhost:8080/", 541 | "height": 632 542 | }, 543 | "id": "yLLV4UstOHQ7", 544 | "outputId": "04e1adfe-25fa-4527-d301-b3657fc56027" 545 | }, 546 | "source": [ 547 | "# call the function \n", 548 | "number_of_drops = 500\n", 549 | "r = rain(number_of_drops, plot=True, format='png', dynamic=False)\n", 550 | "\n", 551 | "print(\"----------------------\")\n", 552 | "print(\"%s drops\" % number_of_drops)\n", 553 | "print(\"pi estimated as: %s \" % (4 * r[0] / r[1]))\n", 554 | "print(\"----------------------\")" 555 | ], 556 | "execution_count": null, 557 | "outputs": [ 558 | { 559 | "output_type": "stream", 560 | "name": "stdout", 561 | "text": [ 562 | "----------------------\n", 563 | "500 drops\n", 564 | "pi estimated as: 3.128 \n", 565 | "----------------------\n" 566 | ] 567 | }, 568 | { 569 | "output_type": "display_data", 570 | "data": { 571 | "text/plain": [ 572 | "
" 573 | ], 574 | "image/png": "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\n" 575 | }, 576 | "metadata": { 577 | "needs_background": "light" 578 | } 579 | }, 580 | { 581 | "output_type": "display_data", 582 | "data": { 583 | "text/plain": [ 584 | "
" 585 | ], 586 | "image/png": "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\n" 587 | }, 588 | "metadata": { 589 | "needs_background": "light" 590 | } 591 | } 592 | ] 593 | }, 594 | { 595 | "cell_type": "markdown", 596 | "metadata": { 597 | "id": "Si-mUBcUSuJr" 598 | }, 599 | "source": [ 600 | "## Now try increasing number_of_drops and check the value of $\\pi$. \n", 601 | "\n", 602 | "## At what value of number_of_drops does the $\\pi$ value approaches 3.14? Write down your answer below. " 603 | ] 604 | }, 605 | { 606 | "cell_type": "code", 607 | "metadata": { 608 | "id": "Fu1QGY8gTHxa" 609 | }, 610 | "source": [ 611 | "# write your answer here. \n" 612 | ], 613 | "execution_count": null, 614 | "outputs": [] 615 | }, 616 | { 617 | "cell_type": "markdown", 618 | "metadata": { 619 | "id": "gcHiPdooiubi" 620 | }, 621 | "source": [ 622 | "# ***Let's go back to power point - slide 22***" 623 | ] 624 | }, 625 | { 626 | "cell_type": "markdown", 627 | "metadata": { 628 | "id": "0-_f8CZnVmYO" 629 | }, 630 | "source": [ 631 | "# Multivariate Gaussian Distribution\n", 632 | "\n", 633 | "For two continuous random variables, plot type density uses the simulated $ (x,y)$ to estimate the joint probability density function and plot it.\n", 634 | "\n", 635 | "### Example. Assume
\n", 636 | "mean of X = 1, mean of Y = 2
\n", 637 | "variance of X = 2, variance of Y = 4
\n", 638 | "covariance of xy and yx = 1" 639 | ] 640 | }, 641 | { 642 | "cell_type": "code", 643 | "metadata": { 644 | "id": "lY6YpCNPVpsk" 645 | }, 646 | "source": [ 647 | "mu = [1, 2]\n", 648 | "Sigma = [[2, 1],\n", 649 | " [1, 4]]\n", 650 | "\n", 651 | "X, Y = RV(MultivariateNormal(mean = mu, cov = Sigma))\n", 652 | "Z = X + Y\n" 653 | ], 654 | "execution_count": null, 655 | "outputs": [] 656 | }, 657 | { 658 | "cell_type": "code", 659 | "metadata": { 660 | "colab": { 661 | "background_save": true 662 | }, 663 | "id": "9FVnrgThbEyw", 664 | "outputId": "77a76ae7-3984-45c2-e022-cdfda14d3eae" 665 | }, 666 | "source": [ 667 | "# understand each output \n", 668 | "\n", 669 | "x = X.sim(10000)\n", 670 | "y = Y.sim(10000)\n", 671 | "z = Z.sim(10000)\n", 672 | "print('X mean:', x.mean())\n", 673 | "print('Y mean:', y.mean())\n", 674 | "print('Z mean:', z.mean())\n", 675 | "print('X variance:', x.sd()**2)\n", 676 | "print('Y variance:', y.sd()**2)\n", 677 | "print('Z variance:', z.sd()**2)\n" 678 | ], 679 | "execution_count": null, 680 | "outputs": [ 681 | { 682 | "name": "stdout", 683 | "output_type": "stream", 684 | "text": [ 685 | "X mean: 1.0258520182513167\n", 686 | "Y mean: 1.9758308752410725\n", 687 | "Z mean: 2.984547830463785\n", 688 | "X variance: 1.9987250660153855\n", 689 | "Y variance: 4.012078198155444\n", 690 | "Z variance: 8.089690367918754\n" 691 | ] 692 | } 693 | ] 694 | }, 695 | { 696 | "cell_type": "code", 697 | "metadata": { 698 | "colab": { 699 | "background_save": true 700 | }, 701 | "id": "BP6E_Ytdd7Km", 702 | "outputId": "60487e35-a564-46c6-df2e-70e0e2d5056b" 703 | }, 704 | "source": [ 705 | "(X & Y).sim(10000).plot(type=\"density\")" 706 | ], 707 | "execution_count": null, 708 | "outputs": [ 709 | { 710 | "data": { 711 | "image/png": "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\n", 712 | "text/plain": [ 713 | "
" 714 | ] 715 | }, 716 | "metadata": {}, 717 | "output_type": "display_data" 718 | } 719 | ] 720 | }, 721 | { 722 | "cell_type": "markdown", 723 | "metadata": { 724 | "id": "VPiOeOD1a-FF" 725 | }, 726 | "source": [ 727 | "# Exercise 3 \n", 728 | "Generate the Multivariate Gaussian as shown below given variance of X = 2, variance of Y = 4\n", 729 | "\n", 730 | " " 731 | ] 732 | }, 733 | { 734 | "cell_type": "code", 735 | "metadata": { 736 | "colab": { 737 | "background_save": true 738 | }, 739 | "id": "0fYiOs5_lVBl" 740 | }, 741 | "source": [ 742 | "# your code here" 743 | ], 744 | "execution_count": null, 745 | "outputs": [] 746 | }, 747 | { 748 | "cell_type": "code", 749 | "metadata": { 750 | "cellView": "code", 751 | "id": "kF_99p4Jg4AP" 752 | }, 753 | "source": [ 754 | "#@title Solution - Try yourself first\n", 755 | "mu = [4, 2]\n", 756 | "Sigma = [[2, -1],\n", 757 | " [-1, 4]]\n", 758 | "\n", 759 | "X, Y = RV(MultivariateNormal(mean = mu, cov = Sigma))\n", 760 | "(X & Y).sim(10000).plot(type=\"density\")" 761 | ], 762 | "execution_count": null, 763 | "outputs": [] 764 | }, 765 | { 766 | "cell_type": "markdown", 767 | "metadata": { 768 | "id": "9lbejY3TVZsJ" 769 | }, 770 | "source": [ 771 | "# ***Let's go back to power point - slide 36***" 772 | ] 773 | }, 774 | { 775 | "cell_type": "markdown", 776 | "metadata": { 777 | "id": "pQXygBZFK9MJ" 778 | }, 779 | "source": [ 780 | "# Regularization \n", 781 | "\n", 782 | "Here we examine how regularizer in Ridge regression help in reducing overfitting. " 783 | ] 784 | }, 785 | { 786 | "cell_type": "code", 787 | "metadata": { 788 | "id": "p0abOD4LK8oO" 789 | }, 790 | "source": [ 791 | "import numpy as np\n", 792 | "import matplotlib.pyplot as plt\n", 793 | "\n", 794 | "from sklearn.preprocessing import PolynomialFeatures\n", 795 | "from sklearn.linear_model import Ridge\n", 796 | "from sklearn.preprocessing import MinMaxScaler \n", 797 | "from sklearn.metrics import mean_squared_error as mse\n" 798 | ], 799 | "execution_count": null, 800 | "outputs": [] 801 | }, 802 | { 803 | "cell_type": "code", 804 | "metadata": { 805 | "id": "1HxAoiAGL3VY" 806 | }, 807 | "source": [ 808 | "# generate 1d regression data \n", 809 | "def make_1dregression_data(n=21):\n", 810 | " np.random.seed(0)\n", 811 | " xtrain = np.linspace(0.0, 20, n)\n", 812 | " xtest = np.arange(0.0, 20, 0.1)\n", 813 | " sigma2 = 4\n", 814 | " w = np.array([-1.5, 1/9.])\n", 815 | " fun = lambda x: w[0]*x + w[1]*np.square(x)\n", 816 | " ytrain = fun(xtrain) + np.random.normal(0, 1, xtrain.shape) * \\\n", 817 | " np.sqrt(sigma2)\n", 818 | " ytest= fun(xtest) + np.random.normal(0, 1, xtest.shape) * \\\n", 819 | " np.sqrt(sigma2)\n", 820 | " return xtrain, ytrain, xtest, ytest\n" 821 | ], 822 | "execution_count": null, 823 | "outputs": [] 824 | }, 825 | { 826 | "cell_type": "code", 827 | "metadata": { 828 | "id": "oKlktL3rM3jI" 829 | }, 830 | "source": [ 831 | "import numpy as np\n", 832 | "n=21\n", 833 | "xtrain = np.linspace(0.0, 20, n)\n", 834 | "w = np.array([-1.5, 1/9.])\n", 835 | "fun = lambda x: w[0]*x + w[1]*np.square(x)\n", 836 | "\n", 837 | "ytrain = fun(xtrain)" 838 | ], 839 | "execution_count": null, 840 | "outputs": [] 841 | }, 842 | { 843 | "cell_type": "code", 844 | "metadata": { 845 | "id": "2-2X7p5E4JZu" 846 | }, 847 | "source": [], 848 | "execution_count": null, 849 | "outputs": [] 850 | }, 851 | { 852 | "cell_type": "code", 853 | "metadata": { 854 | "id": "Kd-943vgL-Gp" 855 | }, 856 | "source": [ 857 | "# split data into train and test\n", 858 | "xtrain, ytrain, xtest, ytest = make_1dregression_data(n=21)\n", 859 | "\n", 860 | "#Rescaling data\n", 861 | "scaler = MinMaxScaler(feature_range=(-1, 1))\n", 862 | "Xtrain = scaler.fit_transform(xtrain.reshape(-1, 1))\n", 863 | "Xtest = scaler.transform(xtest.reshape(-1, 1))\n" 864 | ], 865 | "execution_count": null, 866 | "outputs": [] 867 | }, 868 | { 869 | "cell_type": "code", 870 | "metadata": { 871 | "id": "A_qzH6A8MCdJ" 872 | }, 873 | "source": [ 874 | "# fit Ridge model with different regularizer strength\n", 875 | "deg = 14\n", 876 | "alphas = np.logspace(-10, 1.3, 10) # Regularization strength\n", 877 | "nalphas = len(alphas)\n", 878 | "mse_train = np.empty(nalphas)\n", 879 | "mse_test = np.empty(nalphas)\n", 880 | "ytest_pred_stored = dict()\n", 881 | "\n", 882 | "\n", 883 | "for i, alpha in enumerate(alphas):\n", 884 | " model = Ridge(alpha=alpha, fit_intercept=False)\n", 885 | " poly_features = PolynomialFeatures(degree=deg, include_bias=False) # create 14 features which is used as X\n", 886 | " Xtrain_poly = poly_features.fit_transform(Xtrain)\n", 887 | " model.fit(Xtrain_poly, ytrain)\n", 888 | " ytrain_pred = model.predict(Xtrain_poly)\n", 889 | " Xtest_poly = poly_features.transform(Xtest)\n", 890 | " ytest_pred = model.predict(Xtest_poly)\n", 891 | " mse_train[i] = mse(ytrain_pred, ytrain) \n", 892 | " mse_test[i] = mse(ytest_pred, ytest)\n", 893 | " ytest_pred_stored[alpha] = ytest_pred\n", 894 | " \n" 895 | ], 896 | "execution_count": null, 897 | "outputs": [] 898 | }, 899 | { 900 | "cell_type": "code", 901 | "metadata": { 902 | "id": "B8Tbv5RrMmRe" 903 | }, 904 | "source": [ 905 | "# Plot MSE vs degree\n", 906 | "fig, ax = plt.subplots()\n", 907 | "mask = [True]*nalphas\n", 908 | "ax.plot(alphas[mask], mse_test[mask], color = 'r', marker = 'x',label='test')\n", 909 | "ax.plot(alphas[mask], mse_train[mask], color='b', marker = 's', label='train')\n", 910 | "ax.set_xscale('log')\n", 911 | "ax.legend(loc='upper right', shadow=True)\n", 912 | "plt.xlabel('L2 regularizer')\n", 913 | "plt.ylabel('mse')\n", 914 | "plt.show()\n" 915 | ], 916 | "execution_count": null, 917 | "outputs": [] 918 | }, 919 | { 920 | "cell_type": "code", 921 | "metadata": { 922 | "id": "Yu_yqywDMn2U" 923 | }, 924 | "source": [ 925 | "# Plot fitted functions\n", 926 | "chosen_alphas = alphas[[0,5,8]]\n", 927 | "for i, alpha in enumerate(alphas):\n", 928 | " fig, ax = plt.subplots()\n", 929 | " ax.scatter(xtrain, ytrain)\n", 930 | " ax.plot(xtest, ytest_pred_stored[alpha])\n", 931 | " plt.title('L2 regularizer {:0.5e}'.format(alpha))\n", 932 | " plt.show()" 933 | ], 934 | "execution_count": null, 935 | "outputs": [] 936 | }, 937 | { 938 | "cell_type": "markdown", 939 | "metadata": { 940 | "id": "9ms-23NROC0Y" 941 | }, 942 | "source": [ 943 | "# Exercise 4: \n", 944 | "How do you choose what regularizer strength is optimal?? Explain your answer at the following cell. " 945 | ] 946 | }, 947 | { 948 | "cell_type": "code", 949 | "metadata": { 950 | "id": "MxwId3RjOP2g" 951 | }, 952 | "source": [ 953 | "# your answer here\n" 954 | ], 955 | "execution_count": null, 956 | "outputs": [] 957 | }, 958 | { 959 | "cell_type": "code", 960 | "metadata": { 961 | "id": "7wHhZ-mooapM", 962 | "cellView": "form" 963 | }, 964 | "source": [ 965 | "#@title Solution \n", 966 | "\n", 967 | "Use cross validation - explain the process" 968 | ], 969 | "execution_count": null, 970 | "outputs": [] 971 | }, 972 | { 973 | "cell_type": "markdown", 974 | "source": [ 975 | "# Submission Instructions\n", 976 | "\n", 977 | "Once you are finished, follow these steps:\n", 978 | "\n", 979 | "Restart the kernel and re-run this notebook from beginning to end by going to Kernel > Restart Kernel and Run All Cells. If this process stops halfway through, that means there was an error. Correct the error and repeat Step 1 until the notebook runs from beginning to end. Double check that there is a number next to each code cell and that these numbers are in order. Then, submit your lab as follows:\n", 980 | "\n", 981 | "Go to File > Print > Save as PDF. Double check that the entire notebook, from beginning to end, is in this PDF file. Make sure Solution for Exercise 4 are in for marks. Upload the PDF to Spectrum." 982 | ], 983 | "metadata": { 984 | "id": "lN7_59o5ZkgZ" 985 | } 986 | }, 987 | { 988 | "cell_type": "markdown", 989 | "metadata": { 990 | "id": "FcqpGzfGyWxL" 991 | }, 992 | "source": [ 993 | "# Acknowledgement\n", 994 | "\n", 995 | "The works are inspired from \n", 996 | "1. Normal Distribtion - https://colab.research.google.com/github/dlsun/Stat350F19/blob/master/Normal_Distribution.ipynb#scrollTo=4K2s06RQFP_1 \n", 997 | "2. Coin Flip Example - https://pub.towardsai.net/monte-carlo-simulation-an-in-depth-tutorial-with-python-bcf6eb7856c8 \n", 998 | "3. Estimating $\\pi$ from circle and square = https://www.youtube.com/watch?v=VJTFfIqO4TU " 999 | ] 1000 | } 1001 | ] 1002 | } -------------------------------------------------------------------------------- /Week3/READMe.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Week3/W3.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week3/W3.pptx -------------------------------------------------------------------------------- /Week3/WOA7015_Wk3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "WOA7015_Wk3.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "authorship_tag": "ABX9TyNIgFUm0FAZOu775EIoFBzm", 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | }, 16 | "language_info": { 17 | "name": "python" 18 | } 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "OzY5ZsYGoDdu" 35 | }, 36 | "source": [ 37 | "# Welcome to WOA7015 Advance Machine Learning Lab - Week 3\n", 38 | "This code is generated for the purpose of WOA7015 module.\n", 39 | "The code is available in github https://github.com/shiernee/Advanced_ML \n" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "nVerYxHW-ZrQ" 46 | }, 47 | "source": [ 48 | "# The effect of imbalanced data on AUROC \n", 49 | "The following code evaluates the effect of imbalanced data on the AUROC of TPR-FPR curve. \n" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "metadata": { 55 | "id": "c87yzg0goBrP" 56 | }, 57 | "source": [ 58 | "# roc curve and auc on an imbalanced dataset\n", 59 | "import numpy as np\n", 60 | "from sklearn.datasets import make_classification\n", 61 | "from sklearn.linear_model import LogisticRegression\n", 62 | "from sklearn.model_selection import train_test_split\n", 63 | "from sklearn.metrics import roc_curve\n", 64 | "from sklearn.metrics import roc_auc_score\n", 65 | "import matplotlib.pyplot as plt\n", 66 | "from imblearn.under_sampling import RandomUnderSampler\n" 67 | ], 68 | "execution_count": 36, 69 | "outputs": [] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "metadata": { 74 | "colab": { 75 | "base_uri": "https://localhost:8080/" 76 | }, 77 | "id": "hcpJntDPEq2J", 78 | "outputId": "6e6cbb8c-8ee1-43a6-91bc-64bdfad9412f" 79 | }, 80 | "source": [ 81 | "# generate 2 class dataset \n", 82 | "X, y = make_classification(n_samples=1000, n_classes=2, random_state=1000)\n", 83 | "\n", 84 | "print(X)\n", 85 | "print('-----------')\n", 86 | "print(y)\n" 87 | ], 88 | "execution_count": 37, 89 | "outputs": [ 90 | { 91 | "output_type": "stream", 92 | "name": "stdout", 93 | "text": [ 94 | "[[-0.32584935 0.21897754 0.62061895 ... 2.84071377 -0.02582733\n", 95 | " -0.40885762]\n", 96 | " [-1.12624124 -0.86026727 -0.89264356 ... -0.92962064 0.59483549\n", 97 | " 1.24052468]\n", 98 | " [-0.48993428 -0.7453348 -1.43801838 ... -1.67525801 -0.09994425\n", 99 | " -0.46569289]\n", 100 | " ...\n", 101 | " [ 0.47406074 -1.9209351 0.41681779 ... 1.04574815 1.092832\n", 102 | " -0.01541749]\n", 103 | " [-0.62731673 -0.94336697 -1.50694171 ... -0.85092941 0.99046917\n", 104 | " 2.19583454]\n", 105 | " [ 0.88990126 0.81857103 -2.12551556 ... 1.00271323 -0.88101446\n", 106 | " -0.81149645]]\n", 107 | "-----------\n", 108 | "[1 0 0 0 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 1 0 0 0 1 0 0 0\n", 109 | " 0 0 0 1 1 0 1 0 1 1 0 0 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 1 0 0 1 1 1 0 0 0 0\n", 110 | " 0 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 1 1 1 0 1 0 0 0 0 1 1 0 1 1 1 1 0 0 0 0 1\n", 111 | " 0 1 1 0 0 1 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 0 0 0 1 0 1\n", 112 | " 0 0 1 1 0 0 1 1 1 0 1 1 1 0 1 0 0 0 0 0 0 1 0 1 1 1 1 1 0 1 0 0 0 0 1 0 0\n", 113 | " 1 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 0 0 1 0\n", 114 | " 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 0 0 0 1 0 1 1 0 0 1 1 1 0 0 1 0 0 0 1 0 1\n", 115 | " 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 1 1 0 1 1 1 1 0 0 0 1 1 0 1 0 0 1 0 1 1 1 0\n", 116 | " 1 1 0 0 1 0 0 0 1 0 0 1 1 0 1 0 1 1 0 1 0 0 0 1 1 1 0 0 0 0 1 0 0 0 1 1 0\n", 117 | " 1 1 1 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0\n", 118 | " 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 1 1 1 0\n", 119 | " 0 0 0 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 1 1 0 1 1 0 0 1 0 1 0 0 0 1 0 1 1 0 0\n", 120 | " 0 1 0 1 0 0 1 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 0\n", 121 | " 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 0 0 0\n", 122 | " 1 0 0 0 1 0 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 1 0 1 0 1\n", 123 | " 0 0 1 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0\n", 124 | " 0 0 1 0 0 0 1 0 0 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0\n", 125 | " 0 1 1 1 0 1 0 0 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 1 1 0 1 1 1 0\n", 126 | " 0 0 1 0 0 0 0 0 1 0 1 0 0 1 1 1 1 0 1 1 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0 0 1\n", 127 | " 0 0 0 1 0 1 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 1 1 0 0 1 0 0 0 1 0 0 0 1 1 0 0\n", 128 | " 0 0 0 1 1 0 1 0 1 0 1 1 1 0 1 1 1 0 0 0 1 0 1 1 0 1 1 0 1 1 0 0 1 0 0 0 1\n", 129 | " 1 1 0 0 0 1 0 1 0 0 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 1 0 0 1 0 1\n", 130 | " 1 1 1 1 0 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 1 0\n", 131 | " 0 0 0 1 1 0 1 1 1 0 0 1 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 0 1 0 0 0 1 1 0 1\n", 132 | " 1 1 1 1 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 0 0 1 0 0 1 1 0 1 0 1 1 1 0 0 1 1 0\n", 133 | " 1 0 1 0 1 1 0 0 1 1 1 0 0 1 0 1 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0\n", 134 | " 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 1 0 1 0 0 1 0 0 1 1 0 1 1 1 0\n", 135 | " 0]\n" 136 | ] 137 | } 138 | ] 139 | }, 140 | { 141 | "cell_type": "code", 142 | "metadata": { 143 | "colab": { 144 | "base_uri": "https://localhost:8080/" 145 | }, 146 | "id": "wLo12OKVE__J", 147 | "outputId": "a6dbfbe9-fecd-4d53-b281-c7193c79caa2" 148 | }, 149 | "source": [ 150 | "# split into train/test sets\n", 151 | "trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=1000)\n", 152 | "\n", 153 | "print('trainy - class0: ', len(trainy)-trainy.sum())\n", 154 | "print('trainy - class1: ', trainy.sum())\n", 155 | "print('----------------------')\n", 156 | "print('testy - class0: ', len(testy)-testy.sum())\n", 157 | "print('testy - class1: ', testy.sum())\n", 158 | "print('============================')\n", 159 | "\n", 160 | "# make testing dataset balance\n", 161 | "undersample = RandomUnderSampler(sampling_strategy='majority')\n", 162 | "testX, testy = undersample.fit_resample(testX, testy)\n", 163 | "\n", 164 | "print('Balanced Testing date')\n", 165 | "print('testy - class0: ', len(testy)-testy.sum())\n", 166 | "print('testy - class1: ', testy.sum())" 167 | ], 168 | "execution_count": 38, 169 | "outputs": [ 170 | { 171 | "output_type": "stream", 172 | "name": "stdout", 173 | "text": [ 174 | "trainy - class0: 253\n", 175 | "trainy - class1: 247\n", 176 | "----------------------\n", 177 | "testy - class0: 249\n", 178 | "testy - class1: 251\n", 179 | "============================\n", 180 | "Balanced Testing date\n", 181 | "testy - class0: 249\n", 182 | "testy - class1: 249\n" 183 | ] 184 | }, 185 | { 186 | "output_type": "stream", 187 | "name": "stderr", 188 | "text": [ 189 | "/usr/local/lib/python3.7/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function safe_indexing is deprecated; safe_indexing is deprecated in version 0.22 and will be removed in version 0.24.\n", 190 | " warnings.warn(msg, category=FutureWarning)\n" 191 | ] 192 | } 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "metadata": { 198 | "id": "Y3QmySaLE7Nm" 199 | }, 200 | "source": [ 201 | "# fit a model with training data\n", 202 | "model = LogisticRegression(solver='lbfgs')\n", 203 | "model.fit(trainX, trainy)\n" 204 | ], 205 | "execution_count": null, 206 | "outputs": [] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "metadata": { 211 | "id": "nOu_783uGpZd" 212 | }, 213 | "source": [ 214 | "# repeat with different skewness \n", 215 | "roc_list = []\n", 216 | "lr_acc = []\n", 217 | "k=1\n", 218 | "for i in range(0, 10):\n", 219 | " pos_ind = np.where(testy==1)[0]\n", 220 | " n = int(i/10 * len(pos_ind))\n", 221 | " tmp_testX, tmp_testy = np.copy(testX), np.copy(testy)\n", 222 | " tmp_testX = np.delete(tmp_testX, pos_ind[:n], axis=0)\n", 223 | " tmp_testy = np.delete(tmp_testy, pos_ind[:n], axis=0)\n", 224 | " print('nth %d:positive: %d negative: %d' \n", 225 | " % (i, tmp_testy.sum(), tmp_testy.shape[0] - tmp_testy.sum()))\n", 226 | " print('---------------------------------------------')\n", 227 | " \n", 228 | " # predict probabilities\n", 229 | " lr_probs = model.predict_proba(tmp_testX)\n", 230 | " # keep probabilities for the positive outcome only\n", 231 | " lr_probs = lr_probs[:, 1]\n", 232 | " # calculate scores\n", 233 | " lr_auc = roc_auc_score(tmp_testy, lr_probs)\n", 234 | "\n", 235 | " # summarize scores\n", 236 | " # print('iteration %d: Logistic: ROC AUC=%.3f' % (k, lr_auc))\n", 237 | " k += 1\n", 238 | " # calculate roc curves\n", 239 | " lr_fpr, lr_tpr, _ = roc_curve(tmp_testy, lr_probs)\n", 240 | " roc_list.append(lr_auc)\n", 241 | "\n", 242 | "plt.plot(np.arange(0, len(roc_list)), roc_list)\n", 243 | "plt.xlabel('skewness ratio')\n", 244 | "plt.ylabel('AUROC')\n", 245 | "plt.title('decreasing positive sample')\n" 246 | ], 247 | "execution_count": null, 248 | "outputs": [] 249 | }, 250 | { 251 | "cell_type": "markdown", 252 | "metadata": { 253 | "id": "njFP2GHpC1VE" 254 | }, 255 | "source": [ 256 | "# Exercise 1 (2%):\n", 257 | "Does the AUROC (TPR vs FPR) affected by imbalanced class?\n", 258 | "\n", 259 | "\n" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "metadata": { 265 | "id": "vOIpcKliC56h" 266 | }, 267 | "source": [ 268 | "# Your answer here\n" 269 | ], 270 | "execution_count": null, 271 | "outputs": [] 272 | }, 273 | { 274 | "cell_type": "markdown", 275 | "metadata": { 276 | "id": "KK4Cxp0q75PM" 277 | }, 278 | "source": [ 279 | "# The effect of imbalanced data on AUROC of PR curve and F1 score\n", 280 | "The following code evaluates the effect of imbalanced data on the AUROC of Precision-Recall and F1 value. \n" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "metadata": { 286 | "id": "oYxjJuD_8ewJ" 287 | }, 288 | "source": [ 289 | "# roc curve and auc on an imbalanced dataset\n", 290 | "import numpy as np\n", 291 | "from sklearn.datasets import make_classification\n", 292 | "from sklearn.linear_model import LogisticRegression\n", 293 | "from sklearn.model_selection import train_test_split\n", 294 | "from sklearn.metrics import auc, f1_score\n", 295 | "from sklearn.metrics import precision_recall_curve\n", 296 | "import matplotlib.pyplot as plt\n" 297 | ], 298 | "execution_count": 23, 299 | "outputs": [] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "metadata": { 304 | "id": "nr_uY_mPHLTF" 305 | }, 306 | "source": [ 307 | "# generate 2 class dataset \n", 308 | "X, y = make_classification(n_samples=1000, n_classes=2, random_state=1000)\n", 309 | "\n", 310 | "print(X)\n", 311 | "print('-----------')\n", 312 | "print(y)\n" 313 | ], 314 | "execution_count": null, 315 | "outputs": [] 316 | }, 317 | { 318 | "cell_type": "code", 319 | "metadata": { 320 | "id": "bbmv6pFhHWyQ" 321 | }, 322 | "source": [ 323 | "# split into train/test sets\n", 324 | "trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=1000)\n", 325 | "\n", 326 | "print('trainy - class0: ', len(trainy)-trainy.sum())\n", 327 | "print('trainy - class1: ', trainy.sum())\n", 328 | "print('----------------------')\n", 329 | "print('testy - class0: ', len(testy)-testy.sum())\n", 330 | "print('testy - class1: ', testy.sum())\n", 331 | "print('============================')\n", 332 | "\n", 333 | "# make testing dataset balance\n", 334 | "undersample = RandomUnderSampler(sampling_strategy='majority')\n", 335 | "testX, testy = undersample.fit_resample(testX, testy)\n", 336 | "\n", 337 | "print('Balanced Testing date')\n", 338 | "print('testy - class0: ', len(testy)-testy.sum())\n", 339 | "print('testy - class1: ', testy.sum())\n" 340 | ], 341 | "execution_count": null, 342 | "outputs": [] 343 | }, 344 | { 345 | "cell_type": "code", 346 | "metadata": { 347 | "id": "i1ST-YEcHh5I" 348 | }, 349 | "source": [ 350 | "# fit a model\n", 351 | "model = LogisticRegression(solver='lbfgs')\n", 352 | "model.fit(trainX, trainy)" 353 | ], 354 | "execution_count": null, 355 | "outputs": [] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "metadata": { 360 | "id": "scPocodDHRp-" 361 | }, 362 | "source": [ 363 | "# repeat with different skewness \n", 364 | "roc_list = []\n", 365 | "f1_list = []\n", 366 | "\n", 367 | "k=1\n", 368 | "for i in range(0, 10):\n", 369 | " pos_ind = np.where(testy==1)[0]\n", 370 | " n = int(i/10 * len(pos_ind))\n", 371 | " tmp_testX, tmp_testy = np.copy(testX), np.copy(testy)\n", 372 | " tmp_testX = np.delete(tmp_testX, pos_ind[:n], axis=0)\n", 373 | " tmp_testy = np.delete(tmp_testy, pos_ind[:n], axis=0)\n", 374 | " print('nth %d:positive: %d negative: %d' \n", 375 | " % (i, tmp_testy.sum(), tmp_testy.shape[0] - tmp_testy.sum()))\n", 376 | " print('---------------------------------------------')\n", 377 | " \n", 378 | "\n", 379 | " # predict probabilities\n", 380 | " lr_probs = model.predict_proba(tmp_testX)\n", 381 | " # keep probabilities for the positive outcome only\n", 382 | " lr_probs = lr_probs[:, 1]\n", 383 | " # predict class values\n", 384 | " yhat = model.predict(tmp_testX)\n", 385 | " # calculate precision and recall for each threshold\n", 386 | " lr_precision, lr_recall, _ = precision_recall_curve(tmp_testy, lr_probs)\n", 387 | " # calculate scores\n", 388 | " lr_f1, lr_auc = f1_score(tmp_testy, yhat), auc(lr_recall, lr_precision)\n", 389 | " # summarize scores\n", 390 | " # print('iteration%d Logistic: f1=%.3f auc=%.3f' % (k, lr_f1, lr_auc))\n", 391 | " k += 1\n", 392 | " roc_list.append(lr_auc)\n", 393 | " f1_list.append(lr_f1)\n", 394 | "\n", 395 | "plt.plot(np.arange(0, len(roc_list)), roc_list)\n", 396 | "plt.xlabel('skewness ratio')\n", 397 | "plt.ylabel('AUC of PR curve')\n", 398 | "plt.title('decreasing positive sample')\n", 399 | "\n", 400 | "plt.figure()\n", 401 | "plt.plot(np.arange(0, len(roc_list)), f1_list)\n", 402 | "plt.xlabel('skewness ratio')\n", 403 | "plt.ylabel('F1')\n", 404 | "plt.title('decreasing positive sample')\n" 405 | ], 406 | "execution_count": null, 407 | "outputs": [] 408 | }, 409 | { 410 | "cell_type": "markdown", 411 | "metadata": { 412 | "id": "2DP3LOZY7v6M" 413 | }, 414 | "source": [ 415 | "# Exercise 2 (4%):\n", 416 | "Does the AUROC (Precision vs Recall), F1 score affected by imbalanced class?" 417 | ] 418 | }, 419 | { 420 | "cell_type": "code", 421 | "metadata": { 422 | "id": "iPXGu2E00-c5" 423 | }, 424 | "source": [ 425 | "# Your answer here" 426 | ], 427 | "execution_count": null, 428 | "outputs": [] 429 | }, 430 | { 431 | "cell_type": "markdown", 432 | "metadata": { 433 | "id": "_h1qUoy4DSc2" 434 | }, 435 | "source": [ 436 | "# ***Let's go back to power point - slide 13***" 437 | ] 438 | }, 439 | { 440 | "cell_type": "markdown", 441 | "metadata": { 442 | "id": "SK3GJxwgzEjP" 443 | }, 444 | "source": [ 445 | "# Convex function\n", 446 | "\n", 447 | "This is the code to generate the graph in slide 38" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "metadata": { 453 | "id": "3v0il6m3zOQb" 454 | }, 455 | "source": [ 456 | "import numpy as np\n", 457 | "import matplotlib.pyplot as plt\n", 458 | "import imageio\n", 459 | "\n", 460 | "x = np.arange(-2, 2, 0.01)\n", 461 | "\n", 462 | "# choose one function to try\n", 463 | "f = lambda x: 0.5 * x ** 2 # Convex\n", 464 | "# f = lambda x: np.cos(np.pi * x) # Nonconvex\n", 465 | "# f = lambda x: -0.5 * x ** 4 # Nonconvex\n", 466 | "\n", 467 | "filenames=[]\n", 468 | "for lamda in np.arange(0, 1, 0.02):\n", 469 | " # LHS\n", 470 | " tmp_x = lamda*x[0] + (1-lamda)*x[-1]\n", 471 | "\n", 472 | " # RHS\n", 473 | " x_line, y_line = np.array([x[0], x[-1]]), np.array([lamda*f(x[0]), (1-lamda)*f(x[-1])])\n", 474 | "\n", 475 | " # compute LHS and RHS\n", 476 | " LHS = f(tmp_x)\n", 477 | " RHS = lamda*f(x[0]) + (1-lamda)*f(x[-1])\n", 478 | " if LHS > RHS:\n", 479 | " print('At lamda %0.3f, it is concave' % lamda)\n", 480 | " print('lhs %.5f rhs %.5f' % (LHS, RHS))\n", 481 | "\n", 482 | " plt.figure()\n", 483 | " # original graph\n", 484 | " plt.plot(x, f(x), label='f(x)')\n", 485 | " # plot RHS\n", 486 | " plt.plot(x_line, y_line, label='%0.3f' % lamda)\n", 487 | " # plot LHS\n", 488 | " plt.scatter(tmp_x, f(tmp_x))\n", 489 | " #title, legennd\n", 490 | " plt.title('lhs %.3f rhs %.3f' % (LHS, RHS))\n", 491 | " plt.legend()\n", 492 | " plt.savefig('lamda %0.3f.png' % lamda)\n", 493 | " # plt.close()\n", 494 | " filenames.append('lamda %0.3f.png' % lamda)\n", 495 | "\n", 496 | "# Build GIF\n", 497 | "with imageio.get_writer('mygif.gif', mode='I') as writer:\n", 498 | " for filename in filenames:\n", 499 | " image = imageio.imread(filename)\n", 500 | " writer.append_data(image)" 501 | ], 502 | "execution_count": null, 503 | "outputs": [] 504 | }, 505 | { 506 | "cell_type": "markdown", 507 | "metadata": { 508 | "id": "l9Wuu9o0pGmg" 509 | }, 510 | "source": [ 511 | "# Understand how learning rate affects your SGD optimization\n", 512 | "\n", 513 | "We will train a neural network for a pretty simple task, i.e. calculating the exclusive-or (XOR) of two input. \n", 514 | "\n", 515 | "
\n", 516 | "\n", 517 | "\n" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "metadata": { 523 | "id": "Qr2IABWKoGHk" 524 | }, 525 | "source": [ 526 | "import random\n", 527 | "import numpy as np" 528 | ], 529 | "execution_count": null, 530 | "outputs": [] 531 | }, 532 | { 533 | "cell_type": "code", 534 | "metadata": { 535 | "colab": { 536 | "base_uri": "https://localhost:8080/" 537 | }, 538 | "id": "3PpJZLhyndlE", 539 | "outputId": "b780d629-bcb3-46dd-82f4-b50699ec8d0a" 540 | }, 541 | "source": [ 542 | "# generate a function for XOR\n", 543 | "x1 = random.randint(0, 1)\n", 544 | "x2 = random.randint(0, 1)\n", 545 | "yy = 0 if (x1 == x2) else 1\n", 546 | "\n", 547 | "print('x1:', x1)\n", 548 | "print('x2:',x2)\n", 549 | "print('yy:',yy)" 550 | ], 551 | "execution_count": 52, 552 | "outputs": [ 553 | { 554 | "output_type": "stream", 555 | "name": "stdout", 556 | "text": [ 557 | "1\n", 558 | "1\n", 559 | "0\n" 560 | ] 561 | } 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "metadata": { 567 | "colab": { 568 | "base_uri": "https://localhost:8080/" 569 | }, 570 | "id": "sucvJe_fntPU", 571 | "outputId": "3dff8ccc-9361-430c-f2a8-5fe510e90b2f" 572 | }, 573 | "source": [ 574 | "x1 = random.randint(0, 1)\n", 575 | "x2 = random.randint(0, 1)\n", 576 | "yy = 0 if (x1 == x2) else 1\n", 577 | "\n", 578 | "# centered at zero\n", 579 | "x1 = 2. * (x1 - 0.5)\n", 580 | "x2 = 2. * (x2 - 0.5)\n", 581 | "yy = 2. * (yy - 0.5)\n", 582 | "\n", 583 | "print('x1:', x1)\n", 584 | "print('x2:',x2)\n", 585 | "print('yy:',yy)" 586 | ], 587 | "execution_count": 54, 588 | "outputs": [ 589 | { 590 | "output_type": "stream", 591 | "name": "stdout", 592 | "text": [ 593 | "x1: -1.0\n", 594 | "x2: 1.0\n", 595 | "yy: 1.0\n" 596 | ] 597 | } 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "metadata": { 603 | "colab": { 604 | "base_uri": "https://localhost:8080/" 605 | }, 606 | "id": "aEbi2kK4n9Ci", 607 | "outputId": "75c1ede3-5545-40bb-80bc-01fecf04192f" 608 | }, 609 | "source": [ 610 | "x1 = random.randint(0, 1)\n", 611 | "x2 = random.randint(0, 1)\n", 612 | "yy = 0 if (x1 == x2) else 1\n", 613 | "\n", 614 | "# centered at zero\n", 615 | "x1 = 2. * (x1 - 0.5)\n", 616 | "x2 = 2. * (x2 - 0.5)\n", 617 | "yy = 2. * (yy - 0.5)\n", 618 | "\n", 619 | "# add noise\n", 620 | "x1 += 0.1 * random.random()\n", 621 | "x2 += 0.1 * random.random()\n", 622 | "yy += 0.1 * random.random()\n", 623 | "\n", 624 | "print('x1:', x1)\n", 625 | "print('x2:',x2)\n", 626 | "print('yy:',yy)" 627 | ], 628 | "execution_count": 56, 629 | "outputs": [ 630 | { 631 | "output_type": "stream", 632 | "name": "stdout", 633 | "text": [ 634 | "x1: -0.9574273128896689\n", 635 | "x2: -0.9030175180760335\n", 636 | "yy: -0.9475814083656239\n" 637 | ] 638 | } 639 | ] 640 | }, 641 | { 642 | "cell_type": "code", 643 | "metadata": { 644 | "id": "6RiENlDbpGS3" 645 | }, 646 | "source": [ 647 | "# make it into function \n", 648 | "def make_data():\n", 649 | " x1 = random.randint(0, 1)\n", 650 | " x2 = random.randint(0, 1)\n", 651 | " yy = 0 if (x1 == x2) else 1\n", 652 | " \n", 653 | " # centered at zero\n", 654 | " x1 = 2. * (x1 - 0.5)\n", 655 | " x2 = 2. * (x2 - 0.5)\n", 656 | " yy = 2. * (yy - 0.5)\n", 657 | " \n", 658 | " # add noise\n", 659 | " x1 += 0.1 * random.random()\n", 660 | " x2 += 0.1 * random.random()\n", 661 | " yy += 0.1 * random.random()\n", 662 | " \n", 663 | " return [x1, x2, ], yy\n", 664 | " " 665 | ], 666 | "execution_count": null, 667 | "outputs": [] 668 | }, 669 | { 670 | "cell_type": "code", 671 | "metadata": { 672 | "id": "IRS81-dioL4n" 673 | }, 674 | "source": [ 675 | "# create batch samples\n", 676 | "batch_size = 10\n", 677 | "def make_batch():\n", 678 | " data = [make_data() for ii in range(batch_size)]\n", 679 | " labels = [label for xx, label in data]\n", 680 | " data = [xx for xx, label in data]\n", 681 | " return np.array(data, dtype='float32'), np.array(labels, dtype='float32')\n", 682 | " \n", 683 | "print(make_batch())\n" 684 | ], 685 | "execution_count": null, 686 | "outputs": [] 687 | }, 688 | { 689 | "cell_type": "code", 690 | "metadata": { 691 | "id": "XB7kASWVoZJi" 692 | }, 693 | "source": [ 694 | "# generate 500 train and 50 test data \n", 695 | "train_data = [make_batch() for ii in range(500)]\n", 696 | "test_data = [make_batch() for ii in range(50)]\n" 697 | ], 698 | "execution_count": 106, 699 | "outputs": [] 700 | }, 701 | { 702 | "cell_type": "code", 703 | "metadata": { 704 | "id": "huxK2x7WpUGw" 705 | }, 706 | "source": [ 707 | "# import torch libraries\n", 708 | "import torch\n", 709 | "import torch.nn as nn\n", 710 | "import torch.nn.functional as F\n", 711 | "import torch.optim as optim\n", 712 | "from torch.autograd import Variable\n", 713 | " " 714 | ], 715 | "execution_count": 107, 716 | "outputs": [] 717 | }, 718 | { 719 | "cell_type": "code", 720 | "metadata": { 721 | "id": "BMj_0PO0ojry" 722 | }, 723 | "source": [ 724 | "## Define our neural network class\n", 725 | "torch.manual_seed(42)\n", 726 | " \n", 727 | "class NN(nn.Module):\n", 728 | " def __init__(self):\n", 729 | " super(NN, self).__init__()\n", 730 | " \n", 731 | " self.dense1 = nn.Linear(2, 2)\n", 732 | " self.dense2 = nn.Linear(2, 1)\n", 733 | " \n", 734 | " def forward(self, x):\n", 735 | " x = F.tanh(self.dense1(x))\n", 736 | " x = self.dense2(x)\n", 737 | " return torch.squeeze(x)\n", 738 | " \n" 739 | ], 740 | "execution_count": 112, 741 | "outputs": [] 742 | }, 743 | { 744 | "cell_type": "code", 745 | "metadata": { 746 | "id": "ZqLyWCLOtrJS" 747 | }, 748 | "source": [ 749 | "# initialize our network\n", 750 | "model = NN()\n", 751 | "\n", 752 | "## optimizer = stochastic gradient descent\n", 753 | "optimizer = optim.SGD(model.parameters(), lr)" 754 | ], 755 | "execution_count": 127, 756 | "outputs": [] 757 | }, 758 | { 759 | "cell_type": "code", 760 | "metadata": { 761 | "id": "Furjt7ZppdxA" 762 | }, 763 | "source": [ 764 | "## train and test functions\n", 765 | " \n", 766 | "def train(epoch):\n", 767 | " model.train()\n", 768 | " for batch_idx, (data, target) in enumerate(train_data):\n", 769 | " data, target = Variable(torch.from_numpy(data)), Variable(torch.from_numpy(target))\n", 770 | " optimizer.zero_grad()\n", 771 | " output = model(data)\n", 772 | " loss = F.mse_loss(output, target)\n", 773 | " loss.backward()\n", 774 | " optimizer.step()\n", 775 | " if batch_idx % 100 == 0:\n", 776 | " print('Train Epoch: {} {}\\tLoss: {:.4f}'.format(epoch, batch_idx * len(data), loss.item()))\n", 777 | " \n", 778 | "def test():\n", 779 | " model.eval()\n", 780 | " test_loss = 0\n", 781 | " correct = 0\n", 782 | " for data, target in test_data:\n", 783 | " data, target = Variable(torch.from_numpy(data), volatile=True), Variable(torch.from_numpy(target))\n", 784 | " output = model(data)\n", 785 | " test_loss += F.mse_loss(output, target)\n", 786 | " correct += (np.around(output.data.numpy()) == np.around(target.data.numpy())).sum()\n", 787 | " \n", 788 | " test_loss /= len(test_data)\n", 789 | " test_loss = test_loss.item()\n", 790 | " \n", 791 | " print('\\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\\n'.format(\n", 792 | " test_loss, correct, batch_size * len(test_data), 100. * correct / (batch_size * len(test_data))) )\n", 793 | " " 794 | ], 795 | "execution_count": 128, 796 | "outputs": [] 797 | }, 798 | { 799 | "cell_type": "code", 800 | "metadata": { 801 | "id": "wZ4c_vUzphKy", 802 | "colab": { 803 | "base_uri": "https://localhost:8080/" 804 | }, 805 | "outputId": "60d93a88-ce66-41e1-f823-1de85b60c26e" 806 | }, 807 | "source": [ 808 | "## run experiment \n", 809 | "nepochs = 1000\n", 810 | "lr = 0.001\n", 811 | "\n", 812 | "print('lr=', lr)\n", 813 | "for epoch in range(1, nepochs + 1):\n", 814 | " train(epoch)\n", 815 | " print('---------------------------------------------')\n", 816 | " test()\n", 817 | " \n", 818 | " # everytime rerun this cell, please re initialize your network, and re run the train test function " 819 | ], 820 | "execution_count": null, 821 | "outputs": [ 822 | { 823 | "output_type": "stream", 824 | "name": "stdout", 825 | "text": [ 826 | "Train Epoch: 497 1000\tLoss: 0.4051\n", 827 | "Train Epoch: 497 2000\tLoss: 0.3741\n", 828 | "Train Epoch: 497 3000\tLoss: 0.6958\n", 829 | "Train Epoch: 497 4000\tLoss: 0.5083\n", 830 | "---------------------------------------------\n", 831 | "\n", 832 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 833 | "\n", 834 | "Train Epoch: 498 0\tLoss: 0.2817\n", 835 | "Train Epoch: 498 1000\tLoss: 0.4051\n", 836 | "Train Epoch: 498 2000\tLoss: 0.3741\n", 837 | "Train Epoch: 498 3000\tLoss: 0.6958\n", 838 | "Train Epoch: 498 4000\tLoss: 0.5083\n", 839 | "---------------------------------------------\n", 840 | "\n", 841 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 842 | "\n", 843 | "Train Epoch: 499 0\tLoss: 0.2817\n", 844 | "Train Epoch: 499 1000\tLoss: 0.4051\n", 845 | "Train Epoch: 499 2000\tLoss: 0.3741\n", 846 | "Train Epoch: 499 3000\tLoss: 0.6958\n", 847 | "Train Epoch: 499 4000\tLoss: 0.5083\n", 848 | "---------------------------------------------\n", 849 | "\n", 850 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 851 | "\n", 852 | "Train Epoch: 500 0\tLoss: 0.2817\n", 853 | "Train Epoch: 500 1000\tLoss: 0.4051\n", 854 | "Train Epoch: 500 2000\tLoss: 0.3741\n", 855 | "Train Epoch: 500 3000\tLoss: 0.6958\n", 856 | "Train Epoch: 500 4000\tLoss: 0.5083\n", 857 | "---------------------------------------------\n", 858 | "\n", 859 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 860 | "\n", 861 | "Train Epoch: 501 0\tLoss: 0.2817\n", 862 | "Train Epoch: 501 1000\tLoss: 0.4051\n", 863 | "Train Epoch: 501 2000\tLoss: 0.3741\n", 864 | "Train Epoch: 501 3000\tLoss: 0.6958\n", 865 | "Train Epoch: 501 4000\tLoss: 0.5083\n", 866 | "---------------------------------------------\n", 867 | "\n", 868 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 869 | "\n", 870 | "Train Epoch: 502 0\tLoss: 0.2817\n", 871 | "Train Epoch: 502 1000\tLoss: 0.4051\n", 872 | "Train Epoch: 502 2000\tLoss: 0.3741\n", 873 | "Train Epoch: 502 3000\tLoss: 0.6958\n", 874 | "Train Epoch: 502 4000\tLoss: 0.5083\n", 875 | "---------------------------------------------\n", 876 | "\n", 877 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 878 | "\n", 879 | "Train Epoch: 503 0\tLoss: 0.2817\n", 880 | "Train Epoch: 503 1000\tLoss: 0.4051\n", 881 | "Train Epoch: 503 2000\tLoss: 0.3741\n", 882 | "Train Epoch: 503 3000\tLoss: 0.6958\n", 883 | "Train Epoch: 503 4000\tLoss: 0.5083\n", 884 | "---------------------------------------------\n", 885 | "\n", 886 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 887 | "\n", 888 | "Train Epoch: 504 0\tLoss: 0.2817\n", 889 | "Train Epoch: 504 1000\tLoss: 0.4051\n", 890 | "Train Epoch: 504 2000\tLoss: 0.3741\n", 891 | "Train Epoch: 504 3000\tLoss: 0.6958\n", 892 | "Train Epoch: 504 4000\tLoss: 0.5083\n", 893 | "---------------------------------------------\n", 894 | "\n", 895 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 896 | "\n", 897 | "Train Epoch: 505 0\tLoss: 0.2817\n", 898 | "Train Epoch: 505 1000\tLoss: 0.4051\n", 899 | "Train Epoch: 505 2000\tLoss: 0.3741\n", 900 | "Train Epoch: 505 3000\tLoss: 0.6958\n", 901 | "Train Epoch: 505 4000\tLoss: 0.5083\n", 902 | "---------------------------------------------\n", 903 | "\n", 904 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 905 | "\n", 906 | "Train Epoch: 506 0\tLoss: 0.2817\n", 907 | "Train Epoch: 506 1000\tLoss: 0.4051\n", 908 | "Train Epoch: 506 2000\tLoss: 0.3741\n", 909 | "Train Epoch: 506 3000\tLoss: 0.6958\n", 910 | "Train Epoch: 506 4000\tLoss: 0.5083\n", 911 | "---------------------------------------------\n", 912 | "\n", 913 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 914 | "\n", 915 | "Train Epoch: 507 0\tLoss: 0.2817\n", 916 | "Train Epoch: 507 1000\tLoss: 0.4051\n", 917 | "Train Epoch: 507 2000\tLoss: 0.3741\n", 918 | "Train Epoch: 507 3000\tLoss: 0.6958\n", 919 | "Train Epoch: 507 4000\tLoss: 0.5083\n", 920 | "---------------------------------------------\n", 921 | "\n", 922 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 923 | "\n", 924 | "Train Epoch: 508 0\tLoss: 0.2817\n", 925 | "Train Epoch: 508 1000\tLoss: 0.4051\n", 926 | "Train Epoch: 508 2000\tLoss: 0.3741\n", 927 | "Train Epoch: 508 3000\tLoss: 0.6958\n", 928 | "Train Epoch: 508 4000\tLoss: 0.5083\n", 929 | "---------------------------------------------\n", 930 | "\n", 931 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 932 | "\n", 933 | "Train Epoch: 509 0\tLoss: 0.2817\n", 934 | "Train Epoch: 509 1000\tLoss: 0.4051\n", 935 | "Train Epoch: 509 2000\tLoss: 0.3741\n", 936 | "Train Epoch: 509 3000\tLoss: 0.6958\n", 937 | "Train Epoch: 509 4000\tLoss: 0.5083\n", 938 | "---------------------------------------------\n", 939 | "\n", 940 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 941 | "\n", 942 | "Train Epoch: 510 0\tLoss: 0.2817\n", 943 | "Train Epoch: 510 1000\tLoss: 0.4051\n", 944 | "Train Epoch: 510 2000\tLoss: 0.3741\n", 945 | "Train Epoch: 510 3000\tLoss: 0.6958\n", 946 | "Train Epoch: 510 4000\tLoss: 0.5083\n", 947 | "---------------------------------------------\n", 948 | "\n", 949 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 950 | "\n", 951 | "Train Epoch: 511 0\tLoss: 0.2817\n", 952 | "Train Epoch: 511 1000\tLoss: 0.4051\n", 953 | "Train Epoch: 511 2000\tLoss: 0.3741\n", 954 | "Train Epoch: 511 3000\tLoss: 0.6958\n", 955 | "Train Epoch: 511 4000\tLoss: 0.5083\n", 956 | "---------------------------------------------\n", 957 | "\n", 958 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 959 | "\n", 960 | "Train Epoch: 512 0\tLoss: 0.2817\n", 961 | "Train Epoch: 512 1000\tLoss: 0.4051\n", 962 | "Train Epoch: 512 2000\tLoss: 0.3741\n", 963 | "Train Epoch: 512 3000\tLoss: 0.6958\n", 964 | "Train Epoch: 512 4000\tLoss: 0.5083\n", 965 | "---------------------------------------------\n", 966 | "\n", 967 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 968 | "\n", 969 | "Train Epoch: 513 0\tLoss: 0.2817\n", 970 | "Train Epoch: 513 1000\tLoss: 0.4051\n", 971 | "Train Epoch: 513 2000\tLoss: 0.3741\n", 972 | "Train Epoch: 513 3000\tLoss: 0.6958\n", 973 | "Train Epoch: 513 4000\tLoss: 0.5083\n", 974 | "---------------------------------------------\n", 975 | "\n", 976 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 977 | "\n", 978 | "Train Epoch: 514 0\tLoss: 0.2817\n", 979 | "Train Epoch: 514 1000\tLoss: 0.4051\n", 980 | "Train Epoch: 514 2000\tLoss: 0.3741\n", 981 | "Train Epoch: 514 3000\tLoss: 0.6958\n", 982 | "Train Epoch: 514 4000\tLoss: 0.5083\n", 983 | "---------------------------------------------\n", 984 | "\n", 985 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 986 | "\n", 987 | "Train Epoch: 515 0\tLoss: 0.2817\n", 988 | "Train Epoch: 515 1000\tLoss: 0.4051\n", 989 | "Train Epoch: 515 2000\tLoss: 0.3741\n", 990 | "Train Epoch: 515 3000\tLoss: 0.6958\n", 991 | "Train Epoch: 515 4000\tLoss: 0.5083\n", 992 | "---------------------------------------------\n", 993 | "\n", 994 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 995 | "\n", 996 | "Train Epoch: 516 0\tLoss: 0.2817\n", 997 | "Train Epoch: 516 1000\tLoss: 0.4051\n", 998 | "Train Epoch: 516 2000\tLoss: 0.3741\n", 999 | "Train Epoch: 516 3000\tLoss: 0.6958\n", 1000 | "Train Epoch: 516 4000\tLoss: 0.5083\n", 1001 | "---------------------------------------------\n", 1002 | "\n", 1003 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1004 | "\n", 1005 | "Train Epoch: 517 0\tLoss: 0.2817\n", 1006 | "Train Epoch: 517 1000\tLoss: 0.4051\n", 1007 | "Train Epoch: 517 2000\tLoss: 0.3741\n", 1008 | "Train Epoch: 517 3000\tLoss: 0.6958\n", 1009 | "Train Epoch: 517 4000\tLoss: 0.5083\n", 1010 | "---------------------------------------------\n", 1011 | "\n", 1012 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1013 | "\n", 1014 | "Train Epoch: 518 0\tLoss: 0.2817\n", 1015 | "Train Epoch: 518 1000\tLoss: 0.4051\n", 1016 | "Train Epoch: 518 2000\tLoss: 0.3741\n", 1017 | "Train Epoch: 518 3000\tLoss: 0.6958\n", 1018 | "Train Epoch: 518 4000\tLoss: 0.5083\n", 1019 | "---------------------------------------------\n", 1020 | "\n", 1021 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1022 | "\n", 1023 | "Train Epoch: 519 0\tLoss: 0.2817\n", 1024 | "Train Epoch: 519 1000\tLoss: 0.4051\n", 1025 | "Train Epoch: 519 2000\tLoss: 0.3741\n", 1026 | "Train Epoch: 519 3000\tLoss: 0.6958\n", 1027 | "Train Epoch: 519 4000\tLoss: 0.5083\n", 1028 | "---------------------------------------------\n", 1029 | "\n", 1030 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1031 | "\n", 1032 | "Train Epoch: 520 0\tLoss: 0.2817\n", 1033 | "Train Epoch: 520 1000\tLoss: 0.4051\n", 1034 | "Train Epoch: 520 2000\tLoss: 0.3741\n", 1035 | "Train Epoch: 520 3000\tLoss: 0.6958\n", 1036 | "Train Epoch: 520 4000\tLoss: 0.5083\n", 1037 | "---------------------------------------------\n", 1038 | "\n", 1039 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1040 | "\n", 1041 | "Train Epoch: 521 0\tLoss: 0.2817\n", 1042 | "Train Epoch: 521 1000\tLoss: 0.4051\n", 1043 | "Train Epoch: 521 2000\tLoss: 0.3741\n", 1044 | "Train Epoch: 521 3000\tLoss: 0.6958\n", 1045 | "Train Epoch: 521 4000\tLoss: 0.5083\n", 1046 | "---------------------------------------------\n", 1047 | "\n", 1048 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1049 | "\n", 1050 | "Train Epoch: 522 0\tLoss: 0.2817\n", 1051 | "Train Epoch: 522 1000\tLoss: 0.4051\n", 1052 | "Train Epoch: 522 2000\tLoss: 0.3741\n", 1053 | "Train Epoch: 522 3000\tLoss: 0.6958\n", 1054 | "Train Epoch: 522 4000\tLoss: 0.5083\n", 1055 | "---------------------------------------------\n", 1056 | "\n", 1057 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1058 | "\n", 1059 | "Train Epoch: 523 0\tLoss: 0.2817\n", 1060 | "Train Epoch: 523 1000\tLoss: 0.4051\n", 1061 | "Train Epoch: 523 2000\tLoss: 0.3741\n", 1062 | "Train Epoch: 523 3000\tLoss: 0.6958\n", 1063 | "Train Epoch: 523 4000\tLoss: 0.5083\n", 1064 | "---------------------------------------------\n", 1065 | "\n", 1066 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1067 | "\n", 1068 | "Train Epoch: 524 0\tLoss: 0.2817\n", 1069 | "Train Epoch: 524 1000\tLoss: 0.4051\n", 1070 | "Train Epoch: 524 2000\tLoss: 0.3741\n", 1071 | "Train Epoch: 524 3000\tLoss: 0.6958\n", 1072 | "Train Epoch: 524 4000\tLoss: 0.5083\n", 1073 | "---------------------------------------------\n", 1074 | "\n", 1075 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1076 | "\n", 1077 | "Train Epoch: 525 0\tLoss: 0.2817\n", 1078 | "Train Epoch: 525 1000\tLoss: 0.4051\n", 1079 | "Train Epoch: 525 2000\tLoss: 0.3741\n", 1080 | "Train Epoch: 525 3000\tLoss: 0.6958\n", 1081 | "Train Epoch: 525 4000\tLoss: 0.5083\n", 1082 | "---------------------------------------------\n", 1083 | "\n", 1084 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1085 | "\n", 1086 | "Train Epoch: 526 0\tLoss: 0.2817\n", 1087 | "Train Epoch: 526 1000\tLoss: 0.4051\n", 1088 | "Train Epoch: 526 2000\tLoss: 0.3741\n", 1089 | "Train Epoch: 526 3000\tLoss: 0.6958\n", 1090 | "Train Epoch: 526 4000\tLoss: 0.5083\n", 1091 | "---------------------------------------------\n", 1092 | "\n", 1093 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1094 | "\n", 1095 | "Train Epoch: 527 0\tLoss: 0.2817\n", 1096 | "Train Epoch: 527 1000\tLoss: 0.4051\n", 1097 | "Train Epoch: 527 2000\tLoss: 0.3741\n", 1098 | "Train Epoch: 527 3000\tLoss: 0.6958\n", 1099 | "Train Epoch: 527 4000\tLoss: 0.5083\n", 1100 | "---------------------------------------------\n", 1101 | "\n", 1102 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1103 | "\n", 1104 | "Train Epoch: 528 0\tLoss: 0.2817\n", 1105 | "Train Epoch: 528 1000\tLoss: 0.4051\n", 1106 | "Train Epoch: 528 2000\tLoss: 0.3741\n", 1107 | "Train Epoch: 528 3000\tLoss: 0.6958\n", 1108 | "Train Epoch: 528 4000\tLoss: 0.5083\n", 1109 | "---------------------------------------------\n", 1110 | "\n", 1111 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1112 | "\n", 1113 | "Train Epoch: 529 0\tLoss: 0.2817\n", 1114 | "Train Epoch: 529 1000\tLoss: 0.4051\n", 1115 | "Train Epoch: 529 2000\tLoss: 0.3741\n", 1116 | "Train Epoch: 529 3000\tLoss: 0.6958\n", 1117 | "Train Epoch: 529 4000\tLoss: 0.5083\n", 1118 | "---------------------------------------------\n", 1119 | "\n", 1120 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1121 | "\n", 1122 | "Train Epoch: 530 0\tLoss: 0.2817\n", 1123 | "Train Epoch: 530 1000\tLoss: 0.4051\n", 1124 | "Train Epoch: 530 2000\tLoss: 0.3741\n", 1125 | "Train Epoch: 530 3000\tLoss: 0.6958\n", 1126 | "Train Epoch: 530 4000\tLoss: 0.5083\n", 1127 | "---------------------------------------------\n", 1128 | "\n", 1129 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1130 | "\n", 1131 | "Train Epoch: 531 0\tLoss: 0.2817\n", 1132 | "Train Epoch: 531 1000\tLoss: 0.4051\n", 1133 | "Train Epoch: 531 2000\tLoss: 0.3741\n", 1134 | "Train Epoch: 531 3000\tLoss: 0.6958\n", 1135 | "Train Epoch: 531 4000\tLoss: 0.5083\n", 1136 | "---------------------------------------------\n", 1137 | "\n", 1138 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1139 | "\n", 1140 | "Train Epoch: 532 0\tLoss: 0.2817\n", 1141 | "Train Epoch: 532 1000\tLoss: 0.4051\n", 1142 | "Train Epoch: 532 2000\tLoss: 0.3741\n", 1143 | "Train Epoch: 532 3000\tLoss: 0.6958\n", 1144 | "Train Epoch: 532 4000\tLoss: 0.5083\n", 1145 | "---------------------------------------------\n", 1146 | "\n", 1147 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1148 | "\n", 1149 | "Train Epoch: 533 0\tLoss: 0.2817\n", 1150 | "Train Epoch: 533 1000\tLoss: 0.4051\n", 1151 | "Train Epoch: 533 2000\tLoss: 0.3741\n", 1152 | "Train Epoch: 533 3000\tLoss: 0.6958\n", 1153 | "Train Epoch: 533 4000\tLoss: 0.5083\n", 1154 | "---------------------------------------------\n", 1155 | "\n", 1156 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1157 | "\n", 1158 | "Train Epoch: 534 0\tLoss: 0.2817\n", 1159 | "Train Epoch: 534 1000\tLoss: 0.4051\n", 1160 | "Train Epoch: 534 2000\tLoss: 0.3741\n", 1161 | "Train Epoch: 534 3000\tLoss: 0.6958\n", 1162 | "Train Epoch: 534 4000\tLoss: 0.5083\n", 1163 | "---------------------------------------------\n", 1164 | "\n", 1165 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1166 | "\n", 1167 | "Train Epoch: 535 0\tLoss: 0.2817\n", 1168 | "Train Epoch: 535 1000\tLoss: 0.4051\n", 1169 | "Train Epoch: 535 2000\tLoss: 0.3741\n", 1170 | "Train Epoch: 535 3000\tLoss: 0.6958\n", 1171 | "Train Epoch: 535 4000\tLoss: 0.5083\n", 1172 | "---------------------------------------------\n", 1173 | "\n", 1174 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1175 | "\n", 1176 | "Train Epoch: 536 0\tLoss: 0.2817\n", 1177 | "Train Epoch: 536 1000\tLoss: 0.4051\n", 1178 | "Train Epoch: 536 2000\tLoss: 0.3741\n", 1179 | "Train Epoch: 536 3000\tLoss: 0.6958\n", 1180 | "Train Epoch: 536 4000\tLoss: 0.5083\n", 1181 | "---------------------------------------------\n", 1182 | "\n", 1183 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1184 | "\n", 1185 | "Train Epoch: 537 0\tLoss: 0.2817\n", 1186 | "Train Epoch: 537 1000\tLoss: 0.4051\n", 1187 | "Train Epoch: 537 2000\tLoss: 0.3741\n", 1188 | "Train Epoch: 537 3000\tLoss: 0.6958\n", 1189 | "Train Epoch: 537 4000\tLoss: 0.5083\n", 1190 | "---------------------------------------------\n", 1191 | "\n", 1192 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1193 | "\n", 1194 | "Train Epoch: 538 0\tLoss: 0.2817\n", 1195 | "Train Epoch: 538 1000\tLoss: 0.4051\n", 1196 | "Train Epoch: 538 2000\tLoss: 0.3741\n", 1197 | "Train Epoch: 538 3000\tLoss: 0.6958\n", 1198 | "Train Epoch: 538 4000\tLoss: 0.5083\n", 1199 | "---------------------------------------------\n", 1200 | "\n", 1201 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1202 | "\n", 1203 | "Train Epoch: 539 0\tLoss: 0.2817\n", 1204 | "Train Epoch: 539 1000\tLoss: 0.4051\n", 1205 | "Train Epoch: 539 2000\tLoss: 0.3741\n", 1206 | "Train Epoch: 539 3000\tLoss: 0.6958\n", 1207 | "Train Epoch: 539 4000\tLoss: 0.5083\n", 1208 | "---------------------------------------------\n", 1209 | "\n", 1210 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1211 | "\n", 1212 | "Train Epoch: 540 0\tLoss: 0.2817\n", 1213 | "Train Epoch: 540 1000\tLoss: 0.4051\n", 1214 | "Train Epoch: 540 2000\tLoss: 0.3741\n", 1215 | "Train Epoch: 540 3000\tLoss: 0.6958\n", 1216 | "Train Epoch: 540 4000\tLoss: 0.5083\n", 1217 | "---------------------------------------------\n", 1218 | "\n", 1219 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1220 | "\n", 1221 | "Train Epoch: 541 0\tLoss: 0.2817\n", 1222 | "Train Epoch: 541 1000\tLoss: 0.4051\n", 1223 | "Train Epoch: 541 2000\tLoss: 0.3741\n", 1224 | "Train Epoch: 541 3000\tLoss: 0.6958\n", 1225 | "Train Epoch: 541 4000\tLoss: 0.5083\n", 1226 | "---------------------------------------------\n", 1227 | "\n", 1228 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1229 | "\n", 1230 | "Train Epoch: 542 0\tLoss: 0.2817\n", 1231 | "Train Epoch: 542 1000\tLoss: 0.4051\n", 1232 | "Train Epoch: 542 2000\tLoss: 0.3741\n", 1233 | "Train Epoch: 542 3000\tLoss: 0.6958\n", 1234 | "Train Epoch: 542 4000\tLoss: 0.5083\n", 1235 | "---------------------------------------------\n", 1236 | "\n", 1237 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1238 | "\n", 1239 | "Train Epoch: 543 0\tLoss: 0.2817\n", 1240 | "Train Epoch: 543 1000\tLoss: 0.4051\n", 1241 | "Train Epoch: 543 2000\tLoss: 0.3741\n", 1242 | "Train Epoch: 543 3000\tLoss: 0.6958\n", 1243 | "Train Epoch: 543 4000\tLoss: 0.5083\n", 1244 | "---------------------------------------------\n", 1245 | "\n", 1246 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1247 | "\n", 1248 | "Train Epoch: 544 0\tLoss: 0.2817\n", 1249 | "Train Epoch: 544 1000\tLoss: 0.4051\n", 1250 | "Train Epoch: 544 2000\tLoss: 0.3741\n", 1251 | "Train Epoch: 544 3000\tLoss: 0.6958\n", 1252 | "Train Epoch: 544 4000\tLoss: 0.5083\n", 1253 | "---------------------------------------------\n", 1254 | "\n", 1255 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1256 | "\n", 1257 | "Train Epoch: 545 0\tLoss: 0.2817\n", 1258 | "Train Epoch: 545 1000\tLoss: 0.4051\n", 1259 | "Train Epoch: 545 2000\tLoss: 0.3741\n", 1260 | "Train Epoch: 545 3000\tLoss: 0.6958\n", 1261 | "Train Epoch: 545 4000\tLoss: 0.5083\n", 1262 | "---------------------------------------------\n", 1263 | "\n", 1264 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1265 | "\n", 1266 | "Train Epoch: 546 0\tLoss: 0.2817\n", 1267 | "Train Epoch: 546 1000\tLoss: 0.4051\n", 1268 | "Train Epoch: 546 2000\tLoss: 0.3741\n", 1269 | "Train Epoch: 546 3000\tLoss: 0.6958\n", 1270 | "Train Epoch: 546 4000\tLoss: 0.5083\n", 1271 | "---------------------------------------------\n", 1272 | "\n", 1273 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1274 | "\n", 1275 | "Train Epoch: 547 0\tLoss: 0.2817\n", 1276 | "Train Epoch: 547 1000\tLoss: 0.4051\n", 1277 | "Train Epoch: 547 2000\tLoss: 0.3741\n", 1278 | "Train Epoch: 547 3000\tLoss: 0.6958\n", 1279 | "Train Epoch: 547 4000\tLoss: 0.5083\n", 1280 | "---------------------------------------------\n", 1281 | "\n", 1282 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1283 | "\n", 1284 | "Train Epoch: 548 0\tLoss: 0.2817\n", 1285 | "Train Epoch: 548 1000\tLoss: 0.4051\n", 1286 | "Train Epoch: 548 2000\tLoss: 0.3741\n", 1287 | "Train Epoch: 548 3000\tLoss: 0.6958\n", 1288 | "Train Epoch: 548 4000\tLoss: 0.5083\n", 1289 | "---------------------------------------------\n", 1290 | "\n", 1291 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1292 | "\n", 1293 | "Train Epoch: 549 0\tLoss: 0.2817\n", 1294 | "Train Epoch: 549 1000\tLoss: 0.4051\n", 1295 | "Train Epoch: 549 2000\tLoss: 0.3741\n", 1296 | "Train Epoch: 549 3000\tLoss: 0.6958\n", 1297 | "Train Epoch: 549 4000\tLoss: 0.5083\n", 1298 | "---------------------------------------------\n", 1299 | "\n", 1300 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1301 | "\n", 1302 | "Train Epoch: 550 0\tLoss: 0.2817\n", 1303 | "Train Epoch: 550 1000\tLoss: 0.4051\n", 1304 | "Train Epoch: 550 2000\tLoss: 0.3741\n", 1305 | "Train Epoch: 550 3000\tLoss: 0.6958\n", 1306 | "Train Epoch: 550 4000\tLoss: 0.5083\n", 1307 | "---------------------------------------------\n", 1308 | "\n", 1309 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1310 | "\n", 1311 | "Train Epoch: 551 0\tLoss: 0.2817\n", 1312 | "Train Epoch: 551 1000\tLoss: 0.4051\n", 1313 | "Train Epoch: 551 2000\tLoss: 0.3741\n", 1314 | "Train Epoch: 551 3000\tLoss: 0.6958\n", 1315 | "Train Epoch: 551 4000\tLoss: 0.5083\n", 1316 | "---------------------------------------------\n", 1317 | "\n", 1318 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1319 | "\n", 1320 | "Train Epoch: 552 0\tLoss: 0.2817\n", 1321 | "Train Epoch: 552 1000\tLoss: 0.4051\n", 1322 | "Train Epoch: 552 2000\tLoss: 0.3741\n", 1323 | "Train Epoch: 552 3000\tLoss: 0.6958\n", 1324 | "Train Epoch: 552 4000\tLoss: 0.5083\n", 1325 | "---------------------------------------------\n", 1326 | "\n", 1327 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1328 | "\n", 1329 | "Train Epoch: 553 0\tLoss: 0.2817\n", 1330 | "Train Epoch: 553 1000\tLoss: 0.4051\n", 1331 | "Train Epoch: 553 2000\tLoss: 0.3741\n", 1332 | "Train Epoch: 553 3000\tLoss: 0.6958\n", 1333 | "Train Epoch: 553 4000\tLoss: 0.5083\n", 1334 | "---------------------------------------------\n", 1335 | "\n", 1336 | "Test set: Average loss: 0.5481, Accuracy: 232/500 (46.40%)\n", 1337 | "\n", 1338 | "Train Epoch: 554 0\tLoss: 0.2817\n", 1339 | "Train Epoch: 554 1000\tLoss: 0.4051\n", 1340 | "Train Epoch: 554 2000\tLoss: 0.3741\n", 1341 | "Train Epoch: 554 3000\tLoss: 0.6958\n" 1342 | ] 1343 | } 1344 | ] 1345 | }, 1346 | { 1347 | "cell_type": "markdown", 1348 | "metadata": { 1349 | "id": "wM3QoS2buZe7" 1350 | }, 1351 | "source": [ 1352 | "## Exercise 3 (6%) \n", 1353 | "For this experiment, try the following learning rate (lr=0.0001, 0.001, 0.01, 0.1). What do you observed?

\n", 1354 | "For example, at lr=0.001, test acc reach 100% at epoch xx... At lr=0.001, test acc reach 100% at epoch xx. As lr increases / decreases, what happen?\n" 1355 | ] 1356 | }, 1357 | { 1358 | "cell_type": "markdown", 1359 | "metadata": { 1360 | "id": "yH5tn9G1ugD1" 1361 | }, 1362 | "source": [ 1363 | "### Your answer here\n" 1364 | ] 1365 | }, 1366 | { 1367 | "cell_type": "markdown", 1368 | "metadata": { 1369 | "id": "P1d47bLhDMlw" 1370 | }, 1371 | "source": [ 1372 | "# Submission Instructions\n", 1373 | "Once you are finished, follow these steps:\n", 1374 | "\n", 1375 | "Restart the kernel and re-run this notebook from beginning to end by going to Kernel > Restart Kernel and Run All Cells.\n", 1376 | "If this process stops halfway through, that means there was an error. Correct the error and repeat Step 1 until the notebook runs from beginning to end.\n", 1377 | "Double check that there is a number next to each code cell and that these numbers are in order.\n", 1378 | "Then, submit your lab as follows:\n", 1379 | "\n", 1380 | "Go to File > Print > Save as PDF.\n", 1381 | "Double check that the entire notebook, from beginning to end, is in this PDF file. Make sure Solution for Exercise 5 are in for marks. \n", 1382 | "Upload the PDF to Spectrum. " 1383 | ] 1384 | }, 1385 | { 1386 | "cell_type": "markdown", 1387 | "metadata": { 1388 | "id": "4FBd4KLZwyVB" 1389 | }, 1390 | "source": [ 1391 | "# Acknowledgement\n", 1392 | "\n", 1393 | "Some of the works are inspired from \n", 1394 | "1. Effect of learning rate on AI model = https://www.commonlounge.com/discussion/5076b2cfb2364594ba608fca3ac606bb" 1395 | ] 1396 | } 1397 | ] 1398 | } -------------------------------------------------------------------------------- /Week3/XOR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week3/XOR.jpg -------------------------------------------------------------------------------- /Week4/MnistExamples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week4/MnistExamples.png -------------------------------------------------------------------------------- /Week4/README: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Week4/W4.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week4/W4.pptx -------------------------------------------------------------------------------- /Week4/WOA7015_Wk4.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "WOA7015_Wk4.ipynb", 7 | "provenance": [], 8 | "collapsed_sections": [], 9 | "authorship_tag": "ABX9TyMTgQdYvrjN0mSEo1r267hp", 10 | "include_colab_link": true 11 | }, 12 | "kernelspec": { 13 | "name": "python3", 14 | "display_name": "Python 3" 15 | }, 16 | "language_info": { 17 | "name": "python" 18 | } 19 | }, 20 | "cells": [ 21 | { 22 | "cell_type": "markdown", 23 | "metadata": { 24 | "id": "view-in-github", 25 | "colab_type": "text" 26 | }, 27 | "source": [ 28 | "\"Open" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": { 34 | "id": "Cw5hkuTyx3VO" 35 | }, 36 | "source": [ 37 | "# Welcome to WOA7015 Advance Machine Learning Lab - Week 4\n", 38 | "This code is generated for the purpose of WOA7015 module.\n", 39 | "The code is available in github https://github.com/shiernee/Advanced_ML \n" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": { 45 | "id": "INxzH5Bqw5dq" 46 | }, 47 | "source": [ 48 | "## 1.0 Effect of weight and bias to sigmoid function\n", 49 | "This is the code to generate the figure in slide 6" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "metadata": { 55 | "id": "2HctFBauH47o" 56 | }, 57 | "source": [ 58 | "#### 1.1 Effect of weight on sigmoid function" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "metadata": { 64 | "id": "ah7KAg-fsGWY" 65 | }, 66 | "source": [ 67 | "import matplotlib.pyplot as plt\n", 68 | "import numpy as np\n", 69 | "import imageio\n", 70 | "\n", 71 | "# create sigmoid function\n", 72 | "f = lambda x, w, b: 1/(1 + np.exp(-(w*x + b)))\n", 73 | "\n", 74 | "x = np.arange(-10, 10, 0.01).reshape([-1, 1])\n", 75 | "\n", 76 | "# effect of weight on sigmoid function\n", 77 | "filenames = []\n", 78 | "for i in np.arange(1, 5, 0.1):\n", 79 | " w = np.ones([1, 1]) * i * 0.5\n", 80 | " b = np.ones([1, 1]) * 0\n", 81 | "\n", 82 | " plt.plot(x, f(x, w, b))\n", 83 | " plt.title('w = %0.1f' % i)\n", 84 | " plt.grid()\n", 85 | " plt.savefig('w %0.1f.png' % i)\n", 86 | " plt.close()\n", 87 | " filenames.append('w %0.1f.png' % i)\n", 88 | "\n", 89 | "# Build GIF\n", 90 | "with imageio.get_writer('w_mygif.gif', mode='I') as writer:\n", 91 | " for filename in filenames:\n", 92 | " image = imageio.imread(filename)\n", 93 | " writer.append_data(image)\n", 94 | "\n" 95 | ], 96 | "execution_count": 1, 97 | "outputs": [] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "id": "JYbm63A9H91J" 103 | }, 104 | "source": [ 105 | "#### 1.1 Effect of bias on sigmoid function" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "metadata": { 111 | "id": "s1QreLFgHyIi" 112 | }, 113 | "source": [ 114 | "import matplotlib.pyplot as plt\n", 115 | "import numpy as np\n", 116 | "import imageio\n", 117 | "\n", 118 | "# create sigmoid function\n", 119 | "f = lambda x, w, b: 1/(1 + np.exp(-(w*x + b)))\n", 120 | "\n", 121 | "x = np.arange(-10, 10, 0.01).reshape([-1, 1])\n", 122 | "\n", 123 | "# effect of bias on sigmoid function\n", 124 | "filenames = []\n", 125 | "for i in np.arange(1, 5, 0.1):\n", 126 | " w = np.ones([1, 1])\n", 127 | " b = np.ones([1, 1])* i\n", 128 | "\n", 129 | " plt.plot(x, f(x, w, b))\n", 130 | " plt.title('b = %0.1f' % i)\n", 131 | " plt.grid()\n", 132 | " plt.savefig('b %0.1f.png' % i)\n", 133 | " plt.close()\n", 134 | " filenames.append('b %0.1f.png' % i)\n", 135 | "\n", 136 | "# Build GIF\n", 137 | "with imageio.get_writer('b_mygif.gif', mode='I') as writer:\n", 138 | " for filename in filenames:\n", 139 | " image = imageio.imread(filename)\n", 140 | " writer.append_data(image)\n" 141 | ], 142 | "execution_count": 5, 143 | "outputs": [] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": { 148 | "id": "iXAZiEqSEbDH" 149 | }, 150 | "source": [ 151 | "# 2.0 Logistic Regression\n", 152 | "\n", 153 | "In this section, we will learn how to create train a Logistic Regression Model using pytorch. We will use MNIST image, as shown below.

\n", 154 | "\n", 155 | "PyTorch (https://pytorch.org/) is an open source machine learning library based on the Torch library, used for applications such as computer vision and natural language processing, primarily developed by Facebook's AI Research lab. \n", 156 | "\n", 157 | "\n", 158 | "
\n", 159 | "\n", 160 | "\n" 161 | ] 162 | }, 163 | { 164 | "cell_type": "code", 165 | "metadata": { 166 | "id": "5NXavLptEdGe" 167 | }, 168 | "source": [ 169 | "# 2.1 import library\n", 170 | "import torch\n", 171 | "import torch.nn as nn\n", 172 | "import torchvision\n", 173 | "import torchvision.transforms as transforms\n" 174 | ], 175 | "execution_count": 6, 176 | "outputs": [] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "metadata": { 181 | "id": "crKCbRxdFD86" 182 | }, 183 | "source": [ 184 | "#2.2 Set the Hyper-parameters \n", 185 | "input_size = 28 * 28 # 784\n", 186 | "num_classes = 10\n", 187 | "num_epochs = 5\n", 188 | "batch_size = 100\n", 189 | "learning_rate = 0.001\n" 190 | ], 191 | "execution_count": 7, 192 | "outputs": [] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "metadata": { 197 | "id": "cZXRWEdzFt_Z" 198 | }, 199 | "source": [ 200 | "#2.3 Data loader\n", 201 | "# MNIST dataset (images and labels)\n", 202 | "train_dataset = torchvision.datasets.MNIST(root='../../data', \n", 203 | " train=True, \n", 204 | " transform=transforms.ToTensor())\n", 205 | "\n", 206 | "test_dataset = torchvision.datasets.MNIST(root='../../data', \n", 207 | " train=False, \n", 208 | " transform=transforms.ToTensor())\n", 209 | "\n", 210 | "# Data loader (input pipeline)\n", 211 | "train_loader = torch.utils.data.DataLoader(dataset=train_dataset, \n", 212 | " batch_size=batch_size, \n", 213 | " shuffle=True)\n", 214 | "\n", 215 | "test_loader = torch.utils.data.DataLoader(dataset=test_dataset, \n", 216 | " batch_size=batch_size, \n", 217 | " shuffle=False)\n" 218 | ], 219 | "execution_count": 11, 220 | "outputs": [] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "metadata": { 225 | "colab": { 226 | "base_uri": "https://localhost:8080/", 227 | "height": 587 228 | }, 229 | "id": "PCMGIa6ZLxWX", 230 | "outputId": "8cbe4714-bd53-4744-cacc-b3b2099965de" 231 | }, 232 | "source": [ 233 | "# 2.3.1 Check data \n", 234 | "print(train_dataset)\n", 235 | "print('----------------')\n", 236 | "print(test_dataset)\n", 237 | "print()\n", 238 | "\n", 239 | "import matplotlib.pyplot as plt\n", 240 | "print('training data shape: ', train_dataset.data.shape)\n", 241 | "n = np.random.randint(0, 60000)\n", 242 | "plt.imshow(train_dataset.data[n])\n", 243 | "plt.title(f'n = %d label = %d' % (n, train_dataset.train_labels[n].numpy()))\n" 244 | ], 245 | "execution_count": 34, 246 | "outputs": [ 247 | { 248 | "output_type": "stream", 249 | "name": "stdout", 250 | "text": [ 251 | "Dataset MNIST\n", 252 | " Number of datapoints: 60000\n", 253 | " Root location: ../../data\n", 254 | " Split: Train\n", 255 | " StandardTransform\n", 256 | "Transform: ToTensor()\n", 257 | "----------------\n", 258 | "Dataset MNIST\n", 259 | " Number of datapoints: 10000\n", 260 | " Root location: ../../data\n", 261 | " Split: Test\n", 262 | " StandardTransform\n", 263 | "Transform: ToTensor()\n", 264 | "\n", 265 | "training data shape: torch.Size([60000, 28, 28])\n" 266 | ] 267 | }, 268 | { 269 | "output_type": "stream", 270 | "name": "stderr", 271 | "text": [ 272 | "/usr/local/lib/python3.7/dist-packages/torchvision/datasets/mnist.py:52: UserWarning: train_labels has been renamed targets\n", 273 | " warnings.warn(\"train_labels has been renamed targets\")\n" 274 | ] 275 | }, 276 | { 277 | "output_type": "execute_result", 278 | "data": { 279 | "text/plain": [ 280 | "Text(0.5, 1.0, 'n = 47414 label = 5')" 281 | ] 282 | }, 283 | "metadata": {}, 284 | "execution_count": 34 285 | }, 286 | { 287 | "output_type": "display_data", 288 | "data": { 289 | "image/png": "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\n", 290 | "text/plain": [ 291 | "
" 292 | ] 293 | }, 294 | "metadata": { 295 | "needs_background": "light" 296 | } 297 | } 298 | ] 299 | }, 300 | { 301 | "cell_type": "code", 302 | "metadata": { 303 | "id": "N6ZE4roJF0HA" 304 | }, 305 | "source": [ 306 | "#2.4 Logistic regression model\n", 307 | "model = nn.Linear(input_size, num_classes)\n" 308 | ], 309 | "execution_count": 35, 310 | "outputs": [] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "metadata": { 315 | "id": "XXCxm64GH27K" 316 | }, 317 | "source": [ 318 | "#2.5 Cross Entropy Loss \n", 319 | "# nn.CrossEntropyLoss() computes softmax internally\n", 320 | "criterion = nn.CrossEntropyLoss() \n" 321 | ], 322 | "execution_count": 36, 323 | "outputs": [] 324 | }, 325 | { 326 | "cell_type": "code", 327 | "metadata": { 328 | "id": "pm2Q-PDcH34b" 329 | }, 330 | "source": [ 331 | "#2.6 Optimizer Stochastic Gradient Descent \n", 332 | "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate) \n" 333 | ], 334 | "execution_count": 37, 335 | "outputs": [] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "metadata": { 340 | "id": "4TO7Egs7F2o9" 341 | }, 342 | "source": [ 343 | "#2.7 Train the model\n", 344 | "total_step = len(train_loader)\n", 345 | "for epoch in range(num_epochs):\n", 346 | " for i, (images, labels) in enumerate(train_loader):\n", 347 | " # Reshape images to (batch_size, input_size)\n", 348 | " images = images.reshape(-1, input_size)\n", 349 | " \n", 350 | " # Forward pass\n", 351 | " outputs = model(images)\n", 352 | " loss = criterion(outputs, labels)\n", 353 | "\n", 354 | " # Backward and optimize\n", 355 | " optimizer.zero_grad()\n", 356 | " loss.backward()\n", 357 | " optimizer.step()\n", 358 | " \n", 359 | " if (i+1) % 100 == 0:\n", 360 | " print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}' \n", 361 | " .format(epoch+1, num_epochs, i+1, total_step, loss.item()))" 362 | ], 363 | "execution_count": null, 364 | "outputs": [] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "metadata": { 369 | "id": "fGO_mdMZF4iS", 370 | "colab": { 371 | "base_uri": "https://localhost:8080/" 372 | }, 373 | "outputId": "7b99b627-0111-4f1a-9103-b7762f59baa8" 374 | }, 375 | "source": [ 376 | "#2.8 Test the model\n", 377 | "# In test phase, we don't need to compute gradients (for memory efficiency)\n", 378 | "with torch.no_grad():\n", 379 | " correct = 0\n", 380 | " total = 0\n", 381 | " for images, labels in test_loader:\n", 382 | " images = images.reshape(-1, input_size)\n", 383 | " outputs = model(images)\n", 384 | " _, predicted = torch.max(outputs.data, 1)\n", 385 | " total += labels.size(0)\n", 386 | " correct += (predicted == labels).sum()\n", 387 | "\n", 388 | " print('Accuracy of the model on the 10000 test images: {} %'.format(100 * correct / total))\n" 389 | ], 390 | "execution_count": 39, 391 | "outputs": [ 392 | { 393 | "output_type": "stream", 394 | "name": "stdout", 395 | "text": [ 396 | "Accuracy of the model on the 10000 test images: 82.5 %\n" 397 | ] 398 | } 399 | ] 400 | }, 401 | { 402 | "cell_type": "code", 403 | "metadata": { 404 | "id": "EBEBeGYsF5t-" 405 | }, 406 | "source": [ 407 | "#2.9 Save the model checkpoint\n", 408 | "torch.save(model.state_dict(), 'model.ckpt')" 409 | ], 410 | "execution_count": 40, 411 | "outputs": [] 412 | }, 413 | { 414 | "cell_type": "markdown", 415 | "metadata": { 416 | "id": "j6nIkwr2YM9l" 417 | }, 418 | "source": [ 419 | "## Exercise 1 (10%): Create custom loss function\n", 420 | "In this section, you will need to create our own Cross Entropy loss function and compare with Pytorch's Cross Entropy loss. The objective of this exercise is to enable you to design your own loss in the future. \n", 421 | "\n", 422 | "Follow the steps below:\n", 423 | "1. Import libraries - copy section 2.1\n", 424 | "2. Set hyperparameter - copy section 2.2\n", 425 | "3. Data loader - copy section 2.3\n", 426 | "4. Initialize Logistic Regression - copy section 2.4\n", 427 | "5. Create custom_CrossEntropyLoss class - copy the following code. Your task is to ***code the log_softmax equation in the log_softmax function.*** \n", 428 | "\n", 429 | "```\n", 430 | "# Custom Loss - Cross Entropy Loss\n", 431 | "class custom_CrossEntropyLoss(nn.Module):\n", 432 | " def __init__(self, weight=None, size_average=True):\n", 433 | " super(custom_CrossEntropyLoss, self).__init__()\n", 434 | " \n", 435 | " def forward(self, inputs, targets, smooth=1): \n", 436 | " num_examples = targets.shape[0]\n", 437 | " batch_size = inputs.shape[0]\n", 438 | " softmax_outputs = self.log_softmax(inputs)\n", 439 | " outputs = softmax_outputs[range(batch_size), targets] \n", 440 | " return -torch.sum(outputs)/num_examples\n", 441 | "\n", 442 | " @staticmethod\n", 443 | " def log_softmax(x):\n", 444 | " return ### put the log_softmax function here ### \n", 445 | "```\n", 446 | "\n", 447 | "6. Initialize custom_CrossEntropyLoss loss as criterion - copy section 2.5. Replace *nn.CrossEntropyLoss* with *custom_CrossEntropyLoss*\n", 448 | "7. Train the model, evaluate it on your testing data. Save your model. \n", 449 | "8. Compare the loss computed from torch and our custom loss. \n", 450 | "\n", 451 | "\n", 452 | " 5% will be given if step 1 - 4 are done correctly
\n", 453 | " 3% will be given if step 5-7 is done correctly
\n", 454 | " 2% will be given if your custom loss and pytorch loss is near zero. " 455 | ] 456 | }, 457 | { 458 | "cell_type": "code", 459 | "metadata": { 460 | "id": "7azur5ciavP2" 461 | }, 462 | "source": [ 463 | "# your code here" 464 | ], 465 | "execution_count": null, 466 | "outputs": [] 467 | }, 468 | { 469 | "cell_type": "markdown", 470 | "metadata": { 471 | "id": "2d7IdSoak0p2" 472 | }, 473 | "source": [ 474 | "# Submission Instructions\n", 475 | "Once you are finished, follow these steps:\n", 476 | "\n", 477 | "Restart the kernel and re-run this notebook from beginning to end by going to Kernel > Restart Kernel and Run All Cells.\n", 478 | "If this process stops halfway through, that means there was an error. Correct the error and repeat Step 1 until the notebook runs from beginning to end.\n", 479 | "Double check that there is a number next to each code cell and that these numbers are in order.\n", 480 | "Then, submit your lab as follows:\n", 481 | "\n", 482 | "Go to File > Print > Save as PDF.\n", 483 | "Double check that the entire notebook, from beginning to end, is in this PDF file. Make sure Solution for Exercise 5 are in for marks. \n", 484 | "Upload the PDF to Spectrum. " 485 | ] 486 | } 487 | ] 488 | } -------------------------------------------------------------------------------- /Week5/CV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week5/CV.png -------------------------------------------------------------------------------- /Week5/CV_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week5/CV_test.png -------------------------------------------------------------------------------- /Week5/W5.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week5/W5.pptx -------------------------------------------------------------------------------- /Week5/iris.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week5/iris.PNG -------------------------------------------------------------------------------- /Week5/train_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week5/train_test.png -------------------------------------------------------------------------------- /Week6/W6.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week6/W6.pptx -------------------------------------------------------------------------------- /Week7/W7.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week7/W7.pptx -------------------------------------------------------------------------------- /Week8/W8.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week8/W8.pptx -------------------------------------------------------------------------------- /Week9/Adj_matrix.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week9/Adj_matrix.PNG -------------------------------------------------------------------------------- /Week9/Message_passing.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week9/Message_passing.PNG -------------------------------------------------------------------------------- /Week9/W9.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shiernee/Advanced_ML/09ae2103b9ccb9edbe80461ba6dbac148830d1ce/Week9/W9.pptx -------------------------------------------------------------------------------- /Week9/WOA7015_Wk9_Extra.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "colab": { 6 | "name": "WOA7015_Wk9_Extra.ipynb", 7 | "provenance": [], 8 | "authorship_tag": "ABX9TyMuy2xu5jnoqDQLIYuEVjiC", 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 | }, 19 | "cells": [ 20 | { 21 | "cell_type": "markdown", 22 | "metadata": { 23 | "id": "view-in-github", 24 | "colab_type": "text" 25 | }, 26 | "source": [ 27 | "\"Open" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "source": [ 33 | "# Welcome to WOA7015 Advance Machine Learning Lab - Week 9_extra\n", 34 | "This code is generated for the purpose of WOA7015 module.\n", 35 | "The code is available in github https://github.com/shiernee/Advanced_ML \n" 36 | ], 37 | "metadata": { 38 | "id": "NB-ogNj0uNhs" 39 | } 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": { 45 | "colab": { 46 | "base_uri": "https://localhost:8080/" 47 | }, 48 | "id": "jy2YuQ-suK7m", 49 | "outputId": "6b840de3-ef3c-4c76-f537-29c146f02be1" 50 | }, 51 | "outputs": [ 52 | { 53 | "output_type": "stream", 54 | "name": "stdout", 55 | "text": [ 56 | "[]\n" 57 | ] 58 | } 59 | ], 60 | "source": [ 61 | "# Create an empty graph with no nodes and no edges.\n", 62 | "import networkx as nx\n", 63 | "G = nx.Graph()\n", 64 | "print(list(G.nodes)) # examine element in nodes" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "source": [ 70 | "## Add nodes" 71 | ], 72 | "metadata": { 73 | "id": "zM4dl6K8wMhj" 74 | } 75 | }, 76 | { 77 | "cell_type": "code", 78 | "source": [ 79 | "G.add_node(1) # add one node\n", 80 | "print(list(G.nodes)) \n", 81 | "print()\n", 82 | "\n", 83 | "G.add_nodes_from([2, 3]) # add nodes from any iterable container, such as a list\n", 84 | "print(list(G.nodes))\n", 85 | "print()\n", 86 | "\n", 87 | "# add nodes along with node attributes if your container yields 2-tuples of the form (node, node_attribute_dict)\n", 88 | "G.add_nodes_from([\n", 89 | " (4, {\"color\": \"red\"}),\n", 90 | " (5, {\"color\": \"green\"}),\n", 91 | "])\n", 92 | "print(list(G.nodes)) \n", 93 | "print()\n", 94 | "\n", 95 | "# Nodes from one graph can be incorporated into another:\n", 96 | "H = nx.path_graph(10)\n", 97 | "print('H nodes: ', list(H.nodes))\n", 98 | "G.add_nodes_from(H)\n", 99 | "print('G nodes: ', list(G.nodes))\n", 100 | "print()\n", 101 | "\n", 102 | "G.add_node(H)\n", 103 | "print('G nodes: ', list(G.nodes))\n" 104 | ], 105 | "metadata": { 106 | "colab": { 107 | "base_uri": "https://localhost:8080/" 108 | }, 109 | "id": "fbLKZrdfujay", 110 | "outputId": "b0cd5a63-e817-4d0f-f545-092103200071" 111 | }, 112 | "execution_count": null, 113 | "outputs": [ 114 | { 115 | "output_type": "stream", 116 | "name": "stdout", 117 | "text": [ 118 | "[1]\n", 119 | "\n", 120 | "[1, 2, 3]\n", 121 | "\n", 122 | "[1, 2, 3, 4, 5]\n", 123 | "\n", 124 | "H nodes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", 125 | "G nodes: [1, 2, 3, 4, 5, 0, 6, 7, 8, 9]\n", 126 | "\n", 127 | "G nodes: [1, 2, 3, 4, 5, 0, 6, 7, 8, 9, ]\n" 128 | ] 129 | } 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "source": [ 135 | "# Add edges" 136 | ], 137 | "metadata": { 138 | "id": "_0Fx_PkVwObo" 139 | } 140 | }, 141 | { 142 | "cell_type": "code", 143 | "source": [ 144 | "G.add_edge(1, 2)\n", 145 | "print(list(G.edges))\n", 146 | "print()\n", 147 | "\n", 148 | "e = (2, 3)\n", 149 | "G.add_edge(*e) # unpack edge tuple*\n", 150 | "print(list(G.edges))\n", 151 | "print()\n", 152 | "\n", 153 | "G.add_edges_from([(1, 2), (1, 3)])\n", 154 | "print(list(G.edges))\n", 155 | "print()\n", 156 | "\n", 157 | "G.add_edges_from(H.edges)\n", 158 | "\n", 159 | "print(list(G.adj[1])) # or list(G.neighbors(1))" 160 | ], 161 | "metadata": { 162 | "colab": { 163 | "base_uri": "https://localhost:8080/" 164 | }, 165 | "id": "p08Fo4XLwPb9", 166 | "outputId": "087921c5-bd2d-40d3-eb39-a200687d36d9" 167 | }, 168 | "execution_count": null, 169 | "outputs": [ 170 | { 171 | "output_type": "stream", 172 | "name": "stdout", 173 | "text": [ 174 | "[(1, 2), (2, 3)]\n", 175 | "\n", 176 | "[(1, 2), (2, 3)]\n", 177 | "\n", 178 | "[1, 2, 3, 4, 5, 0, 6, 7, 8, 9, ]\n" 179 | ] 180 | } 181 | ] 182 | } 183 | ] 184 | } --------------------------------------------------------------------------------