{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":11848,"databundleVersionId":862157,"sourceType":"competition"}],"dockerImageVersionId":30762,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-09-07T21:59:17.677016Z","iopub.execute_input":"2024-09-07T21:59:17.677876Z","iopub.status.idle":"2024-09-07T22:00:28.772465Z","shell.execute_reply.started":"2024-09-07T21:59:17.677835Z","shell.execute_reply":"2024-09-07T22:00:28.771506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import transforms, models\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score, precision_recall_fscore_support, roc_curve, confusion_matrix\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:28.509982Z","iopub.execute_input":"2024-09-07T23:38:28.510392Z","iopub.status.idle":"2024-09-07T23:38:28.519084Z","shell.execute_reply.started":"2024-09-07T23:38:28.510352Z","shell.execute_reply":"2024-09-07T23:38:28.517977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Transformaciones para las imágenes de entrenamiento\ntrain_transforms = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomRotation(10),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])\n\n# Transformaciones para las imágenes de prueba (sin aumentación)\ntest_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5], std=[0.5])\n])","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:42.713843Z","iopub.execute_input":"2024-09-07T23:38:42.714555Z","iopub.status.idle":"2024-09-07T23:38:42.720366Z","shell.execute_reply.started":"2024-09-07T23:38:42.714512Z","shell.execute_reply":"2024-09-07T23:38:42.719229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CancerDataset(Dataset):\n    def __init__(self, labels_df, root_dir, transform=None):\n        self.labels = labels_df\n        self.root_dir = root_dir\n        self.transform = transform\n    \n    def __len__(self):\n        return len(self.labels)\n    \n    def __getitem__(self, idx):\n        img_id = self.labels.iloc[idx, 0]\n        img_path = os.path.join(self.root_dir, img_id + '.tif')\n        image = Image.open(img_path)\n        label = int(self.labels.iloc[idx, 1])\n        \n        if self.transform:\n            image = self.transform(image)\n        \n        return image, label","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:45.035648Z","iopub.execute_input":"2024-09-07T23:38:45.036079Z","iopub.status.idle":"2024-09-07T23:38:45.043416Z","shell.execute_reply.started":"2024-09-07T23:38:45.036036Z","shell.execute_reply":"2024-09-07T23:38:45.042413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Cargar los datos de entrenamiento\ntrain_labels_df = pd.read_csv('/kaggle/input/histopathologic-cancer-detection/train_labels.csv')\n\n# Dividir el DataFrame en conjuntos de entrenamiento y validación\ntrain_df, val_df = train_test_split(train_labels_df, test_size=0.2, stratify=train_labels_df['label'])\n\n# Definir directorios\ntrain_dir = '/kaggle/input/histopathologic-cancer-detection/train'\ntest_dir = '/kaggle/input/histopathologic-cancer-detection/test'\n\n# Crear datasets para entrenamiento y validación\ntrain_dataset = CancerDataset(labels_df=train_df, root_dir=train_dir, transform=train_transforms)\nval_dataset = CancerDataset(labels_df=val_df, root_dir=train_dir, transform=test_transforms)\n\n# Crear DataLoaders para entrenamiento y validación\ntrain_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:47.562480Z","iopub.execute_input":"2024-09-07T23:38:47.562856Z","iopub.status.idle":"2024-09-07T23:38:47.881693Z","shell.execute_reply.started":"2024-09-07T23:38:47.562818Z","shell.execute_reply":"2024-09-07T23:38:47.880682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CancerClassifier(nn.Module):\n    def __init__(self):\n        super(CancerClassifier, self).__init__()\n        self.model = models.resnet18(pretrained=True)\n        num_ftrs = self.model.fc.in_features\n        self.model.fc = nn.Linear(num_ftrs, 1)  # Capa de salida para clasificación binaria\n\n    def forward(self, x):\n        x = self.model(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:50.503447Z","iopub.execute_input":"2024-09-07T23:38:50.503945Z","iopub.status.idle":"2024-09-07T23:38:50.511541Z","shell.execute_reply.started":"2024-09-07T23:38:50.503896Z","shell.execute_reply":"2024-09-07T23:38:50.510384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Definir el modelo y moverlo a GPU si está disponible\nmodel = CancerClassifier()\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n\n# Definir optimizador y función de pérdida\noptimizer = optim.Adam(model.parameters(), lr=0.001)\ncriterion = nn.BCEWithLogitsLoss()\n\n# Loop de entrenamiento\nnum_epochs = 5\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    print(f\"Epoch {epoch+1} / {num_epochs}\")  # Verificar el progreso\n    for i, (images, labels) in enumerate(train_loader):\n        if i % 100 == 0:  # Imprimir cada 100 batches\n            print(f\"Processing batch {i} / {len(train_loader)}\")\n        \n        images, labels = images.to(device), labels.to(device).float()\n        \n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs.squeeze(), labels)\n        loss.backward()\n        optimizer.step()\n        \n        running_loss += loss.item()\n    \n    print(f\"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(train_loader):.4f}\")","metadata":{"execution":{"iopub.status.busy":"2024-09-07T23:38:52.983900Z","iopub.execute_input":"2024-09-07T23:38:52.984288Z","iopub.status.idle":"2024-09-08T00:27:17.666572Z","shell.execute_reply.started":"2024-09-07T23:38:52.984253Z","shell.execute_reply":"2024-09-08T00:27:17.665513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluar el modelo en el conjunto de validación\nmodel.eval()  # Modo de evaluación\nval_loss = 0.0\nall_labels = []\nall_preds = []\n\nwith torch.no_grad():\n    for images, labels in val_loader:\n        images, labels = images.to(device), labels.to(device).float()\n        outputs = model(images)\n        loss = criterion(outputs.squeeze(), labels)\n        \n        val_loss += loss.item()\n        \n        preds = torch.sigmoid(outputs.squeeze())  # Convertir a probabilidades\n        all_labels.extend(labels.cpu().numpy())\n        all_preds.extend(preds.cpu().numpy())\n\n# Calcular la pérdida media en el conjunto de validación\nval_loss /= len(val_loader)\nprint(f'Validation Loss: {val_loss:.4f}')\n\n# Calcular el AUC-ROC para el conjunto de validación\nauc = roc_auc_score(all_labels, all_preds)\nprint(f'Validation AUC-ROC: {auc:.4f}')\n\n# Calcular precisión, recall y F1 Score\nprecision, recall, f1, _ = precision_recall_fscore_support(all_labels, (np.array(all_preds) > 0.5).astype(int))\nprint(f'Precision: {precision[1]:.4f}')\nprint(f'Recall: {recall[1]:.4f}')\nprint(f'F1 Score: {f1[1]:.4f}')","metadata":{"execution":{"iopub.status.busy":"2024-09-08T00:29:51.949360Z","iopub.execute_input":"2024-09-08T00:29:51.949662Z","iopub.status.idle":"2024-09-08T00:31:26.171244Z","shell.execute_reply.started":"2024-09-08T00:29:51.949629Z","shell.execute_reply":"2024-09-08T00:31:26.170138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Función para graficar la curva ROC\ndef plot_roc_curve(y_true, y_scores):\n    fpr, tpr, _ = roc_curve(y_true, y_scores)\n    plt.figure(figsize=(10, 7))\n    plt.plot(fpr, tpr, color='blue', label='ROC Curve (area = %0.2f)' % auc)\n    plt.plot([0, 1], [0, 1], color='grey', linestyle='--')\n    plt.xlabel('False Positive Rate')\n    plt.ylabel('True Positive Rate')\n    plt.title('Receiver Operating Characteristic')\n    plt.legend(loc='lower right')\n    plt.show()\n\n# Función para graficar la matriz de confusión\ndef plot_confusion_matrix(y_true, y_pred):\n    cm = confusion_matrix(y_true, y_pred)\n    plt.figure(figsize=(10, 7))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['No Tumor', 'Tumor'], yticklabels=['No Tumor', 'Tumor'])\n    plt.xlabel('Predicted')\n    plt.ylabel('True')\n    plt.title('Confusion Matrix')\n    plt.show()\n\n# Función para graficar la distribución de predicciones\ndef plot_prediction_distribution(y_true, y_scores):\n    plt.figure(figsize=(10, 7))\n    plt.hist(y_scores, bins=50, alpha=0.7, label='Predicted Probabilities')\n    plt.axvline(x=0.5, color='red', linestyle='--', label='Threshold = 0.5')\n    plt.xlabel('Probability')\n    plt.ylabel('Frequency')\n    plt.title('Distribution of Predicted Probabilities')\n    plt.legend()\n    plt.show()\n\n# Graficar resultados\nplot_roc_curve(all_labels, all_preds)\nplot_confusion_matrix(all_labels, (np.array(all_preds) > 0.5).astype(int))\nplot_prediction_distribution(all_labels, all_preds)","metadata":{"execution":{"iopub.status.busy":"2024-09-08T00:40:17.245728Z","iopub.execute_input":"2024-09-08T00:40:17.246140Z","iopub.status.idle":"2024-09-08T00:40:18.603727Z","shell.execute_reply.started":"2024-09-08T00:40:17.246100Z","shell.execute_reply":"2024-09-08T00:40:18.602792Z"},"trusted":true},"execution_count":null,"outputs":[]}]}