{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "id": "zuYRBFMVid1-" }, "outputs": [], "source": [ "!pip install torch\n", "!pip install datasets\n", "!pip install torchviz\n", "!pip install scikit-learn\n", "!pip install torcheval\n", "!pip install seaborn\n", "!pip install matplotlib" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Ha9PrHzLAFiB" }, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", "import torch.nn.functional as F\n", "import torch.optim as optim\n", "\n", "import torcheval.metrics as tm\n", "from torchviz import make_dot\n", "\n", "import seaborn as sn\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import numpy as np\n" ] }, { "cell_type": "markdown", "metadata": { "id": "zS0xOw68_23I" }, "source": [ "# Tensores" ] }, { "cell_type": "markdown", "metadata": { "id": "SJof4QZmIOjt" }, "source": [ "### Crear tensores con PyTorch" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "pKlfSEVN9JeD" }, "outputs": [], "source": [ "z = torch.zeros(5, 3)\n", "print(z)\n", "print(z.dtype)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qdSdDxwkAdxu" }, "outputs": [], "source": [ "i = torch.ones((5, 3), dtype=torch.int16)\n", "print(i)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "epBoF-frBBkM" }, "outputs": [], "source": [ "data = [[1,2],[3,4]]\n", "x_data = torch.tensor(data)\n", "print(x_data)\n", "\n", "np_array = np.array(data)\n", "x_np = torch.from_numpy(np_array)\n", "print(x_np)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "oMDEgZboBD8q" }, "outputs": [], "source": [ "x_ones = torch.ones_like(x_data)\n", "print(x_ones)\n", "\n", "x_rand = torch.rand_like(x_data, dtype=torch.float)\n", "print(x_rand)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XgXLHBOcBs0_" }, "outputs": [], "source": [ "print(\"Primera vez\")\n", "torch.manual_seed(1729)\n", "r1 = torch.rand(2, 2)\n", "print(r1)\n", "\n", "r2 = torch.rand(2, 2)\n", "print(r2)\n", "\n", "print(\"\\nSegunda vez\")\n", "torch.manual_seed(1729)\n", "r3 = torch.rand(2, 2)\n", "print(r3)\n", "\n", "r4 = torch.rand(2, 2)\n", "print(r4)" ] }, { "cell_type": "markdown", "metadata": { "id": "KEep2CIPIJpH" }, "source": [ "### Atributos de un tensor" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XUS5SoUeDPsk" }, "outputs": [], "source": [ "print(r1.shape)\n", "print(r1.dtype)\n", "print(r1.device)\n", "\n", "if torch.cuda.is_available():\n", " r1 = r1.to(\"cuda\")\n", "print(r1.device)" ] }, { "cell_type": "markdown", "metadata": { "id": "O-ZMitM0IDyX" }, "source": [ "### Operaciones con tensores" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tJDPO5BUEXEg" }, "outputs": [], "source": [ "ones = torch.ones(2, 3)\n", "print(ones)\n", "\n", "twos = torch.ones(2, 3) * 2\n", "print(twos)\n", "\n", "threes = ones + twos\n", "print(threes)\n", "print(threes.shape)\n", "\n", "# r1 = torch.rand(2, 3)\n", "# r2 = torch.rand(3, 2)\n", "\n", "# r12 = r1 + r2" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "jWhGAeZ-FGHV" }, "outputs": [], "source": [ "# Valores entre -1 y 1\n", "print(\"Vector random:\")\n", "r = (torch.rand(2, 2) - 0.5) * 2\n", "print(r)\n", "\n", "# Valor absoluto\n", "print(\"\\nValor absoluto:\")\n", "print(torch.abs(r))\n", "\n", "# Arcoseno\n", "print(\"\\nArcoseno:\")\n", "print(torch.asin(r))\n", "\n", "# Determinante\n", "print(\"\\nDeterminante:\")\n", "print(torch.det(r))\n", "\n", "# Descomposición por valores singulares\n", "print(\"\\nDescomposición por valores singulares:\")\n", "print(torch.svd(r))\n", "\n", "# Promedio y desviación estándar\n", "print(\"\\nPromedio y desviación estándar:\")\n", "print(torch.std_mean(r))\n", "\n", "# Encontrar el valor máximo\n", "print(\"\\nValor máximo:\")\n", "print(torch.max(r))" ] }, { "cell_type": "markdown", "metadata": { "id": "nhAlDHIlIWkc" }, "source": [ "#### Operadores in-place" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-GfKcVfDIYr3" }, "outputs": [], "source": [ "r1 = torch.ones(2, 3)\n", "r2 = torch.ones(2, 3) * 2\n", "print(r1)\n", "print(r2)\n", "\n", "r1.add_(r2)\n", "print(f\"\\n{r1}\")\n", "\n", "r1.t_()\n", "print(f\"\\n{r1}\")" ] }, { "cell_type": "markdown", "metadata": { "id": "ySHYT4UAMelS" }, "source": [ "# Autograd" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "IQ_vu3bFqHmP" }, "outputs": [], "source": [ "a = torch.tensor([3.], requires_grad=True)\n", "b = torch.tensor([1.], requires_grad=True)\n", "c = torch.tensor([-2.], requires_grad=True)\n", "\n", "L = c*(a + 2*b)\n", "\n", "print(f\"a: {a}, derivada de L respecto de a: {a.grad}\")\n", "print(f\"b: {b}, derivada de L respecto de b: {b.grad}\")\n", "print(f\"c: {c}, derivada de L respecto de c: {c.grad}\")\n", "print(f\"L: {L}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "KlRMUDGQ20VN" }, "outputs": [], "source": [ "L.grad_fn.next_functions[1][0].next_functions" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "QuHtZLa7Pe0Z" }, "outputs": [], "source": [ "make_dot(L, params={'a': a, 'b': b, 'c': c, 'L':L})" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ZS3N6_yh5-yY" }, "outputs": [], "source": [ "L.backward()\n", "\n", "print(f\"\\na: {a}, derivada de L respecto de a: {a.grad}\")\n", "print(f\"b: {b}, derivada de L respecto de b: {b.grad}\")\n", "print(f\"c: {c}, derivada de L respecto de c: {c.grad}\")\n", "print(f\"L: {L}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "IqTDi6qQVbq6" }, "outputs": [], "source": [ "x = torch.ones(5)\n", "y = torch.zeros(3)\n", "w = torch.randn(5, 3, requires_grad=True)\n", "b = torch.randn(3, requires_grad=True)\n", "z = torch.matmul(x, w) + b\n", "\n", "print(f\"w: {w}\")\n", "print(f\"b: {b}\")\n", "\n", "loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)\n", "optimizer = torch.optim.SGD([w, b], lr=0.001)\n", "\n", "loss.backward()\n", "\n", "print(f\"\\nw.grad: {w.grad}\")\n", "print(f\"b.grad: {b.grad}\")\n", "\n", "optimizer.step()\n", "\n", "print(f\"\\nw: {w}\")\n", "print(f\"b: {b}\")\n", "\n", "optimizer.zero_grad()\n", "\n", "print(f\"\\nw.grad: {w.grad}\")\n", "print(f\"b.grad: {b.grad}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "JCW852QOYO7w" }, "outputs": [], "source": [ "make_dot(loss, params={'w': w, 'b': b, 'loss':loss})" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DaXgPI0cVnwK" }, "outputs": [], "source": [ "print(z.requires_grad)\n", "\n", "with torch.no_grad():\n", " z = torch.matmul(x, w) + b\n", "print(z.requires_grad)" ] }, { "cell_type": "markdown", "metadata": { "id": "imf5S9_IKPM1" }, "source": [ "# Ejemplo de FFNN" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TWKWnP8Lp_dz" }, "outputs": [], "source": [ "from datasets import load_dataset\n", "\n", "train_iter = load_dataset(\"stanfordnlp/imdb\", split=\"train\")\n", "test_iter = load_dataset(\"stanfordnlp/imdb\", split=\"test\")\n", "\n", "print(f\"Tamaño de train: {len(train_iter)}\")\n", "print(f\"Tamaño de test: {len(test_iter)}\")\n", "\n", "# Ejemplo negativo\n", "negative_example = next(data[\"text\"] for data in train_iter if data[\"label\"] == 0)\n", "print(f\"\\nEjemplo negativo:\\n{negative_example}\")\n", "\n", "# Ejemplo positivo\n", "positive_example = next(data[\"text\"] for data in train_iter if data[\"label\"] == 1)\n", "print(f\"\\nEjemplo positivo:\\n{positive_example}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "tIOoqw36UA5h" }, "outputs": [], "source": [ "from sklearn.feature_extraction.text import CountVectorizer\n", "from sklearn.decomposition import TruncatedSVD\n", "\n", "X = train_iter[\"text\"]\n", "\n", "vectorizer_bow = CountVectorizer(analyzer='word')\n", "vectorizer_bow = vectorizer_bow.fit(X)\n", "\n", "X_bow = vectorizer_bow.transform(X)\n", "\n", "# SVD dimensionality reduction\n", "vectorizer_svd = TruncatedSVD(n_components=500, n_iter=10, random_state=432)\n", "vectorizer_svd = vectorizer_svd.fit(X_bow)\n", "\n", "def transform_data(iter):\n", " X = iter[\"text\"]\n", " y = iter[\"label\"]\n", "\n", " X_bow = vectorizer_bow.transform(X)\n", " X_svd = vectorizer_svd.transform(X_bow)\n", "\n", " return X_svd, y" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "R88mCuJbWJ-t" }, "outputs": [], "source": [ "from torch.utils.data import Dataset\n", "\n", "class IMDBDataset(Dataset):\n", " def __init__(self, iter):\n", " X, y = transform_data(iter)\n", " self.X = torch.tensor(X, dtype=torch.float32)\n", " self.y = torch.tensor(y, dtype=torch.float32)\n", "\n", " def __len__(self):\n", " return len(self.X)\n", "\n", " def __getitem__(self, idx):\n", " return self.X[idx], self.y[idx]\n", "\n", "train_dataset = IMDBDataset(train_iter)\n", "test_dataset = IMDBDataset(test_iter)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "58i1dsyROmQ9" }, "outputs": [], "source": [ "from torch.utils.data import DataLoader\n", "\n", "train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)\n", "test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=True)\n", "\n", "print(f\"Tamaño de train_dataloader: {len(train_dataloader)}\")\n", "print(f\"Tamaño de primer batch de train_dataloader: {len(next(iter(train_dataloader))[0])}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "3ZlBmkK8YkpR" }, "outputs": [], "source": [ "class Net(nn.Module):\n", "\n", " def __init__(self):\n", " super(Net, self).__init__()\n", " self.fc1 = nn.Linear(500, 200)\n", " self.fc2 = nn.Linear(200, 1)\n", "\n", " def forward(self, x):\n", " x = self.fc1(x)\n", " x = F.relu(x)\n", " x = self.fc2(x)\n", " x = F.sigmoid(x)\n", " return x\n", "\n", "my_net = Net()\n", "print(my_net)\n", "\n", "y = my_net(torch.randn(1, 500))\n", "print(f\"\\n{y}\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "t9VUW8ZrovUn" }, "outputs": [], "source": [ "my_net.fc1.weight.shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "H5CjhZg6ZUyZ" }, "outputs": [], "source": [ "criterion = nn.BCELoss()\n", "optimizer = optim.SGD(my_net.parameters(), lr=0.001, momentum=.9)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "q8Ln6cxlgsDD" }, "outputs": [], "source": [ "for epoch in range(20):\n", "\n", " running_loss = 0.0\n", " for i, data in enumerate(train_dataloader):\n", "\n", " # Obtener inputs y labels, data es una lista de [inputs, labels]\n", " inputs, labels = data\n", "\n", " # Resetear los gradientes de los parámetros\n", " optimizer.zero_grad()\n", "\n", " # forward + backward + optimizar\n", " outputs = my_net(inputs).squeeze(1)\n", " loss = criterion(outputs, labels)\n", " loss.backward()\n", " optimizer.step()\n", "\n", " # Imprimir estadísticas\n", " running_loss += loss.item()\n", " if i % 50 == 49: # Cada 50 mini-batches\n", " print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 50:.3f}')\n", " running_loss = 0.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "xPiybzUMgLiG" }, "outputs": [], "source": [ "precision = tm.BinaryPrecision()\n", "recall = tm.BinaryRecall()\n", "f1 = tm.BinaryF1Score()\n", "accuracy = tm.BinaryAccuracy()\n", "confusion_matrix = tm.BinaryConfusionMatrix()\n", "\n", "with torch.no_grad():\n", " for data in test_dataloader:\n", " inputs, labels = data\n", " outputs = my_net(inputs).squeeze(1)\n", " labels = labels.type(torch.int32)\n", "\n", " precision.update(outputs, labels)\n", " recall.update(outputs, labels)\n", " f1.update(outputs, labels)\n", " accuracy.update(outputs, labels)\n", " confusion_matrix.update(outputs, labels)\n", "\n", "print(f\"Precision: {precision.compute()}\")\n", "print(f\"Recall: {recall.compute()}\")\n", "print(f\"F1: {f1.compute()}\")\n", "print(f\"Accuracy: {accuracy.compute()}\")\n", "\n", "# Confusion matrix\n", "cm = confusion_matrix.compute().cpu().numpy()\n", "\n", "df_cm = pd.DataFrame(cm, index = [i for i in [\"Negativo\", \"Positivo\"]],\n", " columns = [i for i in [\"Negativo\", \"Positivo\"]])\n", "sn.heatmap(df_cm, annot=True, cmap='Blues', fmt='g')\n", "plt.title('Matriz de confusión')\n", "plt.xlabel('Predicción')\n", "plt.ylabel('Valor real')\n", "plt.show()" ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.19" } }, "nbformat": 4, "nbformat_minor": 0 }