{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":91844,"databundleVersionId":11361821,"sourceType":"competition"},{"sourceId":11053663,"sourceType":"datasetVersion","datasetId":6886569},{"sourceId":11627519,"sourceType":"datasetVersion","datasetId":7294952},{"sourceId":11638793,"sourceType":"datasetVersion","datasetId":7302899},{"sourceId":11657344,"sourceType":"datasetVersion","datasetId":7315518},{"sourceId":11661073,"sourceType":"datasetVersion","datasetId":7318043},{"sourceId":368209,"sourceType":"modelInstanceVersion","modelInstanceId":305047,"modelId":325490},{"sourceId":370508,"sourceType":"modelInstanceVersion","modelInstanceId":306726,"modelId":327213},{"sourceId":370627,"sourceType":"modelInstanceVersion","modelInstanceId":306815,"modelId":327301},{"sourceId":371044,"sourceType":"modelInstanceVersion","modelInstanceId":307141,"modelId":327620},{"sourceId":372011,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":307890,"modelId":328339},{"sourceId":372049,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":307919,"modelId":328368}],"dockerImageVersionId":31012,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# I looked through several other approaches and decide to use efficientnet_b0 ","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport ast\nimport cv2\nimport math\nimport time\nimport timm\nimport torch\nimport random\nimport librosa\nimport logging\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport torch.nn as nn\nimport soundfile as sf\nfrom pathlib import Path\nfrom tqdm.auto import tqdm\nimport torch.optim as optim\nimport matplotlib.pyplot as plt\nimport torch.nn.functional as F\nimport torch.nn.functional as F_t\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom IPython.display import Audio, display\nfrom sklearn.model_selection import StratifiedKFold\nfrom torchaudio.transforms import TimeMasking, FrequencyMasking\nimport torchvision\n\n# Suppress warnings and limit logging output\nwarnings.filterwarnings(\"ignore\")\nlogging.basicConfig(level=logging.ERROR)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:02:46.641047Z","iopub.execute_input":"2025-05-05T04:02:46.641347Z","iopub.status.idle":"2025-05-05T04:03:00.354067Z","shell.execute_reply.started":"2025-05-05T04:02:46.641324Z","shell.execute_reply":"2025-05-05T04:03:00.353127Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"REGENERATE_SPECTROGRAMS = False\n\npretrained = False\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\nmodel_name = 'efficientnet_b0'\n\nbatch_size = 16\n\nSR = 32000  \nin_channels = 1\nN_FFT = 2048\nHOP_LENGTH = 512\nN_MELS = 512\nFMIN = 20\nFMAX = 16000\nTARGET_SHAPE = (256, 256)\n\ninput_path = \"/kaggle/input/birdclef-2025/\"\n\ntrain_csv = input_path + 'train.csv'\ntrain_audio = input_path + 'train_audio'\ntaxonomy_csv = input_path + 'taxonomy.csv'\ntest_soundscapes = '/kaggle/input/birdclef-2025/test_soundscapes'\ntrain_soundscapes = input_path + 'train_soundscapes'\nsubmission_csv = input_path + 'sample_submission.csv'\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.356121Z","iopub.execute_input":"2025-05-05T04:03:00.356593Z","iopub.status.idle":"2025-05-05T04:03:00.367161Z","shell.execute_reply.started":"2025-05-05T04:03:00.356566Z","shell.execute_reply":"2025-05-05T04:03:00.366252Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(train_csv)\ndf['filepath'] = \"/kaggle/input/birdclef-2025/train_audio/\" + df['filename']\ndf.head()\nprint(df.columns.tolist())\ndf.head(3)\ntaxonomy_df = pd.read_csv(taxonomy_csv)\nprint(f\"Number of classes: {len(taxonomy_df['primary_label'].tolist())}\")\n# taxonomy mappings\ntax2id = {t[\"primary_label\"]: i for i, t in taxonomy_df.iterrows()}\nid2tax = {i: t for t, i in tax2id.items()}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.368144Z","iopub.execute_input":"2025-05-05T04:03:00.368469Z","iopub.status.idle":"2025-05-05T04:03:00.618138Z","shell.execute_reply.started":"2025-05-05T04:03:00.368439Z","shell.execute_reply":"2025-05-05T04:03:00.617190Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"class FocalLossBCE(torch.nn.Module):\n    def __init__(\n            self,\n            alpha: float = 0.25,\n            gamma: float = 2,\n            reduction: str = \"mean\",\n            bce_weight: float = 0.6,\n            focal_weight: float = 1.4,\n    ):\n        super().__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n        self.reduction = reduction\n        self.bce = torch.nn.BCEWithLogitsLoss(reduction=reduction)\n        self.bce_weight = bce_weight\n        self.focal_weight = focal_weight\n\n    def forward(self, logits, targets):\n        focall_loss = torchvision.ops.focal_loss.sigmoid_focal_loss(\n            inputs=logits,\n            targets=targets,\n            alpha=self.alpha,\n            gamma=self.gamma,\n            reduction=self.reduction,\n        )\n        bce_loss = self.bce(logits, targets)\n        return self.bce_weight * bce_loss + self.focal_weight * focall_loss\n\ndef get_criterion(cfg):\n    return FocalLossBCE()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.619154Z","iopub.execute_input":"2025-05-05T04:03:00.619418Z","iopub.status.idle":"2025-05-05T04:03:00.627338Z","shell.execute_reply.started":"2025-05-05T04:03:00.619395Z","shell.execute_reply":"2025-05-05T04:03:00.626272Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def audio2melspec(audio_data):\n    mel_spec = librosa.feature.melspectrogram(\n        y=audio_data,\n        sr=SR,\n        n_fft=N_FFT,\n        hop_length=HOP_LENGTH,\n        n_mels=N_MELS,\n        fmin=FMIN,\n        fmax=FMAX,\n        power=2.0\n    )\n    mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max)\n    mel_spec_norm = (mel_spec_db - mel_spec_db.min()) / (mel_spec_db.max() - mel_spec_db.min() + 1e-8)\n    return mel_spec_norm\n\ndef process_audio_file(audio_path):\n    try:\n        audio_data, _ = librosa.load(audio_path, sr=SR)\n        target_samples = 5 * SR\n\n        # Repeat audio if too short\n        if len(audio_data) < target_samples:\n            n_copy = math.ceil(target_samples / len(audio_data))\n            audio_data = np.tile(audio_data, n_copy)\n\n        # Choose random 5-second segment\n        max_start = len(audio_data) - target_samples\n        start_idx = random.randint(0, max_start)\n        end_idx = start_idx + target_samples\n        segment = audio_data[start_idx:end_idx]\n\n        mel_spec = audio2melspec(segment)\n        mel_spec = cv2.resize(mel_spec, TARGET_SHAPE, interpolation=cv2.INTER_LINEAR)\n\n        return mel_spec.astype(np.float32)\n\n    except Exception as e:\n        print(f\"Error processing {audio_path}: {e}\")\n        return None\n\n\ndef get_spec_df(df):\n    spectrogram_data = []\n    for i, row in tqdm(df.iterrows(), total=len(df)):\n        # if  i >= 100:\n        #     break\n        \n        try:\n            primary_label = row['primary_label']\n            secondary_labels = row['secondary_labels']\n            filepath = row['filepath']\n            mel_spec = process_audio_file(filepath)\n            \n            if mel_spec is not None:\n                spectrogram_data.append({\n                    \"primary_label\": primary_label,\n                    \"secondary_labels\": secondary_labels,\n                    \"filepath\": filepath,\n                    \"mel_spec\": mel_spec  \n                })\n            \n        except Exception as e:\n            print(f\"Error processing {row.filepath}: {e}\")\n            errors.append((row.filepath, str(e)))\n    return pd.DataFrame(spectrogram_data)\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.629861Z","iopub.execute_input":"2025-05-05T04:03:00.630170Z","iopub.status.idle":"2025-05-05T04:03:00.651429Z","shell.execute_reply.started":"2025-05-05T04:03:00.630147Z","shell.execute_reply":"2025-05-05T04:03:00.650335Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # # this is for training\n# if REGENERATE_SPECTROGRAMS:\n#     spectrogram_df = get_spec_df(df)\n#     spectrogram_df.to_pickle(\"/kaggle/working/mel_spectrograms_v2.pkl\")\n# else:\n#     spectrogram_df = pd.read_pickle(\"/kaggle/input/d/harukatou/spectrograms/mel_spectrograms.pkl\")\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.652309Z","iopub.execute_input":"2025-05-05T04:03:00.652623Z","iopub.status.idle":"2025-05-05T04:03:00.673927Z","shell.execute_reply.started":"2025-05-05T04:03:00.652594Z","shell.execute_reply":"2025-05-05T04:03:00.672886Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# spectrogram_df.head()\n# spec = spectrogram_df[\"mel_spec\"][10_000]\n\n# # # plt.imshow(spec, origin=\"lower\", aspect=\"auto\", cmap=\"magma\")\n# # # plt.colorbar()\n# # # plt.title(\"Mel Spectrogram\")\n# # # plt.xlabel(\"Time\")\n# # # plt.ylabel(\"Mel Frequency\")\n# # # plt.tight_layout()\n# # # plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.675197Z","iopub.execute_input":"2025-05-05T04:03:00.675464Z","iopub.status.idle":"2025-05-05T04:03:00.693027Z","shell.execute_reply.started":"2025-05-05T04:03:00.675442Z","shell.execute_reply":"2025-05-05T04:03:00.692011Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class DatasetCLEF(Dataset):\n    def __init__(self, df, train=False):\n        self.df = df.reset_index(drop=True)\n        self.train = train\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        item = self.df.iloc[idx]\n\n        mel_spec = torch.tensor(item[\"mel_spec\"]).unsqueeze(0)\n\n        # Small augmentations\n        if self.train:\n            if random.uniform(0, 1) < 0.5:\n                mel_spec = FrequencyMasking(freq_mask_param=40)(mel_spec)\n            if random.uniform(0, 1) < 0.5:\n                mel_spec = TimeMasking(time_mask_param=40)(mel_spec)\n            \n        secondary = eval(item[\"secondary_labels\"])\n        all_labels = [item[\"primary_label\"]] + secondary\n        indices = [tax2id[lbl] for lbl in all_labels if lbl in tax2id]\n\n        target = np.zeros(len(tax2id), dtype=np.float32)\n        target[indices] = 1.0\n        target = torch.tensor(target)\n\n        return mel_spec, target\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.693995Z","iopub.execute_input":"2025-05-05T04:03:00.694256Z","iopub.status.idle":"2025-05-05T04:03:00.714161Z","shell.execute_reply.started":"2025-05-05T04:03:00.694233Z","shell.execute_reply":"2025-05-05T04:03:00.713130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ModelCLEF(nn.Module):\n    def __init__(self, num_classes):\n        super().__init__()\n        \n        self.backbone = timm.create_model(\n            model_name,\n            pretrained=pretrained,\n            in_chans=in_channels,\n            drop_rate=0.0,    \n            drop_path_rate=0.0\n        )\n\n        # Replace classifier head with identity\n        backbone_out = self.backbone.classifier.in_features\n        self.backbone.classifier = nn.Identity()\n\n        # Optional pooling if output is still feature map\n        self.pooling = nn.AdaptiveAvgPool2d(1)\n        self.classifier = nn.Linear(backbone_out, num_classes)\n\n    def forward(self, x):\n        features = self.backbone(x)\n\n        if isinstance(features, dict):\n            features = features['features']\n\n        if len(features.shape) == 4:\n            features = self.pooling(features)\n            features = features.view(features.size(0), -1)\n\n        logits = self.classifier(features)\n        return logits","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.715168Z","iopub.execute_input":"2025-05-05T04:03:00.715430Z","iopub.status.idle":"2025-05-05T04:03:00.736500Z","shell.execute_reply.started":"2025-05-05T04:03:00.715409Z","shell.execute_reply":"2025-05-05T04:03:00.735394Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def apply_tta(spec, tta_idx):\n    \"\"\"Apply test-time augmentation\"\"\"\n    if tta_idx == 0:\n        return spec\n    elif tta_idx == 1:\n        return np.flip(spec, axis=1).copy()  # Horizontal flip (time shift)\n    elif tta_idx == 2:\n        return np.flip(spec, axis=0).copy()  # Vertical flip (frequency shift)\n    else:\n        return spec","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.737519Z","iopub.execute_input":"2025-05-05T04:03:00.737894Z","iopub.status.idle":"2025-05-05T04:03:00.754474Z","shell.execute_reply.started":"2025-05-05T04:03:00.737863Z","shell.execute_reply":"2025-05-05T04:03:00.753611Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def process_audio_file_chunks(audio_path):\n    try:\n        audio_data, _ = librosa.load(audio_path, sr=SR)\n        target_samples = 5 * SR\n        mel_specs = []\n\n        for start in range(0, len(audio_data), target_samples):\n            end = start + target_samples\n            chunk = audio_data[start:end]\n\n            if len(chunk) < target_samples:\n                # Repeat last chunk to reach 5 seconds\n                n_copy = math.ceil(target_samples / len(chunk))\n                chunk = np.tile(chunk, n_copy)[:target_samples]\n\n            mel_spec = audio2melspec(chunk)\n            mel_spec = cv2.resize(mel_spec, TARGET_SHAPE, interpolation=cv2.INTER_LINEAR)\n            mel_specs.append(mel_spec.astype(np.float32))\n\n        return mel_specs\n\n    except Exception as e:\n        print(f\"Error processing {audio_path}: {e}\")\n        return None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.755415Z","iopub.execute_input":"2025-05-05T04:03:00.755732Z","iopub.status.idle":"2025-05-05T04:03:00.778240Z","shell.execute_reply.started":"2025-05-05T04:03:00.755689Z","shell.execute_reply":"2025-05-05T04:03:00.777043Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## From EDA we can see that our dataset is very imbalanced, so I decided to use StratifiedKFold to balance training","metadata":{}},{"cell_type":"code","source":"# if device == \"cuda\":\n#     skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)\n#     spectrogram_df[\"fold\"] = -1\n    \n#     for fold, (_, val_idx) in enumerate(skf.split(spectrogram_df, spectrogram_df[\"primary_label\"])):\n#         spectrogram_df.loc[val_idx, \"fold\"] = fold\n#     spectrogram_df.groupby(['fold', 'primary_label']).size().unstack(fill_value=0).T.plot(kind='bar', stacked=True, figsize=(15, 6))\n#     plt.title(\"Class distribution per fold\")\n#     plt.tight_layout()\n#     plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.779192Z","iopub.execute_input":"2025-05-05T04:03:00.779429Z","iopub.status.idle":"2025-05-05T04:03:00.795998Z","shell.execute_reply.started":"2025-05-05T04:03:00.779410Z","shell.execute_reply":"2025-05-05T04:03:00.795001Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# if device == \"cuda\":\n#     train_df = spectrogram_df[spectrogram_df[\"fold\"] != 0]\n#     val_df   = spectrogram_df[spectrogram_df[\"fold\"] == 0]\n    \n#     train_dataset = DatasetCLEF(train_df, train=True)\n#     val_dataset = DatasetCLEF(val_df, train=False)\n    \n#     train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=4, pin_memory=True)\n#     val_loader = DataLoader(val_dataset, batch_size=16, shuffle=False, num_workers=4, pin_memory=True)\n    \n#     model = ModelCLEF(num_classes=len(tax2id)).to(device)\n    \n#     # criterion = nn.BCEWithLogitsLoss()\n#     criterion = FocalLossBCE()\n#     optimizer = optim.AdamW(model.parameters(), lr=1e-4)\n#     scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=10)\n    \n#     best_val_loss = float('inf')\n#     for epoch in range(1, 7):\n#         print(f\"\\nEpoch {epoch}\")\n    \n#         model.train()\n#         train_loss = 0\n#         for mel, target in tqdm(train_loader, desc=\"Training\", leave=False):\n#             mel = mel.to(device)\n#             target = target.to(device)\n    \n#             optimizer.zero_grad()\n#             logits = model(mel)\n#             loss = criterion(logits, target)\n#             loss.backward()\n#             optimizer.step()\n    \n#             train_loss += loss.item() * mel.size(0)\n    \n#         avg_train_loss = train_loss / len(train_loader.dataset)\n    \n#         model.eval()\n#         val_loss = 0\n#         with torch.no_grad():\n#             for mel, target in tqdm(val_loader, desc=\"Validation\", leave=False):\n#                 mel = mel.to(device)\n#                 target = target.to(device)\n    \n#                 logits = model(mel)\n#                 loss = criterion(logits, target)\n#                 val_loss += loss.item() * mel.size(0)\n    \n#         avg_val_loss = val_loss / len(val_loader.dataset)\n    \n#         print(f\"Train Loss: {avg_train_loss:.4f} | Val Loss: {avg_val_loss:.4f}\")\n    \n#         scheduler.step()\n    \n#         # Save best model\n#         if avg_val_loss < best_val_loss:\n#             best_val_loss = avg_val_loss\n#             torch.save(model.state_dict(), f\"model{epoch}.pth\")\n#             print(f\"Saved model{epoch}.pth\")\n    \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.797403Z","iopub.execute_input":"2025-05-05T04:03:00.797700Z","iopub.status.idle":"2025-05-05T04:03:00.817359Z","shell.execute_reply.started":"2025-05-05T04:03:00.797678Z","shell.execute_reply":"2025-05-05T04:03:00.816460Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Evaluate","metadata":{}},{"cell_type":"code","source":"def find_test_files():\n    \"\"\"Find test files with multiple extensions for robustness\"\"\"\n    test_files = []\n    \n    # Try multiple audio extensions\n    for ext in ['*.ogg', '*.wav', '*.mp3', '*.flac']:\n        files = list(Path(test_soundscapes).glob(ext))\n        if files:\n            print(f\"Found {len(files)} files with extension {ext}\")\n            test_files.extend(files)\n    \n    # If no files found, try searching subdirectories\n    if not test_files:\n        print(\"No files found in main directory, checking subdirectories...\")\n        for subdir in Path(test_soundscapes).glob('**/'):\n            for ext in ['*.ogg', '*.wav', '*.mp3', '*.flac']:\n                files = list(subdir.glob(ext))\n                if files:\n                    print(f\"Found {len(files)} files with extension {ext} in {subdir}\")\n                    test_files.extend(files)\n    \n    return test_files","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.819642Z","iopub.execute_input":"2025-05-05T04:03:00.819969Z","iopub.status.idle":"2025-05-05T04:03:00.841895Z","shell.execute_reply.started":"2025-05-05T04:03:00.819945Z","shell.execute_reply":"2025-05-05T04:03:00.840794Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def submit():\n    class_labels = sorted(os.listdir(train_audio))\n    \n    test_files = list(Path(test_soundscapes).glob('*.ogg'))\n    \n    if not test_files:\n        print(\"It is not submission yet, so took 10 random files\")\n        test_files = list(Path(train_audio).rglob(\"*.ogg\"))[:10]\n    \n    print(len(test_files))\n    model = ModelCLEF(num_classes=len(tax2id))\n    model.load_state_dict(torch.load(\"/kaggle/input/effnet-b0-focal_loss-spec-v2/pytorch/default/1/b0-v2.pth\", map_location=device))\n    model.to(device)\n    model.eval()\n    \n    predictions = pd.DataFrame(columns=[\"row_id\"] + class_labels)\n    \n    for audio_path in test_files:\n        mels = process_audio_file_chunks(audio_path)\n        \n    \n        if mels is None:\n            print(f\"Skipping {audio_path} due to processing error.\")\n            continue\n    \n        for i, mel in enumerate(mels):\n            row_id = os.path.basename(audio_path).split('.')[0] + f\"_{(i+1)*5}\"\n            input_tensor = torch.tensor(mel, dtype=torch.float32).unsqueeze(0).unsqueeze(0).to(device)  \n    \n            logits_list = []\n\n            for tta_idx in range(3):\n                tta_mel = apply_tta(mel, tta_idx)\n                tta_tensor = torch.tensor(tta_mel, dtype=torch.float32).unsqueeze(0).unsqueeze(0).to(device)\n                \n                with torch.no_grad():\n                    logits = model(tta_tensor)[0]\n                    logits_list.append(logits)\n\n            # Average logits\n            avg_logits = torch.mean(torch.stack(logits_list), dim=0)\n            probs = torch.sigmoid(avg_logits).cpu().numpy().tolist()\n    \n            row = pd.DataFrame([[row_id] + probs], columns=[\"row_id\"] + class_labels)\n            predictions = pd.concat([predictions, row], ignore_index=True)\n\n    sample_submission = pd.read_csv(submission_csv)\n    assert set(predictions.columns) == set(sample_submission.columns)\n    \n    predictions.to_csv(\"submission.csv\", index=False, float_format=\"%.16f\")\n    print(\"saved submission.csv\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.842841Z","iopub.execute_input":"2025-05-05T04:03:00.843123Z","iopub.status.idle":"2025-05-05T04:03:00.868854Z","shell.execute_reply.started":"2025-05-05T04:03:00.843103Z","shell.execute_reply":"2025-05-05T04:03:00.867902Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submit()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-05T04:03:00.869846Z","iopub.execute_input":"2025-05-05T04:03:00.870184Z","iopub.status.idle":"2025-05-05T04:04:05.854113Z","shell.execute_reply.started":"2025-05-05T04:03:00.870155Z","shell.execute_reply":"2025-05-05T04:04:05.852921Z"}},"outputs":[],"execution_count":null}]}