{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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\n\n# Use the kagglehub client library to attach Kaggle resources like competitions, datasets, and models to your session\n# Learn more about kagglehub: https://github.com/Kaggle/kagglehub/blob/main/README.md\n\nimport kagglehub\n# kagglehub.dataset_download('<owner>/<dataset-slug>')\n\nimport os\nimport copy\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nimport matplotlib.pyplot as plt\n\nimport torch\nfrom torch import nn\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torchvision import transforms, datasets, models\nfrom torchvision.models import EfficientNet_B4_Weights\n\ntrain_dir = '/kaggle/input/competitions/butterflies-classification/train_butterflies/train_split'\ntest_dir = '/kaggle/input/competitions/butterflies-classification/test_butterflies/valid'\n\n\nnormalize = transforms.Normalize(\n    mean=[0.485, 0.456, 0.406],\n    std=[0.229, 0.224, 0.225]\n)\n\ntrain_transform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),\n    transforms.RandomHorizontalFlip(p=0.5),\n    transforms.RandomRotation(degrees=25),\n    transforms.ColorJitter(\n        brightness=0.2,\n        contrast=0.2,\n        saturation=0.2,\n        hue=0.05\n    ),\n    transforms.ToTensor(),\n    normalize,\n])\n\nvalid_test_transform = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    normalize,\n])","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:45.501754Z","iopub.execute_input":"2026-07-23T15:43:45.502491Z","iopub.status.idle":"2026-07-23T15:43:47.415942Z","shell.execute_reply.started":"2026-07-23T15:43:45.502459Z","shell.execute_reply":"2026-07-23T15:43:47.415221Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_dataset = datasets.ImageFolder(root=train_dir)\n\nnum_classes = len(base_dataset.classes)\nprint(\"classes:\", base_dataset.classes[:10], \"...\")\nprint(\"num_classes:\", num_classes)\nprint(\"dataset size:\", len(base_dataset))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.417235Z","iopub.execute_input":"2026-07-23T15:43:47.417567Z","iopub.status.idle":"2026-07-23T15:43:47.485627Z","shell.execute_reply.started":"2026-07-23T15:43:47.417524Z","shell.execute_reply":"2026-07-23T15:43:47.484809Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_size = int(0.8 * len(base_dataset))\nvalid_size = len(base_dataset) - train_size\n\ngenerator = torch.Generator().manual_seed(42)\ntrain_subset, valid_subset = random_split(base_dataset, [train_size, valid_size], generator=generator)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.486529Z","iopub.execute_input":"2026-07-23T15:43:47.486761Z","iopub.status.idle":"2026-07-23T15:43:47.491970Z","shell.execute_reply.started":"2026-07-23T15:43:47.486739Z","shell.execute_reply":"2026-07-23T15:43:47.491178Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class TransformedSubset(Dataset):\n    def __init__(self, subset, transform=None):\n        self.subset = subset\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.subset)\n\n    def __getitem__(self, idx):\n        image, label = self.subset[idx]\n        if self.transform:\n            image = self.transform(image)\n        return image, label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.494082Z","iopub.execute_input":"2026-07-23T15:43:47.494501Z","iopub.status.idle":"2026-07-23T15:43:47.506182Z","shell.execute_reply.started":"2026-07-23T15:43:47.494465Z","shell.execute_reply":"2026-07-23T15:43:47.505140Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_dataset = TransformedSubset(train_subset, transform=train_transform)\nvalid_dataset = TransformedSubset(valid_subset, transform=valid_test_transform)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.507315Z","iopub.execute_input":"2026-07-23T15:43:47.507652Z","iopub.status.idle":"2026-07-23T15:43:47.517710Z","shell.execute_reply.started":"2026-07-23T15:43:47.507614Z","shell.execute_reply":"2026-07-23T15:43:47.516763Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, img_dir, transform=None):\n        self.img_dir = img_dir\n        self.transform = transform\n        self.images = sorted([\n            f for f in os.listdir(img_dir)\n            if f.lower().endswith(('.jpg', '.jpeg', '.png'))\n        ], key=lambda x: int(x.split('.')[0]))\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        img_name = self.images[idx]\n        img_path = os.path.join(self.img_dir, img_name)\n\n        image = Image.open(img_path).convert('RGB')\n\n        if self.transform is not None:\n            image = self.transform(image)\n\n        return image, img_name","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.518663Z","iopub.execute_input":"2026-07-23T15:43:47.518929Z","iopub.status.idle":"2026-07-23T15:43:47.532130Z","shell.execute_reply.started":"2026-07-23T15:43:47.518908Z","shell.execute_reply":"2026-07-23T15:43:47.531410Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_dataset = TestDataset(test_dir, transform=valid_test_transform)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.532987Z","iopub.execute_input":"2026-07-23T15:43:47.533353Z","iopub.status.idle":"2026-07-23T15:43:47.545147Z","shell.execute_reply.started":"2026-07-23T15:43:47.533292Z","shell.execute_reply":"2026-07-23T15:43:47.544458Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(\n    train_dataset,\n    batch_size=32,\n    shuffle=True,\n    num_workers=2\n)\n\nvalid_loader = DataLoader(\n    valid_dataset,\n    batch_size=32,\n    shuffle=False,\n    num_workers=2\n)\n\ntest_loader = DataLoader(\n    test_dataset,\n    batch_size=32,\n    shuffle=False,\n    num_workers=2\n)\n\nprint(\"train batches:\", len(train_loader))\nprint(\"valid batches:\", len(valid_loader))\nprint(\"test batches:\", len(test_loader))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.546243Z","iopub.execute_input":"2026-07-23T15:43:47.547023Z","iopub.status.idle":"2026-07-23T15:43:47.559945Z","shell.execute_reply.started":"2026-07-23T15:43:47.546990Z","shell.execute_reply":"2026-07-23T15:43:47.559199Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nprint(\"device:\", device)\nif torch.cuda.is_available():\n    print(\"gpu:\", torch.cuda.get_device_name(0))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.561112Z","iopub.execute_input":"2026-07-23T15:43:47.561505Z","iopub.status.idle":"2026-07-23T15:43:47.575616Z","shell.execute_reply.started":"2026-07-23T15:43:47.561465Z","shell.execute_reply":"2026-07-23T15:43:47.574965Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**# Модель ResNet18**","metadata":{}},{"cell_type":"code","source":"model = models.resnet18(weights=None)\nmodel.fc = nn.Linear(model.fc.in_features, num_classes)\nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.578043Z","iopub.execute_input":"2026-07-23T15:43:47.578561Z","iopub.status.idle":"2026-07-23T15:43:47.769269Z","shell.execute_reply.started":"2026-07-23T15:43:47.578537Z","shell.execute_reply":"2026-07-23T15:43:47.768209Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Модель ResNet34**","metadata":{}},{"cell_type":"code","source":"model = models.resnet34(weights=None)\nmodel.fc = nn.Linear(model.fc.in_features, num_classes)\nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:47.770449Z","iopub.execute_input":"2026-07-23T15:43:47.771287Z","iopub.status.idle":"2026-07-23T15:43:48.105830Z","shell.execute_reply.started":"2026-07-23T15:43:47.771248Z","shell.execute_reply":"2026-07-23T15:43:48.104863Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Модель MobileNet V2**","metadata":{}},{"cell_type":"code","source":"model = models.mobilenet_v2(weights=None)\nmodel.classifier[1] = nn.Linear(model.classifier[1].in_features, num_classes)\nmodel = model.to(device)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:48.107044Z","iopub.execute_input":"2026-07-23T15:43:48.108197Z","iopub.status.idle":"2026-07-23T15:43:48.185188Z","shell.execute_reply.started":"2026-07-23T15:43:48.108168Z","shell.execute_reply":"2026-07-23T15:43:48.184616Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Модель EfficientNet_B4**","metadata":{}},{"cell_type":"code","source":"\n#weights = EfficientNet_B4_Weights.IMAGENET1K_V1\n#model = models.efficientnet_b4(weights=weights)\n\n# чистое обучение с нуля:\nmodel = models.efficientnet_b4(weights=None)\n\nin_features = model.classifier[1].in_features\nmodel.classifier[1] = nn.Linear(in_features, num_classes)\n\nmodel = model.to(device)\nprint(model.classifier)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:48.185997Z","iopub.execute_input":"2026-07-23T15:43:48.186313Z","iopub.status.idle":"2026-07-23T15:43:48.539834Z","shell.execute_reply.started":"2026-07-23T15:43:48.186289Z","shell.execute_reply":"2026-07-23T15:43:48.539083Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def train_one_epoch(model, dataloader, optimizer, loss_fn, device):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n\n    for images, labels in dataloader:\n        images = images.to(device)\n        labels = labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = loss_fn(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item() * images.size(0)\n\n        _, preds = torch.max(outputs, 1)\n        correct += (preds == labels).sum().item()\n        total += labels.size(0)\n\n    epoch_loss = running_loss / total\n    epoch_acc = correct / total\n    return epoch_loss, epoch_acc\n\n\n@torch.no_grad()\ndef valid_one_epoch(model, dataloader, loss_fn, device):\n    model.eval()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n\n    for images, labels in dataloader:\n        images = images.to(device)\n        labels = labels.to(device)\n\n        outputs = model(images)\n        loss = loss_fn(outputs, labels)\n\n        running_loss += loss.item() * images.size(0)\n\n        _, preds = torch.max(outputs, 1)\n        correct += (preds == labels).sum().item()\n        total += labels.size(0)\n\n    epoch_loss = running_loss / total\n    epoch_acc = correct / total\n    return epoch_loss, epoch_acc","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:48.540832Z","iopub.execute_input":"2026-07-23T15:43:48.541136Z","iopub.status.idle":"2026-07-23T15:43:48.549514Z","shell.execute_reply.started":"2026-07-23T15:43:48.541103Z","shell.execute_reply":"2026-07-23T15:43:48.548802Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=5e-4)\n\nnum_epochs = 25\n\nhistory = {\n    'train_loss': [],\n    'train_acc': [],\n    'valid_loss': [],\n    'valid_acc': []\n}\n\nbest_model_wts = copy.deepcopy(model.state_dict())\nbest_valid_acc = 0.0\n\nfor epoch in range(num_epochs):\n    train_loss, train_acc = train_one_epoch(model, train_loader, optimizer, criterion, device)\n    valid_loss, valid_acc = valid_one_epoch(model, valid_loader, criterion, device)\n\n    history['train_loss'].append(train_loss)\n    history['train_acc'].append(train_acc)\n    history['valid_loss'].append(valid_loss)\n    history['valid_acc'].append(valid_acc)\n\n    print(\n        f\"Epoch {epoch+1}/{num_epochs} | \"\n        f\"train_loss={train_loss:.4f} | train_acc={train_acc:.4f} | \"\n        f\"valid_loss={valid_loss:.4f} | valid_acc={valid_acc:.4f}\"\n    )\n\n    if valid_acc > best_valid_acc:\n        best_valid_acc = valid_acc\n        best_model_wts = copy.deepcopy(model.state_dict())\n\nprint(\"Best valid accuracy:\", best_valid_acc)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T15:43:48.550581Z","iopub.execute_input":"2026-07-23T15:43:48.550908Z","iopub.status.idle":"2026-07-23T16:09:12.835815Z","shell.execute_reply.started":"2026-07-23T15:43:48.550867Z","shell.execute_reply":"2026-07-23T16:09:12.834789Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.load_state_dict(best_model_wts)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:18.792589Z","iopub.execute_input":"2026-07-23T16:11:18.793040Z","iopub.status.idle":"2026-07-23T16:11:18.823091Z","shell.execute_reply.started":"2026-07-23T16:11:18.793010Z","shell.execute_reply":"2026-07-23T16:11:18.822283Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"График модели Resnet18","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12, 4))\n\nplt.subplot(1, 2, 1)\nplt.plot(history['train_loss'], label='train_loss')\nplt.plot(history['valid_loss'], label='valid_loss')\nplt.title('Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(history['train_acc'], label='train_acc')\nplt.plot(history['valid_acc'], label='valid_acc')\nplt.title('Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:21.508584Z","iopub.execute_input":"2026-07-23T16:11:21.508968Z","iopub.status.idle":"2026-07-23T16:11:21.799184Z","shell.execute_reply.started":"2026-07-23T16:11:21.508933Z","shell.execute_reply":"2026-07-23T16:11:21.798360Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Графк модели Resnet34","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(12, 4))\n\nplt.subplot(1, 2, 1)\nplt.plot(history['train_loss'], label='train_loss')\nplt.plot(history['valid_loss'], label='valid_loss')\nplt.title('Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(history['train_acc'], label='train_acc')\nplt.plot(history['valid_acc'], label='valid_acc')\nplt.title('Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:09:13.385713Z","iopub.execute_input":"2026-07-23T16:09:13.386675Z","iopub.status.idle":"2026-07-23T16:09:13.676100Z","shell.execute_reply.started":"2026-07-23T16:09:13.386621Z","shell.execute_reply":"2026-07-23T16:09:13.675273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"valid_loss, valid_acc = valid_one_epoch(model, valid_loader, criterion, device)\nprint(f\"Final valid loss: {valid_loss:.4f}\")\nprint(f\"Final valid accuracy: {valid_acc:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:34.986623Z","iopub.execute_input":"2026-07-23T16:11:34.987250Z","iopub.status.idle":"2026-07-23T16:11:38.874997Z","shell.execute_reply.started":"2026-07-23T16:11:34.987217Z","shell.execute_reply":"2026-07-23T16:11:38.874098Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\n\npredictions = []\nfilenames = []\n\nwith torch.no_grad():\n    for images, img_names in test_loader:\n        images = images.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs, 1)\n\n        predictions.extend(preds.cpu().numpy())\n        filenames.extend(img_names)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:38.876691Z","iopub.execute_input":"2026-07-23T16:11:38.876920Z","iopub.status.idle":"2026-07-23T16:11:40.019901Z","shell.execute_reply.started":"2026-07-23T16:11:38.876892Z","shell.execute_reply":"2026-07-23T16:11:40.019002Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'filename': filenames,\n    'label': predictions\n})\n\nsubmission['index'] = submission['filename'].str.replace('.jpg', '', regex=False).astype(int)\nsubmission = submission.sort_values('index')\nsubmission = submission[['index', 'label']]\n\nsubmission.to_csv('submission.csv', index=False)\nsubmission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:42.780555Z","iopub.execute_input":"2026-07-23T16:11:42.781129Z","iopub.status.idle":"2026-07-23T16:11:42.796920Z","shell.execute_reply.started":"2026-07-23T16:11:42.781095Z","shell.execute_reply":"2026-07-23T16:11:42.796180Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(submission.head(10))\nprint(submission.shape)\nprint(submission['index'].min(), submission['index'].max())\nprint(sorted(submission['index'].unique())[:20])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:49.114161Z","iopub.execute_input":"2026-07-23T16:11:49.114817Z","iopub.status.idle":"2026-07-23T16:11:49.122599Z","shell.execute_reply.started":"2026-07-23T16:11:49.114787Z","shell.execute_reply":"2026-07-23T16:11:49.121380Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(test_dataset.images[:20])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:09:19.051192Z","iopub.execute_input":"2026-07-23T16:09:19.052076Z","iopub.status.idle":"2026-07-23T16:09:19.063747Z","shell.execute_reply.started":"2026-07-23T16:09:19.052051Z","shell.execute_reply":"2026-07-23T16:09:19.062827Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(base_dataset.classes[:10])\nprint(base_dataset.class_to_idx)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:09:19.064749Z","iopub.execute_input":"2026-07-23T16:09:19.065126Z","iopub.status.idle":"2026-07-23T16:09:19.079576Z","shell.execute_reply.started":"2026-07-23T16:09:19.065093Z","shell.execute_reply":"2026-07-23T16:09:19.078706Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 1. Построение карты current_id -> true_id (ты это уже сделал)\nclasses = base_dataset.classes  # список 'class_0', 'class_1', 'class_10', ...\nname_to_true_id = {name: int(name.split('_')[1]) for name in classes}\nname_to_current_id = base_dataset.class_to_idx\ncurrent_to_true = {cur_id: name_to_true_id[name]\n                   for name, cur_id in name_to_current_id.items()}\n\n# Можно ещё раз проверить\nfor i in range(10):\n    print(i, '->', current_to_true[i])\n\n# 2. Перекодировка предсказаний\n# predictions — список/массив из твоего цикла по test_loader\nmapped_predictions = [current_to_true[int(p)] for p in predictions]\n\n# 3. Сабмишн\nsubmission = pd.DataFrame({\n    'filename': filenames,       # имена файлов: '0.jpg', '1.jpg', ...\n    'label': mapped_predictions  # ВАЖНО: уже перекодированные id\n})\n\nsubmission['index'] = submission['filename'].str.replace('.jpg', '', regex=False).astype(int)\nsubmission = submission.sort_values('index')\nsubmission = submission[['index', 'label']]\n\nsubmission.to_csv('submission.csv', index=False)\nprint(submission.head(10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-07-23T16:11:52.869481Z","iopub.execute_input":"2026-07-23T16:11:52.869892Z","iopub.status.idle":"2026-07-23T16:11:52.888552Z","shell.execute_reply.started":"2026-07-23T16:11:52.869851Z","shell.execute_reply":"2026-07-23T16:11:52.887684Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}