{ "cells": [ { "cell_type": "code", "execution_count": 4, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Successfully installed huggingface_hub-0.30.1 kagglehub-0.3.11 safetensors-0.5.3 timm-1.0.15 torchvision-0.21.0 tqdm-4.67.1\n" ] } ], "source": [ "! pip install timm kagglehub" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting tensorboard\n", " Downloading tensorboard-2.19.0-py3-none-any.whl.metadata (1.8 kB)\n", "Collecting absl-py>=0.4 (from tensorboard)\n", " Downloading absl_py-2.2.2-py3-none-any.whl.metadata (2.6 kB)\n", "Collecting grpcio>=1.48.2 (from tensorboard)\n", " Downloading grpcio-1.71.0-cp313-cp313-macosx_10_14_universal2.whl.metadata (3.8 kB)\n", "Collecting markdown>=2.6.8 (from tensorboard)\n", " Downloading Markdown-3.7-py3-none-any.whl.metadata (7.0 kB)\n", "Requirement already satisfied: numpy>=1.12.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from tensorboard) (2.1.3)\n", "Requirement already satisfied: packaging in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from tensorboard) (24.2)\n", "Collecting protobuf!=4.24.0,>=3.19.6 (from tensorboard)\n", " Downloading protobuf-6.30.2-cp39-abi3-macosx_10_9_universal2.whl.metadata (593 bytes)\n", "Requirement already satisfied: setuptools>=41.0.0 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from tensorboard) (78.1.0)\n", "Requirement already satisfied: six>1.9 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from tensorboard) (1.17.0)\n", "Collecting tensorboard-data-server<0.8.0,>=0.7.0 (from tensorboard)\n", " Downloading tensorboard_data_server-0.7.2-py3-none-any.whl.metadata (1.1 kB)\n", "Collecting werkzeug>=1.0.1 (from tensorboard)\n", " Downloading werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB)\n", "Requirement already satisfied: MarkupSafe>=2.1.1 in /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages (from werkzeug>=1.0.1->tensorboard) (3.0.2)\n", "Downloading tensorboard-2.19.0-py3-none-any.whl (5.5 MB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m5.5/5.5 MB\u001b[0m \u001b[31m299.7 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m kB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m:06\u001b[0m\n", "\u001b[?25hDownloading absl_py-2.2.2-py3-none-any.whl (135 kB)\n", "Downloading grpcio-1.71.0-cp313-cp313-macosx_10_14_universal2.whl (11.3 MB)\n", "\u001b[2K \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m11.3/11.3 MB\u001b[0m \u001b[31m381.9 kB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m1m379.1 kB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n", "\u001b[?25hDownloading Markdown-3.7-py3-none-any.whl (106 kB)\n", "Downloading protobuf-6.30.2-cp39-abi3-macosx_10_9_universal2.whl (417 kB)\n", "Downloading tensorboard_data_server-0.7.2-py3-none-any.whl (2.4 kB)\n", "Downloading werkzeug-3.1.3-py3-none-any.whl (224 kB)\n", "Installing collected packages: werkzeug, tensorboard-data-server, protobuf, markdown, grpcio, absl-py, tensorboard\n", "Successfully installed absl-py-2.2.2 grpcio-1.71.0 markdown-3.7 protobuf-6.30.2 tensorboard-2.19.0 tensorboard-data-server-0.7.2 werkzeug-3.1.3\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "pip install tensorboard" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 5, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Downloading from https://www.kaggle.com/api/v1/datasets/download/birdy654/cifake-real-and-ai-generated-synthetic-images?dataset_version_number=3...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████████████████████████████████████████████████| 105M/105M [00:12<00:00, 8.88MB/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Extracting files...\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Path to dataset files: /Users/spass/.cache/kagglehub/datasets/birdy654/cifake-real-and-ai-generated-synthetic-images/versions/3\n" ] } ], "source": [ "import kagglehub\n", "path = kagglehub.dataset_download(\"birdy654/cifake-real-and-ai-generated-synthetic-images\")\n", "print(\"Path to dataset files:\", path)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "mv /Users/spass/.cache/kagglehub/datasets/birdy654/cifake-real-and-ai-generated-synthetic-images/versions/3 ./v3/" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "import os\n", "#import cv2\n", "from PIL import Image\n", "from torch.utils.data import Dataset\n", "from torchvision import transforms\n", "from torch.utils.data import DataLoader" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "#Dataset class 1 for real, 0 for fake\n", "class RealFakeDataset(Dataset):\n", " def __init__(self, root_dir, split='train', transform=None):\n", " self.root_dir = root_dir\n", " self.split = split\n", " self.transform = transform\n", " self.real_images = self._load_images(os.path.join(root_dir, split, 'REAL'))\n", " self.fake_images = self._load_images(os.path.join(root_dir, split, 'FAKE'))\n", " self.all_images = self.real_images + self.fake_images\n", "\n", " def _load_images(self, folder):\n", " images = []\n", " for filename in os.listdir(folder):\n", " if filename.endswith(('.jpg', '.jpeg')):\n", " images.append(os.path.join(folder, filename))\n", " return images\n", "\n", " def __len__(self):\n", " return len(self.all_images)\n", "\n", " def __getitem__(self, idx):\n", " img_path = self.all_images[idx]\n", " image = Image.open(img_path).convert('RGB')\n", " label = 1 if 'real' in img_path else 0 \n", "\n", " if self.transform:\n", " image = self.transform(image)\n", "\n", " return image, label\n", "\n", "transform = transforms.Compose([\n", " transforms.Resize((128, 128)),\n", " transforms.ToTensor(),\n", "])" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "#model\n", "import torch.nn as nn\n", "class ViTBinaryClassifier(nn.Module):\n", " def __init__(self, pretrained=True):\n", " super(ViTBinaryClassifier, self).__init__()\n", " self.backbone = timm.create_model(\"vit_medium_patch16_224\", pretrained=pretrained)\n", " in_features = self.backbone.head.in_features\n", " self.backbone.head = nn.Identity() \n", " self.classifier = nn.Sequential(\n", " nn.Linear(in_features, 512),\n", " nn.BatchNorm1d(512),\n", " nn.ReLU(),\n", " nn.Dropout(0.3),\n", " nn.Linear(512, 128),\n", " nn.BatchNorm1d(128),\n", " nn.ReLU(),\n", " nn.Dropout(0.3),\n", " nn.Linear(128, 1),\n", " nn.Sigmoid() \n", " )\n", " \n", " def forward(self, x):\n", " features = self.backbone(x)\n", " out = self.classifier(features)\n", " return out" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "def train(model, train_loader, criterion, optimizer, device, epoch, writer):\n", " model.train()\n", " running_loss = 0.0\n", " total = 0\n", " correct = 0\n", " \n", " for batch_idx, (images, labels) in enumerate(train_loader):\n", " images = images.to(device)\n", " labels = labels.float().to(device).unsqueeze(1)\n", " \n", " optimizer.zero_grad()\n", " outputs = model(images)\n", " loss = criterion(outputs, labels)\n", " loss.backward()\n", " optimizer.step()\n", " \n", " running_loss += loss.item()\n", " total += labels.size(0)\n", " predicted = (outputs > 0.5).float()\n", " correct += (predicted == labels).sum().item()\n", " \n", " avg_loss = running_loss / len(train_loader)\n", " accuracy = correct / total\n", " print(f\"Epoch {epoch} Train Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}\")\n", " \n", " # Logging to TensorBoard and WandB\n", " writer.add_scalar(\"Train/Loss\", avg_loss, epoch)\n", " writer.add_scalar(\"Train/Accuracy\", accuracy, epoch)\n", " wandb.log({\"Train Loss\": avg_loss, \"Train Accuracy\": accuracy, \"epoch\": epoch})\n", " \n", " return avg_loss, accuracy\n", "\n", "def test(model, test_loader, criterion, device, epoch, writer):\n", " model.eval()\n", " running_loss = 0.0\n", " total = 0\n", " correct = 0\n", " \n", " with torch.no_grad():\n", " for images, labels in test_loader:\n", " images = images.to(device)\n", " labels = labels.float().to(device).unsqueeze(1)\n", " outputs = model(images)\n", " loss = criterion(outputs, labels)\n", " running_loss += loss.item()\n", " \n", " predicted = (outputs > 0.5).float()\n", " total += labels.size(0)\n", " correct += (predicted == labels).sum().item()\n", " \n", " avg_loss = running_loss / len(test_loader)\n", " accuracy = correct / total\n", " print(f\"Epoch {epoch} Test Loss: {avg_loss:.4f}, Accuracy: {accuracy:.4f}\")\n", " \n", " writer.add_scalar(\"Test/Loss\", avg_loss, epoch)\n", " writer.add_scalar(\"Test/Accuracy\", accuracy, epoch)\n", " wandb.log({\"Test Loss\": avg_loss, \"Test Accuracy\": accuracy, \"epoch\": epoch})\n", " \n", " return avg_loss, accuracy" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [ { "ename": "FileNotFoundError", "evalue": "[Errno 2] No such file or directory: './train/REAL'", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mFileNotFoundError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[18]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m dataset = \u001b[43mRealFakeDataset\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot_dir\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43m.\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msplit\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mtrain\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtransform\u001b[49m\u001b[43m=\u001b[49m\u001b[43mtransform\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 2\u001b[39m dataloader = DataLoader(dataset, batch_size=\u001b[32m16\u001b[39m, shuffle=\u001b[38;5;28;01mTrue\u001b[39;00m)\n", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 7\u001b[39m, in \u001b[36mRealFakeDataset.__init__\u001b[39m\u001b[34m(self, root_dir, split, transform)\u001b[39m\n\u001b[32m 5\u001b[39m \u001b[38;5;28mself\u001b[39m.split = split\n\u001b[32m 6\u001b[39m \u001b[38;5;28mself\u001b[39m.transform = transform\n\u001b[32m----> \u001b[39m\u001b[32m7\u001b[39m \u001b[38;5;28mself\u001b[39m.real_images = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_load_images\u001b[49m\u001b[43m(\u001b[49m\u001b[43mos\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpath\u001b[49m\u001b[43m.\u001b[49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mroot_dir\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msplit\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[33;43m'\u001b[39;49m\u001b[33;43mREAL\u001b[39;49m\u001b[33;43m'\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 8\u001b[39m \u001b[38;5;28mself\u001b[39m.fake_images = \u001b[38;5;28mself\u001b[39m._load_images(os.path.join(root_dir, split, \u001b[33m'\u001b[39m\u001b[33mFAKE\u001b[39m\u001b[33m'\u001b[39m))\n\u001b[32m 9\u001b[39m \u001b[38;5;28mself\u001b[39m.all_images = \u001b[38;5;28mself\u001b[39m.real_images + \u001b[38;5;28mself\u001b[39m.fake_images\n", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[16]\u001b[39m\u001b[32m, line 13\u001b[39m, in \u001b[36mRealFakeDataset._load_images\u001b[39m\u001b[34m(self, folder)\u001b[39m\n\u001b[32m 11\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_load_images\u001b[39m(\u001b[38;5;28mself\u001b[39m, folder):\n\u001b[32m 12\u001b[39m images = []\n\u001b[32m---> \u001b[39m\u001b[32m13\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m filename \u001b[38;5;129;01min\u001b[39;00m \u001b[43mos\u001b[49m\u001b[43m.\u001b[49m\u001b[43mlistdir\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfolder\u001b[49m\u001b[43m)\u001b[49m:\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m filename.endswith((\u001b[33m'\u001b[39m\u001b[33m.jpg\u001b[39m\u001b[33m'\u001b[39m, \u001b[33m'\u001b[39m\u001b[33m.jpeg\u001b[39m\u001b[33m'\u001b[39m)):\n\u001b[32m 15\u001b[39m images.append(os.path.join(folder, filename))\n", "\u001b[31mFileNotFoundError\u001b[39m: [Errno 2] No such file or directory: './train/REAL'" ] } ], "source": [ "dataset = RealFakeDataset(root_dir='./', split='train', transform=transform)\n", "dataloader = DataLoader(dataset, batch_size=16, shuffle=True)" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [ { "ename": "NameError", "evalue": "name 'optimizer' is not defined", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[19]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m \u001b[43moptimizer\u001b[49m\n", "\u001b[31mNameError\u001b[39m: name 'optimizer' is not defined" ] } ], "source": [ "optimizer" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [ "wandb.init(project=\"vit_variable_resolution\", entity=\"your_wandb_entity\") # Set your wandb entity if needed\n", "writer = SummaryWriter(log_dir=\"./runs/vit_variable_resolution\")\n", "\n", "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", "\n", "# Define transforms for normalization (the resizing is handled in the dataset)\n", "transform = transforms.Compose([\n", " transforms.ToTensor(),\n", " transforms.Normalize(mean=[0.485, 0.456, 0.406], # Using ImageNet stats\n", " std=[0.229, 0.224, 0.225])\n", "])\n", "\n", "# Create dataset instances\n", "train_dataset = VariableResolutionDataset(root_dir=\"data/train\", resolutions=[224, 256, 288], transform=transform)\n", "test_dataset = VariableResolutionDataset(root_dir=\"data/test\", resolutions=[224, 256, 288], transform=transform)\n", "\n", "# Create DataLoaders\n", "train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)\n", "test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False, num_workers=4)\n", "\n", "# Initialize model, criterion, and optimizer\n", "model = ViTBinaryClassifier(pretrained=True).to(device)\n", "criterion = nn.BCELoss()\n", "optimizer = optim.Adam(model.parameters(), lr=3e-4)\n", "\n", "num_epochs = 10\n", "for epoch in range(1, num_epochs+1):\n", " train_loss, train_acc = train(model, train_loader, criterion, optimizer, device, epoch, writer)\n", " test_loss, test_acc = test(model, test_loader, criterion, device, epoch, writer)\n", "\n", "# Save model checkpoint\n", "torch.save(model.state_dict(), \"vit_binary_classifier.pth\")\n", "writer.close()\n", "wandb.finish()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [ { "ename": "NameError", "evalue": "name 'model' is not defined", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mNameError\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[21]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01mtorch\u001b[39;00m\u001b[34;01m.\u001b[39;00m\u001b[34;01moptim\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mas\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34;01moptim\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m optim.Adam(\u001b[43mmodel\u001b[49m.parameters(), lr=\u001b[32m3e-4\u001b[39m)\n", "\u001b[31mNameError\u001b[39m: name 'model' is not defined" ] } ], "source": [ "import torch.optim as optim\n", "optim.Adam(model.parameters(), lr=3e-4)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "vscode": { "languageId": "plaintext" } }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "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.13.2" } }, "nbformat": 4, "nbformat_minor": 4 }