├── .gitignore ├── Pytorch Introduction.ipynb └── images ├── intro_pytorch_gradient_descent.PNG ├── intro_pytorch_mnist.PNG ├── intro_pytorch_mnist_operations.PNG ├── intro_pytorch_negativeloglikelihood.PNG └── pytorhc_vs_tensorflow.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | -------------------------------------------------------------------------------- /Pytorch Introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Introduction to Pytorch\n", 8 | "\n", 9 | "" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 29, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import torch\n", 20 | "import matplotlib.pyplot as plt\n", 21 | "from mpl_toolkits.mplot3d import Axes3D" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": {}, 27 | "source": [ 28 | "## Recall Gradient Descent\n", 29 | "\n", 30 | "- [Formation au Deep Learning](https://www.youtube.com/playlist?list=PLpEPgC7cUJ4b1ARx8PyIQa_sdZRL2GXw5)\n", 31 | "- [Formation Tensorflow 2.0](https://www.youtube.com/playlist?list=PLpEPgC7cUJ4byTM5kGA0Te1jUeNwbSgfd)\n", 32 | "- [DESCENTE DE GRADIENT (GRADIENT DESCENT) - ML#4](https://www.youtube.com/watch?v=rcl_YRyoLIY&t=3s)\n", 33 | "- [La descente de gradient (stochastique) | Intelligence artificielle 42](https://www.youtube.com/watch?v=Q9-vDFvDdfg)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "### A simple function to minimize" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 32, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stderr", 50 | "output_type": "stream", 51 | "text": [ 52 | "C:\\Users\\Thibault\\Anaconda3\\envs\\ai-3.7\\lib\\site-packages\\ipykernel_launcher.py:13: UserWarning: The following kwargs were not used by contour: 'color'\n", 53 | " del sys.path[0]\n" 54 | ] 55 | }, 56 | { 57 | "data": { 58 | "image/png": "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\n", 59 | "text/plain": [ 60 | "
" 61 | ] 62 | }, 63 | "metadata": { 64 | "needs_background": "light" 65 | }, 66 | "output_type": "display_data" 67 | } 68 | ], 69 | "source": [ 70 | "def f(x, y):\n", 71 | " return x ** 2 + y ** 2\n", 72 | "\n", 73 | "x = np.linspace(-6, 6, 30)\n", 74 | "y = np.linspace(-6, 6, 30)\n", 75 | "\n", 76 | "X, Y = np.meshgrid(x, y)\n", 77 | "\n", 78 | "Z = f(X, Y)\n", 79 | "\n", 80 | "fig = plt.figure()\n", 81 | "ax = plt.axes(projection='3d')\n", 82 | "ax.contour(X, Y, Z, 50, cmap='binary', color=\"r\")\n", 83 | "ax.set_xlabel('parma1')\n", 84 | "ax.set_ylabel('param2')\n", 85 | "ax.set_zlabel('error')\n", 86 | "\n", 87 | "ax.view_init(30, 30)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "### Create the two variables" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 37, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "x = torch.tensor(3, dtype=torch.float, requires_grad=True)\n", 104 | "y = torch.tensor(3, dtype=torch.float, requires_grad=True)" 105 | ] 106 | }, 107 | { 108 | "cell_type": "markdown", 109 | "metadata": {}, 110 | "source": [ 111 | "### Minimize the function by applying gradient descent\n", 112 | "\n", 113 | "" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 50, 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "Result = >> tensor(11.5200, grad_fn=)\n", 126 | "Result = >> tensor(7.3728, grad_fn=)\n", 127 | "Result = >> tensor(4.7186, grad_fn=)\n", 128 | "Result = >> tensor(3.0199, grad_fn=)\n", 129 | "Result = >> tensor(1.9327, grad_fn=)\n", 130 | "Result = >> tensor(1.2370, grad_fn=)\n", 131 | "Result = >> tensor(0.7916, grad_fn=)\n", 132 | "Result = >> tensor(0.5067, grad_fn=)\n", 133 | "Result = >> tensor(0.3243, grad_fn=)\n", 134 | "Result = >> tensor(0.2075, grad_fn=)\n", 135 | "Result = >> tensor(0.1328, grad_fn=)\n", 136 | "Result = >> tensor(0.0850, grad_fn=)\n", 137 | "Result = >> tensor(0.0544, grad_fn=)\n", 138 | "Result = >> tensor(0.0348, grad_fn=)\n", 139 | "Result = >> tensor(0.0223, grad_fn=)\n", 140 | "Result = >> tensor(0.0143, grad_fn=)\n", 141 | "Result = >> tensor(0.0091, grad_fn=)\n", 142 | "Result = >> tensor(0.0058, grad_fn=)\n", 143 | "Result = >> tensor(0.0037, grad_fn=)\n", 144 | "Result = >> tensor(0.0024, grad_fn=)\n", 145 | "Result = >> tensor(0.0015, grad_fn=)\n", 146 | "Result = >> tensor(0.0010, grad_fn=)\n", 147 | "Result = >> tensor(0.0006, grad_fn=)\n", 148 | "Result = >> tensor(0.0004, grad_fn=)\n", 149 | "Result = >> tensor(0.0003, grad_fn=)\n", 150 | "Result = >> tensor(0.0002, grad_fn=)\n", 151 | "Result = >> tensor(0.0001, grad_fn=)\n", 152 | "Result = >> tensor(6.7346e-05, grad_fn=)\n", 153 | "Result = >> tensor(4.3101e-05, grad_fn=)\n", 154 | "Result = >> tensor(2.7585e-05, grad_fn=)\n", 155 | "Result = >> tensor(1.7654e-05, grad_fn=)\n", 156 | "Result = >> tensor(1.1299e-05, grad_fn=)\n", 157 | "Result = >> tensor(7.2312e-06, grad_fn=)\n", 158 | "Result = >> tensor(4.6280e-06, grad_fn=)\n", 159 | "Result = >> tensor(2.9619e-06, grad_fn=)\n", 160 | "Result = >> tensor(1.8956e-06, grad_fn=)\n", 161 | "Result = >> tensor(1.2132e-06, grad_fn=)\n", 162 | "Result = >> tensor(7.7645e-07, grad_fn=)\n", 163 | "Result = >> tensor(4.9693e-07, grad_fn=)\n", 164 | "Result = >> tensor(3.1803e-07, grad_fn=)\n", 165 | "Result = >> tensor(2.0354e-07, grad_fn=)\n", 166 | "Result = >> tensor(1.3027e-07, grad_fn=)\n", 167 | "Result = >> tensor(8.3370e-08, grad_fn=)\n", 168 | "Result = >> tensor(5.3357e-08, grad_fn=)\n", 169 | "Result = >> tensor(3.4148e-08, grad_fn=)\n", 170 | "Result = >> tensor(2.1855e-08, grad_fn=)\n", 171 | "Result = >> tensor(1.3987e-08, grad_fn=)\n", 172 | "Result = >> tensor(8.9518e-09, grad_fn=)\n", 173 | "Result = >> tensor(5.7292e-09, grad_fn=)\n", 174 | "Result = >> tensor(3.6667e-09, grad_fn=)\n", 175 | "Result = >> tensor(2.3467e-09, grad_fn=)\n", 176 | "Result = >> tensor(1.5019e-09, grad_fn=)\n", 177 | "Result = >> tensor(9.6119e-10, grad_fn=)\n", 178 | "Result = >> tensor(6.1516e-10, grad_fn=)\n", 179 | "Result = >> tensor(3.9371e-10, grad_fn=)\n", 180 | "Result = >> tensor(2.5197e-10, grad_fn=)\n", 181 | "Result = >> tensor(1.6126e-10, grad_fn=)\n", 182 | "Result = >> tensor(1.0321e-10, grad_fn=)\n", 183 | "Result = >> tensor(6.6053e-11, grad_fn=)\n", 184 | "Result = >> tensor(4.2274e-11, grad_fn=)\n", 185 | "Result = >> tensor(2.7055e-11, grad_fn=)\n", 186 | "Result = >> tensor(1.7315e-11, grad_fn=)\n", 187 | "Result = >> tensor(1.1082e-11, grad_fn=)\n", 188 | "Result = >> tensor(7.0924e-12, grad_fn=)\n", 189 | "Result = >> tensor(4.5391e-12, grad_fn=)\n", 190 | "Result = >> tensor(2.9050e-12, grad_fn=)\n", 191 | "Result = >> tensor(1.8592e-12, grad_fn=)\n", 192 | "Result = >> tensor(1.1899e-12, grad_fn=)\n", 193 | "Result = >> tensor(7.6154e-13, grad_fn=)\n", 194 | "Result = >> tensor(4.8738e-13, grad_fn=)\n", 195 | "Result = >> tensor(3.1193e-13, grad_fn=)\n", 196 | "Result = >> tensor(1.9963e-13, grad_fn=)\n", 197 | "Result = >> tensor(1.2776e-13, grad_fn=)\n", 198 | "Result = >> tensor(8.1769e-14, grad_fn=)\n", 199 | "Result = >> tensor(5.2332e-14, grad_fn=)\n", 200 | "Result = >> tensor(3.3493e-14, grad_fn=)\n", 201 | "Result = >> tensor(2.1435e-14, grad_fn=)\n", 202 | "Result = >> tensor(1.3719e-14, grad_fn=)\n", 203 | "Result = >> tensor(8.7799e-15, grad_fn=)\n", 204 | "Result = >> tensor(5.6191e-15, grad_fn=)\n", 205 | "Result = >> tensor(3.5963e-15, grad_fn=)\n", 206 | "Result = >> tensor(2.3016e-15, grad_fn=)\n", 207 | "Result = >> tensor(1.4730e-15, grad_fn=)\n", 208 | "Result = >> tensor(9.4274e-16, grad_fn=)\n", 209 | "Result = >> tensor(6.0335e-16, grad_fn=)\n", 210 | "Result = >> tensor(3.8614e-16, grad_fn=)\n", 211 | "Result = >> tensor(2.4713e-16, grad_fn=)\n", 212 | "Result = >> tensor(1.5816e-16, grad_fn=)\n", 213 | "Result = >> tensor(1.0123e-16, grad_fn=)\n", 214 | "Result = >> tensor(6.4784e-17, grad_fn=)\n", 215 | "Result = >> tensor(4.1462e-17, grad_fn=)\n", 216 | "Result = >> tensor(2.6536e-17, grad_fn=)\n", 217 | "Result = >> tensor(1.6983e-17, grad_fn=)\n", 218 | "Result = >> tensor(1.0869e-17, grad_fn=)\n", 219 | "Result = >> tensor(6.9562e-18, grad_fn=)\n", 220 | "Result = >> tensor(4.4519e-18, grad_fn=)\n", 221 | "Result = >> tensor(2.8492e-18, grad_fn=)\n", 222 | "Result = >> tensor(1.8235e-18, grad_fn=)\n", 223 | "Result = >> tensor(1.1671e-18, grad_fn=)\n", 224 | "Result = >> tensor(7.4691e-19, grad_fn=)\n" 225 | ] 226 | } 227 | ], 228 | "source": [ 229 | "for i in range(100):\n", 230 | " # Compute the operation. We want to minimise the result. To do so we can compute\n", 231 | " # the gradient of each variable and apply the gradient descent formula.\n", 232 | " result = x**2 + y**2\n", 233 | " print(\"Result = >>\", result)\n", 234 | " \n", 235 | " # Compute the gradient for each operations made before\n", 236 | " result.backward()\n", 237 | " \n", 238 | " # Apply gradient descent without tracking the gradient.\n", 239 | " with torch.no_grad():\n", 240 | " x -= 0.1*x.grad\n", 241 | " y -= 0.1*y.grad\n", 242 | " \n", 243 | " x.grad.zero_()\n", 244 | " y.grad.zero_()" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 51, 250 | "metadata": {}, 251 | "outputs": [ 252 | { 253 | "name": "stdout", 254 | "output_type": "stream", 255 | "text": [ 256 | "tensor(4.8889e-10, requires_grad=True) tensor(4.8889e-10, requires_grad=True)\n" 257 | ] 258 | } 259 | ], 260 | "source": [ 261 | "print(x, y)" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "## Simple neural network on MNIST" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 52, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "from torchvision import datasets, transforms\n", 278 | "import torch.nn.functional as F" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "### Import the dataset\n", 286 | "\n", 287 | "" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 53, 293 | "metadata": {}, 294 | "outputs": [], 295 | "source": [ 296 | "# Transform each image into tensor and normalized with mean and std\n", 297 | "transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])\n", 298 | "# Define the batch size used each time we go through the dataset\n", 299 | "batch_size = 32\n", 300 | "\n", 301 | "# Set the training loader\n", 302 | "train_loader = torch.utils.data.DataLoader(datasets.MNIST('../data', train=True, download=True, transform=transform), batch_size=batch_size, shuffle=True)\n", 303 | "# Set the testing loader\n", 304 | "test_loader = torch.utils.data.DataLoader(datasets.MNIST('../data', train=False, download=True, transform=transform), batch_size=batch_size, shuffle=True)" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "metadata": {}, 310 | "source": [ 311 | "### Init the weights" 312 | ] 313 | }, 314 | { 315 | "cell_type": "code", 316 | "execution_count": 56, 317 | "metadata": {}, 318 | "outputs": [], 319 | "source": [ 320 | "## Init weights\n", 321 | "# 784 because there is 784 pixels in each image\n", 322 | "# 10 because there is 10 possible outputs : 0,1,2,3,4,5,6,7,8,9\n", 323 | "# Each pixel is linked to 10 outputs where each link is a weight to optimize\\\n", 324 | "# <=> Each class is linked to 784 pixel where each link is a weight to optimize\n", 325 | "weights = torch.randn(784, 10, requires_grad=True)" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": {}, 331 | "source": [ 332 | "### Compute the accuracy on the test set\n", 333 | "\n", 334 | "" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": 83, 340 | "metadata": {}, 341 | "outputs": [ 342 | { 343 | "name": "stdout", 344 | "output_type": "stream", 345 | "text": [ 346 | " Accuracy on test set 0.0816\n" 347 | ] 348 | } 349 | ], 350 | "source": [ 351 | "def test(weights, test_loader):\n", 352 | " test_size = len(test_loader.dataset)\n", 353 | " correct = 0\n", 354 | "\n", 355 | " for batch_idx, (data, target) in enumerate(test_loader):\n", 356 | " #print(batch_idx, data.shape, target.shape)\n", 357 | " data = data.view((-1, 28*28))\n", 358 | " #print(batch_idx, data.shape, target.shape)\n", 359 | "\n", 360 | " outputs = torch.matmul(data, weights)\n", 361 | " softmax = F.softmax(outputs, dim=1)\n", 362 | " pred = softmax.argmax(dim=1, keepdim=True)\n", 363 | " n_correct = pred.eq(target.view_as(pred)).sum().item()\n", 364 | " correct += n_correct\n", 365 | "\n", 366 | " acc = correct / test_size\n", 367 | " print(\" Accuracy on test set\", acc)\n", 368 | " return\n", 369 | "\n", 370 | "test(weights, test_loader)" 371 | ] 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "### Train the model\n", 378 | "\n", 379 | "" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": 98, 385 | "metadata": { 386 | "scrolled": true 387 | }, 388 | "outputs": [ 389 | { 390 | "name": "stdout", 391 | "output_type": "stream", 392 | "text": [ 393 | "Loss shape: 5.5470104217529375 Accuracy on test set 0.6676\n", 394 | "Loss shape: 3.7371554374694824 Accuracy on test set 0.7678\n", 395 | "Loss shape: 3.7003250122070312 Accuracy on test set 0.7969\n", 396 | "Loss shape: 3.63990139961242685 Accuracy on test set 0.825\n", 397 | "Loss shape: 2.156468629837036787 Accuracy on test set 0.8363\n", 398 | "Loss shape: 1.54896616935729985 Accuracy on test set 0.8345\n", 399 | "Loss shape: 2.52677869796752935 Accuracy on test set 0.842\n", 400 | "Loss shape: 2.875357151031494713 Accuracy on test set 0.8573\n", 401 | "Loss shape: 0.84983670711517333 Accuracy on test set 0.8513\n", 402 | "Loss shape: 0.92615586519241333 Accuracy on test set 0.8582\n", 403 | "Loss shape: 1.82365214824676517 Accuracy on test set 0.8635\n", 404 | "Loss shape: 0.69127744436264046 Accuracy on test set 0.8644\n", 405 | "Loss shape: 1.83464241027832034 Accuracy on test set 0.8613\n", 406 | "Loss shape: 0.3489245176315307666 Accuracy on test set 0.8659\n", 407 | "Loss shape: 1.96130001544952487 Accuracy on test set 0.8691\n", 408 | "Loss shape: 0.52960449457168586 Accuracy on test set 0.8714\n", 409 | "Loss shape: 2.4448368549346924447 Accuracy on test set 0.8688\n", 410 | "Loss shape: 0.0516575723886489944 Accuracy on test set 0.8669\n", 411 | "Loss shape: 0.0055376142263412476" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "it = 0\n", 417 | "for batch_idx, (data, targets) in enumerate(train_loader):\n", 418 | " # Be sure to start the loop with zeros grad\n", 419 | " if weights.grad is not None:\n", 420 | " weights.grad.zero_()\n", 421 | " \n", 422 | " data = data.view((-1, 28*28))\n", 423 | " #print(\"batch_idx: {}, data.shape: {}, target.shape: {}\".format(batch_idx, data.shape, targets.shape))\n", 424 | " outputs = torch.matmul(data, weights)\n", 425 | " #print(\"outputs.shape: {}\".format(outputs.shape))\n", 426 | "\n", 427 | " log_softmax = F.log_softmax(outputs, dim=1)\n", 428 | " #print(\"Log softmax: {}\".format(log_softmax.shape))\n", 429 | "\n", 430 | " #print((-log_softmax[0][targets[0]] + -log_softmax[1][targets[1]] ) / 2 )\n", 431 | " #print(-log_softmax[0][targets[0]], targets[0])\n", 432 | " \n", 433 | " loss = F.nll_loss(log_softmax, targets)\n", 434 | " print(\"\\rLoss shape: {}\".format(loss), end=\"\")\n", 435 | " \n", 436 | " # Compute the gradients for each variables\n", 437 | " loss.backward()\n", 438 | " \n", 439 | " with torch.no_grad():\n", 440 | " weights -= 0.1*weights.grad\n", 441 | " \n", 442 | " it += 1\n", 443 | " if it % 100 == 0:\n", 444 | " test(weights, test_loader)\n", 445 | " \n", 446 | " if it > 5000:\n", 447 | " break" 448 | ] 449 | }, 450 | { 451 | "cell_type": "code", 452 | "execution_count": 111, 453 | "metadata": {}, 454 | "outputs": [ 455 | { 456 | "data": { 457 | "image/png": "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\n", 458 | "text/plain": [ 459 | "
" 460 | ] 461 | }, 462 | "metadata": { 463 | "needs_background": "light" 464 | }, 465 | "output_type": "display_data" 466 | } 467 | ], 468 | "source": [ 469 | "import matplotlib.pyplot as plt\n", 470 | "\n", 471 | "batch_idx, (data, target) = next(enumerate(test_loader))\n", 472 | "data = data.view((-1, 28*28))\n", 473 | "\n", 474 | "outputs = torch.matmul(data, weights)\n", 475 | "softmax = F.softmax(outputs, dim=1)\n", 476 | "pred = softmax.argmax(dim=1, keepdim=True)\n", 477 | "\n", 478 | "plt.imshow(data[0].view(28, 28), cmap=\"gray\")\n", 479 | "plt.title(\"Predicted class {}\".format(pred[0]))\n", 480 | "plt.show()" 481 | ] 482 | } 483 | ], 484 | "metadata": { 485 | "kernelspec": { 486 | "display_name": "Python 3", 487 | "language": "python", 488 | "name": "python3" 489 | }, 490 | "language_info": { 491 | "codemirror_mode": { 492 | "name": "ipython", 493 | "version": 3 494 | }, 495 | "file_extension": ".py", 496 | "mimetype": "text/x-python", 497 | "name": "python", 498 | "nbconvert_exporter": "python", 499 | "pygments_lexer": "ipython3", 500 | "version": "3.7.3" 501 | } 502 | }, 503 | "nbformat": 4, 504 | "nbformat_minor": 2 505 | } 506 | -------------------------------------------------------------------------------- /images/intro_pytorch_gradient_descent.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thibo73800/pytorch_nlp/0ce992d674de7e4a133fb033d8ba69ac0b386762/images/intro_pytorch_gradient_descent.PNG -------------------------------------------------------------------------------- /images/intro_pytorch_mnist.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thibo73800/pytorch_nlp/0ce992d674de7e4a133fb033d8ba69ac0b386762/images/intro_pytorch_mnist.PNG -------------------------------------------------------------------------------- /images/intro_pytorch_mnist_operations.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thibo73800/pytorch_nlp/0ce992d674de7e4a133fb033d8ba69ac0b386762/images/intro_pytorch_mnist_operations.PNG -------------------------------------------------------------------------------- /images/intro_pytorch_negativeloglikelihood.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thibo73800/pytorch_nlp/0ce992d674de7e4a133fb033d8ba69ac0b386762/images/intro_pytorch_negativeloglikelihood.PNG -------------------------------------------------------------------------------- /images/pytorhc_vs_tensorflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thibo73800/pytorch_nlp/0ce992d674de7e4a133fb033d8ba69ac0b386762/images/pytorhc_vs_tensorflow.png --------------------------------------------------------------------------------