diff --git a/My_Experiments/PyTorch_Course/01_pytorch_workflow.ipynb b/My_Experiments/PyTorch_Course/01_pytorch_workflow.ipynb index caa8963..9952745 100644 --- a/My_Experiments/PyTorch_Course/01_pytorch_workflow.ipynb +++ b/My_Experiments/PyTorch_Course/01_pytorch_workflow.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 266, + "execution_count": 41, "id": "87dce210", "metadata": {}, "outputs": [ @@ -25,7 +25,7 @@ " 6: 'putting it all together'}" ] }, - "execution_count": 266, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -42,7 +42,7 @@ }, { "cell_type": "code", - "execution_count": 267, + "execution_count": 42, "id": "e90c8379", "metadata": {}, "outputs": [ @@ -52,7 +52,7 @@ "'2.12.1+cu130'" ] }, - "execution_count": 267, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -75,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 268, + "execution_count": 43, "id": "a5b9b36a", "metadata": {}, "outputs": [ @@ -104,7 +104,7 @@ " [0.4260]]))" ] }, - "execution_count": 268, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -126,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 269, + "execution_count": 44, "id": "41f90d81", "metadata": {}, "outputs": [ @@ -136,7 +136,7 @@ "(50, 50)" ] }, - "execution_count": 269, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -155,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 270, + "execution_count": 45, "id": "b2c8b4d9", "metadata": {}, "outputs": [ @@ -165,7 +165,7 @@ "(40, 40, 10, 10)" ] }, - "execution_count": 270, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -181,7 +181,7 @@ }, { "cell_type": "code", - "execution_count": 271, + "execution_count": 46, "id": "8cd57e5c", "metadata": {}, "outputs": [ @@ -227,7 +227,7 @@ }, { "cell_type": "code", - "execution_count": 272, + "execution_count": 47, "id": "aa9f92c3", "metadata": {}, "outputs": [], @@ -266,7 +266,7 @@ }, { "cell_type": "code", - "execution_count": 273, + "execution_count": 48, "id": "c97c753c", "metadata": {}, "outputs": [ @@ -279,7 +279,7 @@ " tensor([0.1288], requires_grad=True)]" ] }, - "execution_count": 273, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -297,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": 274, + "execution_count": 49, "id": "f38d41c0", "metadata": {}, "outputs": [ @@ -307,7 +307,7 @@ "OrderedDict([('weights', tensor([0.3367])), ('bias', tensor([0.1288]))])" ] }, - "execution_count": 274, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -327,7 +327,7 @@ }, { "cell_type": "code", - "execution_count": 275, + "execution_count": 50, "id": "5263fef5", "metadata": {}, "outputs": [ @@ -356,7 +356,7 @@ " [0.9860]]))" ] }, - "execution_count": 275, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -367,7 +367,7 @@ }, { "cell_type": "code", - "execution_count": 276, + "execution_count": 51, "id": "01a46c08", "metadata": {}, "outputs": [ @@ -386,7 +386,7 @@ " [0.4588]])" ] }, - "execution_count": 276, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -400,7 +400,7 @@ }, { "cell_type": "code", - "execution_count": 277, + "execution_count": 52, "id": "e27f6f66", "metadata": {}, "outputs": [ @@ -429,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": 278, + "execution_count": 53, "id": "cfe9b6be", "metadata": {}, "outputs": [ @@ -451,7 +451,7 @@ " ))" ] }, - "execution_count": 278, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -486,7 +486,7 @@ }, { "cell_type": "code", - "execution_count": 279, + "execution_count": 54, "id": "c678f976", "metadata": {}, "outputs": [ @@ -642,7 +642,7 @@ }, { "cell_type": "code", - "execution_count": 280, + "execution_count": 55, "id": "90cf11b7", "metadata": {}, "outputs": [ @@ -801,7 +801,7 @@ " 0.005023092031478882])" ] }, - "execution_count": 280, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -812,17 +812,17 @@ }, { "cell_type": "code", - "execution_count": 281, + "execution_count": 56, "id": "2d17ee65", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 281, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" }, @@ -848,7 +848,7 @@ }, { "cell_type": "code", - "execution_count": 282, + "execution_count": 57, "id": "6aa42ea1", "metadata": {}, "outputs": [], @@ -859,7 +859,7 @@ }, { "cell_type": "code", - "execution_count": 283, + "execution_count": 58, "id": "04ce6868", "metadata": {}, "outputs": [ @@ -869,7 +869,7 @@ "OrderedDict([('weights', tensor([0.6990])), ('bias', tensor([0.3093]))])" ] }, - "execution_count": 283, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -881,7 +881,7 @@ }, { "cell_type": "code", - "execution_count": 284, + "execution_count": 59, "id": "f1a4db10", "metadata": {}, "outputs": [ @@ -891,7 +891,7 @@ "(0.7, 0.3)" ] }, - "execution_count": 284, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -902,7 +902,7 @@ }, { "cell_type": "code", - "execution_count": 285, + "execution_count": 60, "id": "94cdacb6", "metadata": {}, "outputs": [ @@ -921,10 +921,179 @@ "plot_predictions(predictions=y_preds_new)" ] }, + { + "cell_type": "markdown", + "id": "70ce0795", + "metadata": {}, + "source": [ + "## Saving a model in PyTorch" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "c4756ad1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Saving model to: models/01_pytorch_workflow_model_0.pth\n" + ] + } + ], + "source": [ + "# Saving our PyTorch model\n", + "from pathlib import Path\n", + "\n", + "# 1. Create models directory\n", + "MODEL_PATH = Path(\"models\")\n", + "MODEL_PATH.mkdir(parents=True, exist_ok=True)\n", + "# 2. Create a model save path\n", + "MODEL_NAME = \"01_pytorch_workflow_model_0.pth\"\n", + "MODEL_SAVE_PATH = MODEL_PATH / MODEL_NAME\n", + "MODEL_SAVE_PATH\n", + "# 3. Save the model state_dict\n", + "print(f\"Saving model to: {MODEL_SAVE_PATH}\")\n", + "torch.save(obj=model_0.state_dict(), f=MODEL_SAVE_PATH)" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "31c5e50d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "total 4\n", + "-rw-rw-r-- 1 emil emil 2117 Jul 5 03:40 01_pytorch_workflow_model_0.pth\n" + ] + } + ], + "source": [ + "!ls -l models" + ] + }, + { + "cell_type": "markdown", + "id": "18a405a2", + "metadata": {}, + "source": [ + "## Loading a PyTorch model" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "ef3cf06a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 63, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# To load in a saved state_dict we have to instantiane a new instance of our model class\n", + "\n", + "loaded_model_0 = LinearRegressionModel()\n", + "\n", + "# Load the saved state_dict of model_0\n", + "loaded_model_0.load_state_dict(torch.load(f=MODEL_SAVE_PATH))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "82b3e972", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[0.8685],\n", + " [0.8825],\n", + " [0.8965],\n", + " [0.9105],\n", + " [0.9245],\n", + " [0.9384],\n", + " [0.9524],\n", + " [0.9664],\n", + " [0.9804],\n", + " [0.9944]])" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Make some preditions with our loaded model\n", + "loaded_model_0.eval()\n", + "with torch.inference_mode():\n", + " loaded_model_preds = loaded_model_0(X_test)\n", + "\n", + "loaded_model_preds" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "fb05340b", + "metadata": {}, + "outputs": [], + "source": [ + "model_0.eval()\n", + "with torch.inference_mode():\n", + " y_preds = model_0(X_test)" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "41a4ed50", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True],\n", + " [True]])" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Compare loaded model preds with the original model preds\n", + "y_preds == loaded_model_preds" + ] + }, { "cell_type": "code", "execution_count": null, - "id": "70ce0795", + "id": "da9c5c67", "metadata": {}, "outputs": [], "source": [] @@ -932,7 +1101,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv (3.11.15.final.0)", + "display_name": ".venv (3.11.15)", "language": "python", "name": "python3" }, diff --git a/My_Experiments/PyTorch_Course/models/01_pytorch_workflow_model_0.pth b/My_Experiments/PyTorch_Course/models/01_pytorch_workflow_model_0.pth new file mode 100644 index 0000000..f3c013f Binary files /dev/null and b/My_Experiments/PyTorch_Course/models/01_pytorch_workflow_model_0.pth differ diff --git a/My_Experiments/pytorch3.ipynb b/My_Experiments/pytorch3.ipynb index c465d0a..d8237c2 100644 --- a/My_Experiments/pytorch3.ipynb +++ b/My_Experiments/pytorch3.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 58, "id": "3163fb75", "metadata": {}, "outputs": [], @@ -23,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 59, "id": "64a02514", "metadata": {}, "outputs": [], @@ -34,7 +34,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 60, "id": "35200e59", "metadata": {}, "outputs": [ @@ -42,32 +42,32 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0: Loss = 10481.2871\n", - "Epoch 400: Loss = 207.9038\n", - "Epoch 800: Loss = 122.0165\n", - "Epoch 1200: Loss = 71.6102\n", - "Epoch 1600: Loss = 42.0273\n", - "Epoch 2000: Loss = 24.6654\n", - "Epoch 2400: Loss = 14.4759\n", - "Epoch 2800: Loss = 8.4958\n", - "Epoch 3200: Loss = 4.9861\n", - "Epoch 3600: Loss = 2.9263\n", - "Epoch 4000: Loss = 1.7174\n", - "Epoch 4400: Loss = 1.0079\n", - "Epoch 4800: Loss = 0.5916\n", - "Epoch 5200: Loss = 0.3472\n", - "Epoch 5600: Loss = 0.2038\n", - "Epoch 6000: Loss = 0.1196\n", - "Epoch 6400: Loss = 0.0702\n", - "Epoch 6800: Loss = 0.0412\n", - "Epoch 7200: Loss = 0.0242\n", - "Epoch 7600: Loss = 0.0142\n", - "Epoch 8000: Loss = 0.0083\n", - "Epoch 8400: Loss = 0.0049\n", - "Epoch 8800: Loss = 0.0029\n", - "Epoch 9200: Loss = 0.0017\n", - "Epoch 9600: Loss = 0.0010\n", - "Epoch 10000: Loss = 0.0006\n", + "Epoch 0: Loss = 2051.0815\n", + "Epoch 400: Loss = 181.1680\n", + "Epoch 800: Loss = 106.3257\n", + "Epoch 1200: Loss = 62.4014\n", + "Epoch 1600: Loss = 36.6228\n", + "Epoch 2000: Loss = 21.4935\n", + "Epoch 2400: Loss = 12.6143\n", + "Epoch 2800: Loss = 7.4032\n", + "Epoch 3200: Loss = 4.3449\n", + "Epoch 3600: Loss = 2.5500\n", + "Epoch 4000: Loss = 1.4965\n", + "Epoch 4400: Loss = 0.8783\n", + "Epoch 4800: Loss = 0.5155\n", + "Epoch 5200: Loss = 0.3025\n", + "Epoch 5600: Loss = 0.1775\n", + "Epoch 6000: Loss = 0.1042\n", + "Epoch 6400: Loss = 0.0612\n", + "Epoch 6800: Loss = 0.0359\n", + "Epoch 7200: Loss = 0.0211\n", + "Epoch 7600: Loss = 0.0124\n", + "Epoch 8000: Loss = 0.0073\n", + "Epoch 8400: Loss = 0.0043\n", + "Epoch 8800: Loss = 0.0025\n", + "Epoch 9200: Loss = 0.0015\n", + "Epoch 9600: Loss = 0.0009\n", + "Epoch 10000: Loss = 0.0005\n", "Epoch 10400: Loss = 0.0003\n", "Epoch 10800: Loss = 0.0002\n", "Epoch 11200: Loss = 0.0001\n", @@ -117,7 +117,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 61, "id": "be1eb1bd", "metadata": {}, "outputs": [ @@ -153,7 +153,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 62, "id": "fa3c1e81", "metadata": {}, "outputs": [], @@ -168,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 63, "id": "8860a027", "metadata": {}, "outputs": [], @@ -178,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 64, "id": "b1213a8a", "metadata": {}, "outputs": [], @@ -189,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 65, "id": "27d203c4", "metadata": {}, "outputs": [ @@ -197,11 +197,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0: loss = 5640.71875\n", - "Epoch 400: loss = 197.63983154296875\n", - "Epoch 800: loss = 115.99267578125\n", - "Epoch 1200: loss = 68.0748291015625\n", - "Epoch 1600: loss = 39.95244598388672\n" + "Epoch 0: loss = 5002.43408203125\n", + "Epoch 400: loss = 189.92440795898438\n", + "Epoch 800: loss = 111.46468353271484\n", + "Epoch 1200: loss = 65.41755676269531\n", + "Epoch 1600: loss = 38.39296340942383\n" ] } ], @@ -223,7 +223,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 66, "id": "024b4276", "metadata": {}, "outputs": [ @@ -233,9 +233,9 @@ "text": [ "\n", "--- Результаты обучения ---\n", - "Предсказание для 100°C: 231.59°F\n", - "Итоговый вес W: 2.0797\n", - "Итоговое смещение B: 23.6129\n" + "Предсказание для 100°C: 231.20°F\n", + "Итоговый вес W: 2.0742\n", + "Итоговое смещение B: 23.7783\n" ] } ], @@ -253,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 67, "id": "df8942cd", "metadata": {}, "outputs": [ @@ -268,11 +268,11 @@ ")\n", "\n", "--- Starting Training Simulation ---\n", - "Epoch [1/5], Loss: 2.3642\n", - "Epoch [2/5], Loss: 2.0382\n", - "Epoch [3/5], Loss: 1.7581\n", - "Epoch [4/5], Loss: 1.5167\n", - "Epoch [5/5], Loss: 1.3047\n", + "Epoch [1/5], Loss: 2.3632\n", + "Epoch [2/5], Loss: 2.0220\n", + "Epoch [3/5], Loss: 1.7251\n", + "Epoch [4/5], Loss: 1.4678\n", + "Epoch [5/5], Loss: 1.2423\n", "\n", "MLP Example successfully defined and simulated training steps.\n" ] @@ -344,7 +344,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 68, "id": "98166324", "metadata": {}, "outputs": [], @@ -356,17 +356,56 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 69, "id": "ef1351a0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 69, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "X_test = torch.tensor(" + "w = 0.7\n", + "b = 0.3\n", + "\n", + "X = torch.arange(10, 100, 5).unsqueeze(dim=1)\n", + "y = X * w + b\n", + "\n", + "plt.plot(X, y)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 70, + "id": "e452da62", + "metadata": {}, + "outputs": [], + "source": [ + "train_split = int(0.8 * len(X))\n", + "X_train, y_train = X[:train_split], y[:train_split]\n", + "X_test, y_test = X[train_split:], y[train_split:]" + ] + }, + { + "cell_type": "code", + "execution_count": 71, "id": "b9f7783b", "metadata": {}, "outputs": [], @@ -376,29 +415,71 @@ "class Model(nn.Module):\n", " def __init__(self):\n", " super().__init__()\n", - " " + " self.w = nn.Parameter(torch.randn(1))\n", + " self.b = nn.Parameter(torch.randn(1))\n", + " def forward(self, x):\n", + " return x * self.w + self.b" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 78, "id": "90874c3d", "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b808533", - "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "ename": "RuntimeError", + "evalue": "Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mRuntimeError\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[78]\u001b[39m\u001b[32m, line 17\u001b[39m\n\u001b[32m 13\u001b[39m optimizer.step()\n\u001b[32m 14\u001b[39m epochs.append(epoch)\n\u001b[32m 15\u001b[39m losses.append(loss.item())\n\u001b[32m 16\u001b[39m plt.plot(X, y)\n\u001b[32m---> \u001b[39m\u001b[32m17\u001b[39m plt.plot(X_train, y_pred)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/pyplot.py:4043\u001b[39m, in \u001b[36mplot\u001b[39m\u001b[34m(scalex, scaley, data, *args, **kwargs)\u001b[39m\n\u001b[32m 4035\u001b[39m \u001b[38;5;129m@_copy_docstring_and_deprecators\u001b[39m(Axes.plot)\n\u001b[32m 4036\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mplot\u001b[39m(\n\u001b[32m 4037\u001b[39m *args: \u001b[38;5;28mfloat\u001b[39m | ArrayLike | \u001b[38;5;28mstr\u001b[39m,\n\u001b[32m (...)\u001b[39m\u001b[32m 4041\u001b[39m **kwargs,\n\u001b[32m 4042\u001b[39m ) -> \u001b[38;5;28mlist\u001b[39m[Line2D]:\n\u001b[32m-> \u001b[39m\u001b[32m4043\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mgca\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mplot\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 4044\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43margs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 4045\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mscalex\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mscalex\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 4046\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mscaley\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mscaley\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 4047\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m{\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m\"\u001b[39;49m\u001b[30;43m:\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m}\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mif\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43mdata\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mis\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mnot\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43;01mNone\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43;01melse\u001b[39;49;00m\u001b[30;43m \u001b[39;49m\u001b[30;43m{\u001b[39;49m\u001b[30;43m}\u001b[39;49m\u001b[30;43m)\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 4048\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 4049\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/axes/_axes.py:1792\u001b[39m, in \u001b[36mAxes.plot\u001b[39m\u001b[34m(self, scalex, scaley, data, *args, **kwargs)\u001b[39m\n\u001b[32m 1549\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 1550\u001b[39m \u001b[33;03mPlot y versus x as lines and/or markers.\u001b[39;00m\n\u001b[32m 1551\u001b[39m \n\u001b[32m (...)\u001b[39m\u001b[32m 1789\u001b[39m \u001b[33;03m(``'green'``) or hex strings (``'#008000'``).\u001b[39;00m\n\u001b[32m 1790\u001b[39m \u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 1791\u001b[39m kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)\n\u001b[32m-> \u001b[39m\u001b[32m1792\u001b[39m lines = [*\u001b[38;5;28mself\u001b[39m._get_lines(\u001b[38;5;28mself\u001b[39m, *args, data=data, **kwargs)]\n\u001b[32m 1793\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m line \u001b[38;5;129;01min\u001b[39;00m lines:\n\u001b[32m 1794\u001b[39m \u001b[38;5;28mself\u001b[39m.add_line(line)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/axes/_base.py:331\u001b[39m, in \u001b[36m_process_plot_var_args.__call__\u001b[39m\u001b[34m(self, axes, data, return_kwargs, *args, **kwargs)\u001b[39m\n\u001b[32m 329\u001b[39m this += args[\u001b[32m0\u001b[39m],\n\u001b[32m 330\u001b[39m args = args[\u001b[32m1\u001b[39m:]\n\u001b[32m--> \u001b[39m\u001b[32m331\u001b[39m \u001b[38;5;28;01myield from\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_plot_args\u001b[39;49m\u001b[30;43m(\u001b[39;49m\n\u001b[32m 332\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43maxes\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mthis\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mambiguous_fmt_datakey\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mambiguous_fmt_datakey\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 333\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mreturn_kwargs\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mreturn_kwargs\u001b[39;49m\n\u001b[32m 334\u001b[39m \u001b[30;43m\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/axes/_base.py:499\u001b[39m, in \u001b[36m_process_plot_var_args._plot_args\u001b[39m\u001b[34m(self, axes, tup, kwargs, return_kwargs, ambiguous_fmt_datakey)\u001b[39m\n\u001b[32m 497\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(xy) == \u001b[32m2\u001b[39m:\n\u001b[32m 498\u001b[39m x = _check_1d(xy[\u001b[32m0\u001b[39m])\n\u001b[32m--> \u001b[39m\u001b[32m499\u001b[39m y = \u001b[30;43m_check_1d\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mxy\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43m1\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 500\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 501\u001b[39m x, y = index_of(xy[-\u001b[32m1\u001b[39m])\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/cbook.py:1413\u001b[39m, in \u001b[36m_check_1d\u001b[39m\u001b[34m(x)\u001b[39m\n\u001b[32m 1411\u001b[39m \u001b[38;5;250m\u001b[39m\u001b[33;03m\"\"\"Convert scalars to 1D arrays; pass-through arrays as is.\"\"\"\u001b[39;00m\n\u001b[32m 1412\u001b[39m \u001b[38;5;66;03m# Unpack in case of e.g. Pandas or xarray object\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m1413\u001b[39m x = \u001b[30;43m_unpack_to_numpy\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mx\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1414\u001b[39m \u001b[38;5;66;03m# plot requires `shape` and `ndim`. If passed an\u001b[39;00m\n\u001b[32m 1415\u001b[39m \u001b[38;5;66;03m# object that doesn't provide them, then force to numpy array.\u001b[39;00m\n\u001b[32m 1416\u001b[39m \u001b[38;5;66;03m# Note this will strip unit information.\u001b[39;00m\n\u001b[32m 1417\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (\u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(x, \u001b[33m'\u001b[39m\u001b[33mshape\u001b[39m\u001b[33m'\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m\n\u001b[32m 1418\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(x, \u001b[33m'\u001b[39m\u001b[33mndim\u001b[39m\u001b[33m'\u001b[39m) \u001b[38;5;129;01mor\u001b[39;00m\n\u001b[32m 1419\u001b[39m \u001b[38;5;28mlen\u001b[39m(x.shape) < \u001b[32m1\u001b[39m):\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/matplotlib/cbook.py:2517\u001b[39m, in \u001b[36m_unpack_to_numpy\u001b[39m\u001b[34m(x)\u001b[39m\n\u001b[32m 2508\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m xtmp\n\u001b[32m 2509\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m _is_torch_array(x) \\\n\u001b[32m 2510\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m _is_jax_array(x) \\\n\u001b[32m 2511\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m _is_tensorflow_array(x) \\\n\u001b[32m (...)\u001b[39m\u001b[32m 2515\u001b[39m \u001b[38;5;66;03m# https://numpy.org/devdocs/user/basics.interoperability.html#using-arbitrary-objects-in-numpy\u001b[39;00m\n\u001b[32m 2516\u001b[39m \u001b[38;5;66;03m# therefore, let arrays do better if they can\u001b[39;00m\n\u001b[32m-> \u001b[39m\u001b[32m2517\u001b[39m xtmp = np.asarray(x)\n\u001b[32m 2519\u001b[39m \u001b[38;5;66;03m# In case np.asarray method does not return a numpy array in future\u001b[39;00m\n\u001b[32m 2520\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(xtmp, np.ndarray):\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/Desktop/Karpathy_ZtH_Learning/.venv/lib/python3.11/site-packages/torch/_tensor.py:1253\u001b[39m, in \u001b[36mTensor.__array__\u001b[39m\u001b[34m(self, dtype)\u001b[39m\n\u001b[32m 1251\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m handle_torch_function(Tensor.__array__, (\u001b[38;5;28mself\u001b[39m,), \u001b[38;5;28mself\u001b[39m, dtype=dtype)\n\u001b[32m 1252\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m dtype \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[32m-> \u001b[39m\u001b[32m1253\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43mself\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43mnumpy\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 1254\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 1255\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m.numpy().astype(dtype, copy=\u001b[38;5;28;01mFalse\u001b[39;00m)\n", + "\u001b[31mRuntimeError\u001b[39m: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead." + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "model = Model()\n", + "loss_fn = nn.L1Loss()\n", + "optimizer = torch.optim.SGD(model.parameters(), lr=0.0001)\n", + "epochs_num = 100\n", + "epochs = []\n", + "losses = []\n", + "for epoch in range(epochs_num):\n", + " model.train()\n", + " y_pred = model(X_train)\n", + " loss = loss_fn(y_pred, y_train)\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + " epochs.append(epoch)\n", + " losses.append(loss.item())\n", + "plt.plot(X, y)\n", + "plt.plot(X_train, y_pred)" + ] } ], "metadata": { "kernelspec": { - "display_name": ".venv (3.11.15.final.0)", + "display_name": ".venv (3.11.15)", "language": "python", "name": "python3" },