{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":14774,"databundleVersionId":875431,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":6819899,"sourceType":"datasetVersion","datasetId":3922540},{"sourceId":7320027,"sourceType":"datasetVersion","datasetId":4247945},{"sourceId":7755213,"sourceType":"datasetVersion","datasetId":4534686},{"sourceId":8259021,"sourceType":"datasetVersion","datasetId":4901654},{"sourceId":9912034,"sourceType":"datasetVersion","datasetId":6090444},{"sourceId":12423607,"sourceType":"datasetVersion","datasetId":7836008},{"sourceId":12434794,"sourceType":"datasetVersion","datasetId":7843649},{"sourceId":12434906,"sourceType":"datasetVersion","datasetId":7843701},{"sourceId":12470620,"sourceType":"datasetVersion","datasetId":7867577},{"sourceId":12470628,"sourceType":"datasetVersion","datasetId":7867580},{"sourceId":12589195,"sourceType":"datasetVersion","datasetId":7951120},{"sourceId":12589290,"sourceType":"datasetVersion","datasetId":7951186},{"sourceId":12783315,"sourceType":"datasetVersion","datasetId":8081932},{"sourceId":12783332,"sourceType":"datasetVersion","datasetId":8081946},{"sourceId":12784431,"sourceType":"datasetVersion","datasetId":8082595}],"dockerImageVersionId":30747,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install transformers==4.28.0\n!pip install openpyxl\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:09.953636Z","iopub.execute_input":"2025-08-17T03:11:09.954075Z","iopub.status.idle":"2025-08-17T03:11:38.041901Z","shell.execute_reply.started":"2025-08-17T03:11:09.95403Z","shell.execute_reply":"2025-08-17T03:11:38.040905Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport torch\nimport matplotlib.pyplot as plt\nimport torchvision.transforms.functional as F\nfrom datasets import load_dataset, DatasetDict, load_metric\nfrom transformers import BeitImageProcessor, BeitForImageClassification, TrainingArguments, Trainer\nfrom torchvision.transforms import Compose, Normalize, RandomHorizontalFlip, RandomVerticalFlip, RandomRotation, Resize, ToTensor\nfrom sklearn.preprocessing import MultiLabelBinarizer\nfrom sklearn.model_selection import train_test_split\nimport openpyxl\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:38.043667Z","iopub.execute_input":"2025-08-17T03:11:38.043946Z","iopub.status.idle":"2025-08-17T03:11:54.754827Z","shell.execute_reply.started":"2025-08-17T03:11:38.043925Z","shell.execute_reply":"2025-08-17T03:11:54.754056Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\n\n# --- Ajusta tus rutas ---\ntrain_dir = \"/kaggle/input/dataset-edema-eyepacs-labels/eyepacs/split/train\"   # carpeta con imágenes de train\ntest_dir  = \"/kaggle/input/dataset-edema-eyepacs-labels/eyepacs/split/test\"    # carpeta con imágenes de test\n\ntrain_csv = \"/kaggle/input/dataset-edema-eyepacs-labels/eyepacs/train_split_80.csv\"\ntest_csv  = \"/kaggle/input/dataset-edema-eyepacs-labels/eyepacs/test_split_20.csv\"\n\n# Columnas multilabel\nlabel_columns = ['normal', 'diabetic_retinopathy', 'edema_1', 'edema_2']\n\ndef load_split(img_dir, csv_path, label_cols):\n    df = pd.read_csv(csv_path)\n    # Conservar columnas necesarias\n    df = df[['file'] + label_cols].copy()\n    df[label_cols] = df[label_cols].fillna(0).astype(float)\n\n    # Archivos realmente presentes en la carpeta\n    present = set(os.listdir(img_dir))\n\n    # Coincidencias entre CSV y carpeta\n    in_both = df['file'].isin(present)\n    missing_imgs = df.loc[~in_both, 'file'].tolist()         # en CSV pero no en carpeta\n    extra_imgs = sorted(list(present - set(df['file'])))     # en carpeta pero no en CSV\n\n    # Filtrar solo existentes\n    df = df[in_both].reset_index(drop=True)\n\n    files = np.array([os.path.join(img_dir, f) for f in df['file']])\n    labels = df[label_cols].values.astype(np.float32)\n\n    # Reporte rápido\n    print(f\"[{os.path.basename(img_dir)}] usados: {len(files)} | faltantes: {len(missing_imgs)} | sobrantes: {len(extra_imgs)}\")\n    if missing_imgs:\n        print(\"  - En CSV pero faltan en carpeta (muestra):\", missing_imgs[:10])\n    if extra_imgs:\n        print(\"  - En carpeta pero no en CSV (muestra):\", extra_imgs[:10])\n\n    return files, labels\n\ntrain_files, train_labels = load_split(train_dir, train_csv, label_columns)\ntest_files,  test_labels  = load_split(test_dir,  test_csv,  label_columns)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:12:59.854536Z","iopub.execute_input":"2025-08-17T03:12:59.855192Z","iopub.status.idle":"2025-08-17T03:12:59.986471Z","shell.execute_reply.started":"2025-08-17T03:12:59.855168Z","shell.execute_reply":"2025-08-17T03:12:59.985526Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_files, val_files, train_labels, val_labels = train_test_split(\n    train_files, train_labels, test_size=0.2, random_state=42, shuffle=True\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:06.312921Z","iopub.execute_input":"2025-08-17T03:14:06.313606Z","iopub.status.idle":"2025-08-17T03:14:06.319178Z","shell.execute_reply.started":"2025-08-17T03:14:06.313575Z","shell.execute_reply":"2025-08-17T03:14:06.318312Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:07.577487Z","iopub.execute_input":"2025-08-17T03:14:07.578479Z","iopub.status.idle":"2025-08-17T03:14:07.584375Z","shell.execute_reply.started":"2025-08-17T03:14:07.578442Z","shell.execute_reply":"2025-08-17T03:14:07.583612Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(val_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:09.451253Z","iopub.execute_input":"2025-08-17T03:14:09.451902Z","iopub.status.idle":"2025-08-17T03:14:09.457279Z","shell.execute_reply.started":"2025-08-17T03:14:09.451873Z","shell.execute_reply":"2025-08-17T03:14:09.456384Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(test_files)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:11.683769Z","iopub.execute_input":"2025-08-17T03:14:11.684108Z","iopub.status.idle":"2025-08-17T03:14:11.689446Z","shell.execute_reply.started":"2025-08-17T03:14:11.684086Z","shell.execute_reply":"2025-08-17T03:14:11.688655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"imagePreprocessing = BeitImageProcessor.from_pretrained(\"microsoft/beit-base-patch16-224-pt22k-ft22k\")\n\nnormalize = Normalize(mean=imagePreprocessing.image_mean, std=imagePreprocessing.image_std)\nsize = (imagePreprocessing.size[\"height\"], imagePreprocessing.size[\"width\"])\n\ntrainingTransforms = Compose([\n    Resize(size),\n    RandomRotation(180),\n    RandomHorizontalFlip(),\n    ToTensor(),\n    normalize\n])\n\ndef load_image(file):\n    image = Image.open(file).convert(\"RGB\")\n    return trainingTransforms(image)\n\ndef process_images(image_files, labels):\n    images = [load_image(file) for file in image_files]\n    return torch.stack(images), torch.tensor(labels)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:18.234393Z","iopub.execute_input":"2025-08-17T03:14:18.235378Z","iopub.status.idle":"2025-08-17T03:14:18.306738Z","shell.execute_reply.started":"2025-08-17T03:14:18.235345Z","shell.execute_reply":"2025-08-17T03:14:18.305835Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CustomDataset(torch.utils.data.Dataset):\n    def __init__(self, image_files, labels):\n        self.image_files = image_files\n        self.labels = labels\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        image = load_image(self.image_files[idx])\n        label = torch.tensor(self.labels[idx])\n        return {\"pixel_values\": image, \"labels\": label}\n\ntrain_dataset = CustomDataset(train_files, train_labels)\nval_dataset = CustomDataset(val_files, val_labels)\ntest_dataset = CustomDataset(test_files, test_labels)\n\ndef collate_fn(batch):\n    pixel_values = torch.stack([x[\"pixel_values\"] for x in batch])\n    labels = torch.stack([x[\"labels\"] for x in batch]).float()  # Asegurarse de que las etiquetas sean float\n    return {\"pixel_values\": pixel_values, \"labels\": labels}\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:19.803873Z","iopub.execute_input":"2025-08-17T03:14:19.804216Z","iopub.status.idle":"2025-08-17T03:14:19.810654Z","shell.execute_reply.started":"2025-08-17T03:14:19.804189Z","shell.execute_reply":"2025-08-17T03:14:19.809831Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Asegúrate de tener importada la librería PIL\nfrom PIL import Image\n\ndef load_image(file):\n    image = Image.open(file).convert(\"RGB\")\n    return trainingTransforms(image)\n\nmodel = BeitForImageClassification.from_pretrained(\n    \"microsoft/beit-base-patch16-224-pt22k-ft22k\",\n    num_labels=4,  # Cambiado para multilabel\n    problem_type=\"multi_label_classification\",\n    ignore_mismatched_sizes=True\n)\n\n\nfrom sklearn.metrics import f1_score\n\ndef compute_metrics(p):\n    pred_logits = p.predictions\n    pred_labels = (pred_logits > 0.5).astype(int)\n    true_labels = p.label_ids\n\n    f1 = f1_score(true_labels, pred_labels, average='samples')  # Calcula el F1 score\n    return {\"f1\": f1}\n\n\ntraining_args = TrainingArguments(\n    output_dir=\"./Beit-for-ODIR\",\n    remove_unused_columns=False,\n    per_device_train_batch_size=32,\n    per_device_eval_batch_size=32,\n    fp16=True,\n    load_best_model_at_end=True,\n    evaluation_strategy=\"steps\",\n    save_steps=30,\n    save_total_limit=2,\n    logging_steps=10,\n    num_train_epochs=10,\n    report_to=\"none\",\n)\n\ntrainer = Trainer(\n    model=model,\n    args=training_args,\n    data_collator=collate_fn,\n    compute_metrics=compute_metrics,\n    train_dataset=train_dataset,\n    eval_dataset=val_dataset,\n    tokenizer=imagePreprocessing,\n)\n\ntrain_results = trainer.train()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:14:20.455474Z","iopub.execute_input":"2025-08-17T03:14:20.455813Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"predictions = trainer.predict(test_dataset)\npred_logits = predictions.predictions\npred_labels = (pred_logits > 0.5).astype(int)\ntrue_labels = np.array([x['labels'] for x in test_dataset])\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.578016Z","iopub.status.idle":"2025-08-17T03:11:55.578459Z","shell.execute_reply.started":"2025-08-17T03:11:55.578217Z","shell.execute_reply":"2025-08-17T03:11:55.578235Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Guarda el modelo entrenado\ntrainer.save_model(\"/kaggle/working/\")\n\n# Guarda el procesador de imágenes\nimagePreprocessing.save_pretrained(\"/kaggle/working/\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.57963Z","iopub.status.idle":"2025-08-17T03:11:55.580036Z","shell.execute_reply.started":"2025-08-17T03:11:55.579822Z","shell.execute_reply":"2025-08-17T03:11:55.579838Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import f1_score, accuracy_score, precision_score, recall_score, confusion_matrix\n\nf1 = f1_score(true_labels, pred_labels, average='samples')\naccuracy = accuracy_score(true_labels, pred_labels)\nprecision = precision_score(true_labels, pred_labels, average='samples')\nrecall = recall_score(true_labels, pred_labels, average='samples')\n\nprint(f\"F1 Score: {f1}\")\nprint(f\"Accuracy: {accuracy}\")\nprint(f\"Precision: {precision}\")\nprint(f\"Recall: {recall}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.5813Z","iopub.status.idle":"2025-08-17T03:11:55.581712Z","shell.execute_reply.started":"2025-08-17T03:11:55.581487Z","shell.execute_reply":"2025-08-17T03:11:55.581503Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\n\ndef plot_confusion_matrix(conf_matrix, class_names):\n    fig, ax = plt.subplots(figsize=(10, 10))\n    cax = ax.matshow(conf_matrix, cmap=plt.cm.Blues)\n    fig.colorbar(cax)\n\n    ax.set_xticks(np.arange(len(class_names)))\n    ax.set_yticks(np.arange(len(class_names)))\n\n    ax.set_xticklabels(class_names)\n    ax.set_yticklabels(class_names)\n\n    plt.xlabel('Predicted')\n    plt.ylabel('True')\n    plt.show()\n\n# Calcular la matriz de confusión\nconf_matrix = confusion_matrix(true_labels.argmax(axis=1), pred_labels.argmax(axis=1))\nclass_names = [ 'CNV ', 'Laqquer Cracks', 'atrofia parcheada', 'tessellated', 'atrofia peripapilar']\nplot_confusion_matrix(conf_matrix, class_names)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.583126Z","iopub.status.idle":"2025-08-17T03:11:55.583419Z","shell.execute_reply.started":"2025-08-17T03:11:55.583281Z","shell.execute_reply":"2025-08-17T03:11:55.583293Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import roc_curve, auc\n\ndef plot_roc(true_labels, pred_probs, class_names):\n    plt.figure(figsize=(15, 10))\n    for i, class_name in enumerate(class_names):\n        fpr, tpr, _ = roc_curve(true_labels[:, i], pred_probs[:, i])\n        roc_auc = auc(fpr, tpr)\n        plt.plot(fpr, tpr, lw=2, label=f'{class_name} (AUC = {roc_auc:0.2f})')\n\n    plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')\n    plt.xlim([0.0, 1.0])\n    plt.ylim([0.0, 1.05])\n    plt.xlabel('False Positive Rate')\n    plt.ylabel('True Positive Rate')\n    plt.title('Receiver Operating Characteristic (ROC)')\n    plt.legend(loc=\"lower right\")\n    plt.show()\n\n# Graficar las curvas ROC\nplot_roc(true_labels, pred_logits, class_names)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.584819Z","iopub.status.idle":"2025-08-17T03:11:55.585116Z","shell.execute_reply.started":"2025-08-17T03:11:55.584965Z","shell.execute_reply":"2025-08-17T03:11:55.584977Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generar predicciones en el conjunto de prueba\npredictions = trainer.predict(test_dataset)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.586369Z","iopub.status.idle":"2025-08-17T03:11:55.586663Z","shell.execute_reply.started":"2025-08-17T03:11:55.586499Z","shell.execute_reply":"2025-08-17T03:11:55.58651Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nfrom sklearn.metrics import classification_report, confusion_matrix\n\n# Obtener los logits y etiquetas verdaderas\nlogits = predictions.predictions\ny_true = predictions.label_ids\n\n# Aplicar la función sigmoide para obtener probabilidades\nprobabilities = 1 / (1 + np.exp(-logits))\n\n# Convertir probabilidades a etiquetas binarias con un umbral de 0.5\ny_pred = (probabilities > 0.5).astype(int)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.587488Z","iopub.status.idle":"2025-08-17T03:11:55.587788Z","shell.execute_reply.started":"2025-08-17T03:11:55.587657Z","shell.execute_reply":"2025-08-17T03:11:55.587668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\nimport matplotlib.pyplot as plt\n\n# Suponiendo que label_columns es la lista de nombres de tus etiquetas\n\nfor i in range(len(label_columns)):\n    cm = confusion_matrix(y_true[:, i], y_pred[:, i])\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')\n    plt.title(f\"Matriz de confusión para {label_columns[i]}\")\n    plt.xlabel('Predicción')\n    plt.ylabel('Valor Verdadero')\n    plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.589285Z","iopub.status.idle":"2025-08-17T03:11:55.589538Z","shell.execute_reply.started":"2025-08-17T03:11:55.589418Z","shell.execute_reply":"2025-08-17T03:11:55.589428Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_columns = [\n    'exudados duros', 'hemorragias', 'laser spot', 'microaneurismas',\n    \"tessellated\", \"choroidal\", \"patchy\", \"patologia myopia\",\n    \"diabetic retinopathy\", \"cataract\", \"normal\"\n]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.590757Z","iopub.status.idle":"2025-08-17T03:11:55.591017Z","shell.execute_reply.started":"2025-08-17T03:11:55.590891Z","shell.execute_reply":"2025-08-17T03:11:55.590902Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimport torch\nimport numpy as np\n\n# 1. Cargar imagen y aplicar transformaciones\ndef infer_image(path_img):\n    image = Image.open(path_img).convert(\"RGB\")\n    transformed = trainingTransforms(image)  # Reutiliza tu pipeline\n    inputs = transformed.unsqueeze(0).to(model.device)  # (1, 3, 224, 224)\n\n    # 2. Pasar por el modelo\n    model.eval()\n    with torch.no_grad():\n        outputs = model(pixel_values=inputs)\n        probs = torch.sigmoid(outputs.logits).cpu().numpy()[0]\n\n    # 3. Umbral para multilabel (0.5)\n    pred_labels = (probs > 0.5).astype(int)\n\n    # 4. Mostrar resultado legible\n    resultado = {label: int(pred) for label, pred in zip(label_columns, pred_labels)}\n    return resultado\n\n# 🔍 Ejemplo de uso\nimg_path = \"/kaggle/input/myodir-crop/myodir-crop/24_left.jpg\"  # <- cambia por tu imagen\nresultado = infer_image(img_path)\nprint(\"Resultados de inferencia:\", resultado)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.592291Z","iopub.status.idle":"2025-08-17T03:11:55.59257Z","shell.execute_reply.started":"2025-08-17T03:11:55.592423Z","shell.execute_reply":"2025-08-17T03:11:55.592433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Generar el informe de clasificación\nreport = classification_report(y_true, y_pred, target_names=label_columns)\nprint(report)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.593853Z","iopub.status.idle":"2025-08-17T03:11:55.594178Z","shell.execute_reply.started":"2025-08-17T03:11:55.59403Z","shell.execute_reply":"2025-08-17T03:11:55.594042Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Guardar predicciones y etiquetas verdaderas\nnp.save('y_pred.npy', y_pred)\nnp.save('y_true.npy', y_true)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.594978Z","iopub.status.idle":"2025-08-17T03:11:55.595264Z","shell.execute_reply.started":"2025-08-17T03:11:55.595134Z","shell.execute_reply":"2025-08-17T03:11:55.595145Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_filenames = test_files  # Esto ya lo tienes; es el arreglo original con paths\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.596416Z","iopub.status.idle":"2025-08-17T03:11:55.596716Z","shell.execute_reply.started":"2025-08-17T03:11:55.596581Z","shell.execute_reply":"2025-08-17T03:11:55.596594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\n\n# Obtener logits y etiquetas verdaderas\nlogits = predictions.predictions\ny_true = predictions.label_ids\n\n# Aplicar sigmoide y umbral\nprobabilities = 1 / (1 + np.exp(-logits))\ny_pred = (probabilities > 0.5).astype(int)\n\n# Etiquetas\n\n# Guardar nombres sin la ruta completa (solo el nombre del archivo)\nfilenames = [os.path.basename(path) for path in test_filenames]\n\n# Crear DataFrame\ndf = pd.DataFrame({\n    \"filename\": filenames,\n    **{f\"True_{label}\": y_true[:, i] for i, label in enumerate(label_columns)},\n    **{f\"Pred_{label}\": y_pred[:, i] for i, label in enumerate(label_columns)},\n})\n\n# Guardar como CSV\ndf.to_csv(\"resultados_predicciones3.csv\", index=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.597907Z","iopub.status.idle":"2025-08-17T03:11:55.598161Z","shell.execute_reply.started":"2025-08-17T03:11:55.598038Z","shell.execute_reply":"2025-08-17T03:11:55.598049Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport zipfile\n\ndef folder_to_zip(folder_path, output_zip_path):\n    # Crear un archivo .zip\n    with zipfile.ZipFile(output_zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:\n        # Recorrer todos los archivos en el directorio\n        for root, dirs, files in os.walk(folder_path):\n            for file in files:\n                # Crear la ruta completa del archivo\n                full_path = os.path.join(root, file)\n                # Agregar el archivo al zip, eliminando el prefijo de la carpeta original\n                zipf.write(full_path, os.path.relpath(full_path, folder_path))\n\n    print(f\"Carpeta {folder_path} comprimida en {output_zip_path}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.599483Z","iopub.status.idle":"2025-08-17T03:11:55.599926Z","shell.execute_reply.started":"2025-08-17T03:11:55.599695Z","shell.execute_reply":"2025-08-17T03:11:55.599712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"folder_to_zip('/kaggle/working/Beit-for-ODIR/checkpoint-360', 'beit_dataset_fundus.zip')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-17T03:11:55.601225Z","iopub.status.idle":"2025-08-17T03:11:55.601643Z","shell.execute_reply.started":"2025-08-17T03:11:55.601417Z","shell.execute_reply":"2025-08-17T03:11:55.601433Z"}},"outputs":[],"execution_count":null}]}