{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpuV5e8","dataSources":[{"sourceType":"competition","sourceId":29653,"databundleVersionId":2420395}],"dockerImageVersionId":31287,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\"\"\"\nBrain Tumor MRI Cache Builder\n==============================\nRSNA-MICCAI 2021 — MGMT Methylation Classification\nPlatform : Kaggle GPU T4x2\nOutput   : numpy cache (4, 32, 224, 224) float32 [0, 1]\n\nUsage:\n    Run cell-by-cell in a Kaggle Notebook.\n    Cache is saved to /kaggle/working/cache/ automatically.\n    Re-running skips already-processed patients.\n\"\"\"\n\n\nimport os\nimport numpy as np\nimport cv2\nimport pydicom\nfrom pathlib import Path\nfrom tqdm import tqdm\n\n\n\nDATA_DIR   = Path(\"/kaggle/input/competitions/rsna-miccai-brain-tumor-radiogenomic-classification\")\nCACHE_DIR  = Path(\"/kaggle/working/cache\")\nIMG_SIZE   = 224          \nN_SLICES   = 32           \nMODALITIES = [\"FLAIR\", \"T1w\", \"T1wCE\", \"T2w\"]   \n\nCACHE_DIR.mkdir(parents=True, exist_ok=True)\n\ndef load_dicom(path: Path) -> np.ndarray\n    \"\"\"\n    Read one DICOM file → float32 array normalised to [0, 1].\n\n    Steps:\n      1. Read pixel_array  (uint16 or int16)\n      2. Apply RescaleSlope / RescaleIntercept when present\n      3. Clip 1-99th percentile  (removes scanner artefacts / hot pixels)\n      4. Min-max normalise → [0, 1]\n    \"\"\"\n    dcm = pydicom.dcmread(str(path))\n    img = dcm.pixel_array.astype(np.float32)\n\n    \n    slope     = float(getattr(dcm, \"RescaleSlope\",     1))\n    intercept = float(getattr(dcm, \"RescaleIntercept\", 0))\n    img = img * slope + intercept\n\n    \n    p1, p99 = np.percentile(img, [1, 99])\n    img = np.clip(img, p1, p99)\n\n    \n    lo, hi = img.min(), img.max()\n    img = (img - lo) / (hi - lo + 1e-6)\n\n    return img.astype(np.float32)\n\n\n\ndef select_slices(paths: list, n: int = N_SLICES) -> list:\n    \"\"\"\n    Strategy: the tumor sits in the axial *middle* of the brain volume.\n    We take slices from the 30th → 70th percentile of the sorted file list,\n    then uniformly sub-sample exactly `n` slices from that window.\n\n    Why 30-70 %?  The top / bottom 30 % of slices are mostly skull, neck,\n    and empty space — almost zero tumor content.\n    \"\"\"\n    \n    paths = sorted(paths)\n    total = len(paths)\n\n    if total <= n:\n        \n        return paths\n\n    start = int(total * 0.30)\n    end   = int(total * 0.70)\n    window = paths[start:end]\n\n    \n    indices = np.linspace(0, len(window) - 1, n, dtype=int)\n    return [window[i] for i in indices]\n\n\n\ndef process_patient(patient_dir: Path) -> np.ndarray:\n    \"\"\"\n    Build one (4, 32, 224, 224) float32 volume for a single patient.\n\n    Axis meanings:\n        axis 0  → modality  : [FLAIR, T1w, T1wCE, T2w]\n        axis 1  → slice     : 32 selected axial slices\n        axis 2  → height    : 224 px\n        axis 3  → width     : 224 px\n    \"\"\"\n    volume = np.zeros((4, N_SLICES, IMG_SIZE, IMG_SIZE), dtype=np.float32)\n\n    for m_idx, modality in enumerate(MODALITIES):\n        mod_dir = patient_dir / modality\n\n        if not mod_dir.exists():\n        \n            continue\n\n        \n        dcm_files = sorted(mod_dir.glob(\"*.dcm\"))\n        if len(dcm_files) == 0:\n            continue\n\n        \n        selected = select_slices(dcm_files, N_SLICES)\n\n        for s_idx, dcm_path in enumerate(selected):\n            img = load_dicom(dcm_path)                      \n\n            img = cv2.resize(img, (IMG_SIZE, IMG_SIZE),\n                             interpolation=cv2.INTER_AREA)\n\n            volume[m_idx, s_idx] = img\n\n    return volume   \n\n\n\ndef build_cache(split: str = \"train\"):\n    \"\"\"\n    Process every patient in `split` (train or test) and save as .npy.\n\n    Skips patients whose cache file already exists → safe to re-run.\n    \"\"\"\n    split_dir = DATA_DIR / split\n    patient_ids = sorted([p.name for p in split_dir.iterdir() if p.is_dir()])\n\n    out_dir = CACHE_DIR / split\n    out_dir.mkdir(parents=True, exist_ok=True)\n\n    print(f\"\\n[{split.upper()}]  {len(patient_ids)} patients  →  {out_dir}\\n\")\n\n    for pid in tqdm(patient_ids, desc=split):\n        out_path = out_dir / f\"{pid}.npy\"\n\n        if out_path.exists():\n            continue   # already cached — skip\n\n        volume = process_patient(split_dir / pid)\n        np.save(str(out_path), volume)\n\n    print(f\"  Done.  Cache written to: {out_dir}\")\n\n\n\ndef load_cache(patient_id: str, split: str = \"train\") -> np.ndarray:\n    \"\"\"\n    Load one cached patient.\n\n    Returns:\n        np.ndarray  shape (4, 32, 224, 224)  float32  [0, 1]\n    \"\"\"\n    path = CACHE_DIR / split / f\"{patient_id}.npy\"\n    return np.load(str(path))          \n\ndef sanity_check(split: str = \"train\", n: int = 3):\n    \"\"\"Print shape / dtype / range for the first n cached patients.\"\"\"\n    out_dir = CACHE_DIR / split\n    files = sorted(out_dir.glob(\"*.npy\"))[:n]\n\n    print(f\"\\n--- Sanity check ({split}) ---\")\n    for f in files:\n        vol = np.load(str(f))\n        print(f\"  {f.name}  shape={vol.shape}  dtype={vol.dtype}\"\n              f\"  min={vol.min():.3f}  max={vol.max():.3f}\")\n\n\n\nif __name__ == \"__main__\":\n    build_cache(\"train\")\n    build_cache(\"test\")\n    sanity_check(\"train\")\n    sanity_check(\"test\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-03-15T09:04:08.676566Z","iopub.execute_input":"2026-03-15T09:04:08.677388Z","iopub.status.idle":"2026-03-15T09:19:06.379976Z","shell.execute_reply.started":"2026-03-15T09:04:08.677358Z","shell.execute_reply":"2026-03-15T09:19:06.379252Z"}},"outputs":[{"name":"stdout","text":"\n[TRAIN]  585 patients  →  /kaggle/working/cache/train\n\n","output_type":"stream"},{"name":"stderr","text":"train: 100%|██████████| 585/585 [13:01<00:00,  1.34s/it]\n","output_type":"stream"},{"name":"stdout","text":"  Done.  Cache written to: /kaggle/working/cache/train\n\n[TEST]  87 patients  →  /kaggle/working/cache/test\n\n","output_type":"stream"},{"name":"stderr","text":"test: 100%|██████████| 87/87 [01:54<00:00,  1.31s/it]\n","output_type":"stream"},{"name":"stdout","text":"  Done.  Cache written to: /kaggle/working/cache/test\n\n--- Sanity check (train) ---\n  00000.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n  00002.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n  00003.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n\n--- Sanity check (test) ---\n  00001.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n  00013.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n  00015.npy  shape=(4, 32, 224, 224)  dtype=float32  min=0.000  max=1.000\n","output_type":"stream"}],"execution_count":6},{"cell_type":"code","source":"\"\"\"\nBrain Tumor MGMT — Model (reads directly from cache)\n=====================================================\nInput  : /kaggle/working/cache/train/*.npy\n         shape  (4, 32, 224, 224)  float32  [0.0 – 1.0]\n         axis 0 = modality  [FLAIR, T1w, T1wCE, T2w]\n         axis 1 = 32 slices\n         axis 2,3 = 224 × 224 pixels\n\nOutput : 0 or 1  (MGMT methylation status)\n\nMemory strategy to avoid OOM on T4x2\n  - Process ONE modality at a time inside the model (never load 4 at once in CNN)\n  - Use MobileNetV2 (3 MB) not EfficientNetB3 (43 MB)\n  - batch_size = 4  (safest for T4)\n  - clear_session() between folds\n\"\"\"\n\nimport gc\nimport numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom pathlib import Path\nfrom tqdm import tqdm\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.metrics import roc_auc_score\n\nTRAIN_CACHE = Path(\"/kaggle/working/cache/train\")  \nTEST_CACHE  = Path(\"/kaggle/working/cache/test\")\nLABELS_CSV  = Path(\"/kaggle/input/competitions/rsna-miccai-brain-tumor-radiogenomic-classification/train_labels.csv\")\nSAVE_DIR    = Path(\"/kaggle/working/models\")\nSAVE_DIR.mkdir(parents=True, exist_ok=True)\n\nIMG_SIZE    = 224\nN_SLICES    = 32\nN_MOD       = 4\nBATCH_SIZE  = 4        # small batch = safe memory on T4\nEPOCHS      = 30\nN_FOLDS     = 5\nAUTOTUNE    = tf.data.AUTOTUNE\n\n\n    tf.config.experimental.set_memory_growth(gpu, True)\n\nprint(f\"GPUs: {tf.config.list_physical_devices('GPU')}\")\n\n\n\ntrain_files = sorted(TRAIN_CACHE.glob(\"*.npy\"))\nassert len(train_files) > 0, f\"No .npy files found in {TRAIN_CACHE}\"\n\n_s = np.load(str(train_files[0]))\nprint(f\"Cache OK — {len(train_files)} files  |  \"\n      f\"shape={_s.shape}  dtype={_s.dtype}  \"\n      f\"min={_s.min():.2f}  max={_s.max():.2f}\")\nassert _s.shape == (N_MOD, N_SLICES, IMG_SIZE, IMG_SIZE), \\\n    f\"Expected (4,32,224,224), got {_s.shape}\"\ndel _s; gc.collect()\n\n\ndf           = pd.read_csv(LABELS_CSV)\ndf[\"pid\"]    = df[\"BraTS21ID\"].astype(str).str.zfill(5)\ncached_pids  = {f.stem for f in train_files}\ndf           = df[df[\"pid\"].isin(cached_pids)].reset_index(drop=True)\npatient_ids  = df[\"pid\"].values\nlabels       = df[\"MGMT_value\"].values\nprint(f\"Patients: {len(df)}  (1: {labels.sum()}  0: {(1-labels).sum()})\")\n\n\ndef load_npy(pid: str, cache_dir: Path = TRAIN_CACHE) -> np.ndarray:\n    \"\"\"\n    Load one .npy cache file.\n    Stored : (4, 32, 224, 224)\n    Return : (32, 224, 224, 4)  ← channels-last, required by TensorFlow\n    \"\"\"\n    vol = np.load(str(cache_dir / f\"{pid}.npy\"))  \n    vol = np.transpose(vol, (1, 2, 3, 0))           \n    return vol.astype(np.float32)\n\n\ndef augment(vol: tf.Tensor) -> tf.Tensor:\n    \"\"\"Minimal augmentation — keeps memory low.\"\"\"\n    vol = tf.cond(\n        tf.random.uniform(()) > 0.5,\n        lambda: tf.reverse(vol, axis=[2]),\n        lambda: vol\n    )\n    return vol\n\n\ndef make_dataset(pids, labs, training: bool) -> tf.data.Dataset:\n    def _load(pid, label):\n        vol = tf.py_function(\n            func=lambda p: load_npy(p.numpy().decode()),\n            inp=[pid], Tout=tf.float32\n        )\n        vol.set_shape([N_SLICES, IMG_SIZE, IMG_SIZE, N_MOD])\n        return vol, tf.cast(label, tf.float32)\n\n    ds = tf.data.Dataset.from_tensor_slices((pids, labs))\n    ds = ds.map(_load, num_parallel_calls=2)  \n    if training:\n        ds = ds.shuffle(200, seed=42)\n        ds = ds.map(lambda v, l: (augment(v), l), num_parallel_calls=2)\n    return ds.batch(BATCH_SIZE).prefetch(1)       \n\n\ndef build_model() -> tf.keras.Model:\n    \"\"\"\n    Memory-safe design:\n      - MobileNetV2 (3 MB) processes ONE modality at a time\n      - 4 modalities processed sequentially, features concatenated\n      - No TimeDistributed over 32 slices simultaneously\n        → instead use GlobalAveragePooling over the slice dimension\n\n    Input  : (batch, 32, 224, 224, 4)\n    Output : (batch, 1)  probability\n    \"\"\"\n\n\n    s_inp = tf.keras.Input(shape=(IMG_SIZE, IMG_SIZE, 3))\n    base  = tf.keras.applications.MobileNetV2(\n                input_shape=(IMG_SIZE, IMG_SIZE, 3),\n                include_top=False, weights=\"imagenet\")\n    base.trainable = False   \n\n    s_x   = base(s_inp, training=False)\n    s_x   = tf.keras.layers.GlobalAveragePooling2D()(s_x)  \n    s_x   = tf.keras.layers.Dense(96, activation=\"relu\")(s_x) \n    slice_enc = tf.keras.Model(s_inp, s_x, name=\"slice_enc\")\n\n\n    inp = tf.keras.Input(\n        shape=(N_SLICES, IMG_SIZE, IMG_SIZE, N_MOD), name=\"volume\")\n\n    mod_vecs = []\n    for m in range(N_MOD):\n        \n        single = inp[..., m:m+1]\n        single_rgb = tf.keras.layers.Lambda(\n            lambda t: tf.repeat(t, 3, axis=-1))(single)\n        encoded = tf.keras.layers.TimeDistributed(\n            slice_enc, name=f\"td_mod{m}\")(single_rgb) \n\n        \n        pooled = tf.keras.layers.GlobalAveragePooling1D(\n            name=f\"gap_mod{m}\")(encoded)               \n        mod_vecs.append(pooled)\n\n\n    x = tf.keras.layers.Concatenate(name=\"concat_mods\")(mod_vecs)\n\n    x   = tf.keras.layers.Dense(128, activation=\"relu\")(x)\n    x   = tf.keras.layers.Dropout(0.4)(x)\n    x   = tf.keras.layers.Dense(64,  activation=\"relu\")(x)\n    x   = tf.keras.layers.Dropout(0.3)(x)\n    out = tf.keras.layers.Dense(1, activation=\"sigmoid\", name=\"pred\")(x)\n\n    return tf.keras.Model(inp, out, name=\"mgmt_model\")\n\n\n\ndef focal_loss(gamma=2.0, alpha=0.25):\n    def _loss(y_true, y_pred):\n        y_pred = tf.clip_by_value(tf.cast(y_pred, tf.float32), 1e-7, 1-1e-7)\n        y_true = tf.cast(y_true, tf.float32)\n        bce    = -(y_true * tf.math.log(y_pred)\n                   + (1-y_true) * tf.math.log(1-y_pred))\n        p_t    = y_true*y_pred + (1-y_true)*(1-y_pred)\n        return tf.reduce_mean(alpha * tf.pow(1-p_t, gamma) * bce)\n    return _loss\n\n\n\ndef train():\n    skf       = StratifiedKFold(n_splits=N_FOLDS, shuffle=True, random_state=42)\n    oof_preds = np.zeros(len(df))\n    fold_aucs = []\n\n    for fold, (tr_idx, val_idx) in enumerate(skf.split(patient_ids, labels)):\n        print(f\"\\n{'='*50}\")\n        print(f\"  Fold {fold+1}/{N_FOLDS}  \"\n              f\"train={len(tr_idx)}  val={len(val_idx)}\")\n        print(f\"{'='*50}\")\n\n        tr_ds  = make_dataset(patient_ids[tr_idx],  labels[tr_idx],  True)\n        val_ds = make_dataset(patient_ids[val_idx], labels[val_idx], False)\n\n        model = build_model()\n        if fold == 0:\n            model.summary()\n\n        model.compile(\n            optimizer=tf.keras.optimizers.AdamW(\n                learning_rate=1e-3, weight_decay=1e-4),\n            loss=focal_loss(),\n            metrics=[tf.keras.metrics.AUC(name=\"auc\")]\n        )\n\n        callbacks = [\n            tf.keras.callbacks.ModelCheckpoint(\n                str(SAVE_DIR / f\"fold{fold:02d}.keras\"),\n                monitor=\"val_auc\", save_best_only=True, mode=\"max\"),\n            tf.keras.callbacks.EarlyStopping(\n                monitor=\"val_auc\", patience=8,\n                restore_best_weights=True, mode=\"max\"),\n            tf.keras.callbacks.ReduceLROnPlateau(\n                monitor=\"val_auc\", factor=0.5, patience=4,\n                mode=\"max\", min_lr=1e-6, verbose=1),\n        ]\n\n        model.fit(tr_ds, validation_data=val_ds,\n                  epochs=EPOCHS, callbacks=callbacks, verbose=1)\n\n        preds = model.predict(val_ds, verbose=0).ravel()\n        oof_preds[val_idx] = preds\n        auc = roc_auc_score(labels[val_idx], preds)\n        fold_aucs.append(auc)\n        print(f\"\\n  Fold {fold+1} AUC = {auc:.4f}\")\n\n    \n        del model, tr_ds, val_ds\n        tf.keras.backend.clear_session()\n        gc.collect()\n\n    oof_auc = roc_auc_score(labels, oof_preds)\n    print(f\"\\n{'='*50}\")\n    print(f\"  OOF AUC  : {oof_auc:.4f}\")\n    print(f\"  Per-fold : {[f'{a:.4f}' for a in fold_aucs]}\")\n    print(f\"  Mean±Std : {np.mean(fold_aucs):.4f} ± {np.std(fold_aucs):.4f}\")\n    print(f\"{'='*50}\")\n\n\n\ndef predict_test(n_tta: int = 6):\n    \"\"\"Load 5 fold-models, predict each test patient n_tta times, average.\"\"\"\n    test_files = sorted(TEST_CACHE.glob(\"*.npy\"))\n    if not test_files:\n        print(f\"No test cache found in {TEST_CACHE}\")\n        return {}\n\n    models = [\n        tf.keras.models.load_model(\n            str(SAVE_DIR / f\"fold{k:02d}.keras\"),\n            custom_objects={\"_loss\": focal_loss()})\n        for k in range(N_FOLDS)\n    ]\n\n    results = {}\n    for fpath in tqdm(test_files, desc=\"test inference\"):\n        pid  = fpath.stem\n        vol  = load_npy(pid, TEST_CACHE)           # (32, 224, 224, 4)\n\n        preds = []\n        for m in models:\n            for _ in range(n_tta):\n                aug = augment(tf.constant(vol)).numpy()\n                p   = float(m.predict(aug[np.newaxis], verbose=0)[0, 0])\n                preds.append(p)\n\n        prob         = float(np.mean(preds))\n        results[pid] = int(prob >= 0.5)\n        print(f\"  {pid}  prob={prob:.3f}  →  {results[pid]}\")\n\n    return results\n\n\n\nif __name__ == \"__main__\":\n    train()\n\n    predictions = predict_test(n_tta=6)\n\n    if predictions:\n        sub = pd.DataFrame(\n            [{\"BraTS21ID\": pid, \"MGMT_value\": v}\n             for pid, v in predictions.items()])\n        sub.to_csv(\"/kaggle/working/submission.csv\", index=False)\n        print(f\"\\nSaved {len(sub)} predictions → /kaggle/working/submission.csv\")\n        print(sub.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-15T09:50:35.066771Z","iopub.execute_input":"2026-03-15T09:50:35.066974Z","iopub.status.idle":"2026-03-15T09:51:07.552876Z","shell.execute_reply.started":"2026-03-15T09:50:35.066956Z","shell.execute_reply":"2026-03-15T09:51:07.551761Z"}},"outputs":[{"name":"stderr","text":"/usr/local/lib/python3.12/site-packages/jax/_src/cloud_tpu_init.py:93: UserWarning: Transparent hugepages are not enabled. TPU runtime startup and shutdown time should be significantly improved on TPU v5e and newer. If not already set, you may need to enable transparent hugepages in your VM image (sudo sh -c \"echo always > /sys/kernel/mm/transparent_hugepage/enabled\")\n  warnings.warn(\n","output_type":"stream"},{"name":"stdout","text":"GPUs: []\n","output_type":"stream"},{"name":"stderr","text":"2026-03-15 09:51:07.140721: E external/local_xla/xla/stream_executor/cuda/cuda_platform.cc:51] failed call to cuInit: INTERNAL: CUDA error: Failed call to cuInit: UNKNOWN ERROR (303)\n","output_type":"stream"},{"traceback":["\u001b[31m---------------------------------------------------------------------------\u001b[39m","\u001b[31mAssertionError\u001b[39m                            Traceback (most recent call last)","\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[1]\u001b[39m\u001b[32m, line 53\u001b[39m\n\u001b[32m     51\u001b[39m \u001b[38;5;66;03m# ── Verify cache ──────────────────────────────────────────────────────────────\u001b[39;00m\n\u001b[32m     52\u001b[39m train_files = \u001b[38;5;28msorted\u001b[39m(TRAIN_CACHE.glob(\u001b[33m\"\u001b[39m\u001b[33m*.npy\u001b[39m\u001b[33m\"\u001b[39m))\n\u001b[32m---> \u001b[39m\u001b[32m53\u001b[39m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(train_files) > \u001b[32m0\u001b[39m, \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mNo .npy files found in \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mTRAIN_CACHE\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m\n\u001b[32m     55\u001b[39m _s = np.load(\u001b[38;5;28mstr\u001b[39m(train_files[\u001b[32m0\u001b[39m]))\n\u001b[32m     56\u001b[39m \u001b[38;5;28mprint\u001b[39m(\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mCache OK — \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mlen\u001b[39m(train_files)\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m files  |  \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m     57\u001b[39m       \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mshape=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m_s.shape\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m  dtype=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m_s.dtype\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m  \u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m     58\u001b[39m       \u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mmin=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m_s.min()\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m  max=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m_s.max()\u001b[38;5;132;01m:\u001b[39;00m\u001b[33m.2f\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m\"\u001b[39m)\n","\u001b[31mAssertionError\u001b[39m: No .npy files found in /kaggle/working/cache/train"],"ename":"AssertionError","evalue":"No .npy files found in /kaggle/working/cache/train","output_type":"error"}],"execution_count":1},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}