{"metadata":{"kernelspec":{"display_name":"Python 3","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.11.13"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":99552,"databundleVersionId":13441085},{"sourceType":"datasetVersion","sourceId":12687919,"datasetId":7976292,"databundleVersionId":13297228}],"dockerImageVersionId":31090,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":79.101254,"end_time":"2025-07-30T17:08:48.446116","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-07-30T17:07:29.344862","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"##  RSNA Intracranial Aneurysm Detection - Inference Notebook","metadata":{"papermill":{"duration":0.003275,"end_time":"2025-07-30T17:07:33.344873","exception":false,"start_time":"2025-07-30T17:07:33.341598","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"####  I used to change the some tuning, some neural settings and parameter numbers to improve the score.","metadata":{}},{"cell_type":"markdown","source":"####  I use my **\"Urdu language\"** to promote.","metadata":{}},{"cell_type":"markdown","source":"# 1 Imports and Setup","metadata":{}},{"cell_type":"code","source":"import os\nimport sys\nimport gc\nimport json\nimport shutil\nimport warnings\nwarnings.filterwarnings('ignore')\nfrom pathlib import Path\nfrom collections import defaultdict\nfrom typing import List, Dict, Optional, Tuple\nfrom IPython.display import display\n\n# ڈیٹا ہینڈلنگ\nimport numpy as np\nimport polars as pl\nimport pandas as pd\n\n# میڈیکل امیجنگ\nimport pydicom\nimport cv2\n\n# مشین لرننگ / ڈیپ لرننگ\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.cuda.amp import autocast\nimport timm\n\n# ٹرانسفارمیشنز (ڈیٹا آگمینٹیشن)\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# مقابلے کی API\nimport kaggle_evaluation.rsna_inference_server\n\n# ڈیوائس سیٹ کرنا (GPU اگر دستیاب ہو)\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nprint(f\"استعمال ہونے والا ڈیوائس: {device}\")","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:36:59.35982Z","iopub.execute_input":"2025-08-31T01:36:59.360328Z","iopub.status.idle":"2025-08-31T01:37:44.002466Z","shell.execute_reply.started":"2025-08-31T01:36:59.360301Z","shell.execute_reply":"2025-08-31T01:37:44.001691Z"},"papermill":{"duration":48.035666,"end_time":"2025-07-30T17:08:21.383337","exception":false,"start_time":"2025-07-30T17:07:33.347671","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2 Changes some Configuration","metadata":{}},{"cell_type":"code","source":"# --- مقابلے کے مستقل اقدار ---\nID_COL = 'SeriesInstanceUID'  # ہر کیس کا منفرد آئی ڈی\nLABEL_COLS = [\n    'Left Infraclinoid Internal Carotid Artery',\n    'Right Infraclinoid Internal Carotid Artery',\n    'Left Supraclinoid Internal Carotid Artery',\n    'Right Supraclinoid Internal Carotid Artery',\n    'Left Middle Cerebral Artery',\n    'Right Middle Cerebral Artery',\n    'Anterior Communicating Artery',\n    'Left Anterior Cerebral Artery',\n    'Right Anterior Cerebral Artery',\n    'Left Posterior Communicating Artery',\n    'Right Posterior Communicating Artery',\n    'Basilar Tip',\n    'Other Posterior Circulation',\n    'Aneurysm Present',\n]\nSELECTED_MODEL = 'ensemble'  # منتخب ماڈل (یہاں Ensemble)\n\n# --- ماڈل پاتھ کنفیگریشن ---\nMODEL_PATHS = {\n    'tf_efficientnetv2_s': '/kaggle/input/rsna-iad-trained-models/models/tf_efficientnetv2_s_fold0_best.pth',\n    'convnext_small': '/kaggle/input/rsna-iad-trained-models/models/convnext_small_fold0_best.pth',\n    'swin_small_patch4_window7_224': '/kaggle/input/rsna-iad-trained-models/models/swin_small_patch4_window7_224_fold0_best.pth'\n}\n\nclass InferenceConfig:\n    # --- ماڈل کا انتخاب ---\n    model_selection = SELECTED_MODEL\n    use_ensemble = (SELECTED_MODEL == 'ensemble')\n    \n    # --- ڈیفالٹ ماڈل سیٹنگز (چیک پوائنٹ سے اوور رائیڈ ہوں گی) ---\n    image_size = 512       # ان پٹ امیج کا سائز\n    num_slices = 32        # استعمال ہونے والے DICOM سلائسز کی تعداد\n    use_windowing = True   # کیا ونڈونگ اپلائی کرنی ہے یا نہیں\n    \n    # --- انفیرینس سیٹنگز ---\n    batch_size = 1         # بیچ سائز (انفیرینس کے دوران)\n    use_amp = True         # آٹو مکسڈ پریسجن (AMP)\n    use_tta = True         # ٹیسٹ ٹائم آگمینٹیشن کا استعمال\n    tta_transforms = 4     # TTA کی تعداد\n    \n    # --- اگر Ensemble استعمال ہو رہا ہے تو وزن ---\n    ensemble_weights = {\n        'tf_efficientnetv2_s': 0.4,\n        'convnext_small': 0.3,\n        'swin_small_patch4_window7_224': 0.3\n    }\nCFG = InferenceConfig()","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.003859Z","iopub.execute_input":"2025-08-31T01:37:44.004271Z","iopub.status.idle":"2025-08-31T01:37:44.00983Z","shell.execute_reply.started":"2025-08-31T01:37:44.004252Z","shell.execute_reply":"2025-08-31T01:37:44.009146Z"},"papermill":{"duration":0.009181,"end_time":"2025-07-30T17:08:21.39509","exception":false,"start_time":"2025-07-30T17:08:21.385909","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3 Model Architecture","metadata":{}},{"cell_type":"code","source":"class MultiBackboneModel(nn.Module):\n    \"\"\"لچکدار ماڈل جو مختلف بیک بون استعمال کرسکتا ہے\"\"\"\n    def __init__(self, model_name, num_classes=14, pretrained=True, \n                 drop_rate=0.3, drop_path_rate=0.2):  # ڈراپ ریٹ اور ڈراپ پاتھ ریٹ تھوڑا بڑھا دیا گیا ہے\n        super().__init__()\n        \n        self.model_name = model_name\n        \n        if 'swin' in model_name:\n            # Swin ٹرانسفارمر کے لیے ڈیفالٹ 224x224 ہوتا ہے\n            self.backbone = timm.create_model(\n                model_name, \n                pretrained=pretrained,\n                in_chans=3,\n                drop_rate=drop_rate,\n                drop_path_rate=drop_path_rate,\n                img_size=CFG.image_size,  # ڈیفالٹ سائز اوور رائیڈ\n                num_classes=0,  # کلاسیفائر ہیڈ ہٹا دیا\n                global_pool=''  # گلوبل پولنگ ہٹا دی\n            )\n        else:\n            self.backbone = timm.create_model(\n                model_name, \n                pretrained=pretrained,\n                in_chans=3,\n                drop_rate=drop_rate,\n                drop_path_rate=drop_path_rate,\n                num_classes=0,  # کلاسیفائر ہیڈ ہٹا دیا\n                global_pool=''  # گلوبل پولنگ ہٹا دی\n            )\n        \n        with torch.no_grad():\n            dummy_input = torch.zeros(1, 3, CFG.image_size, CFG.image_size)\n            features = self.backbone(dummy_input)\n            \n            if len(features.shape) == 4:\n                # Conv فیچرز (batch, channels, height, width)\n                num_features = features.shape[1]\n                self.needs_pool = True\n            elif len(features.shape) == 3:\n                # Transformer فیچرز (batch, sequence, features)\n                num_features = features.shape[-1]\n                self.needs_pool = False\n                self.needs_seq_pool = True\n            else:\n                # پہلے سے فلیٹ فیچرز (batch, features)\n                num_features = features.shape[1]\n                self.needs_pool = False\n                self.needs_seq_pool = False\n        \n        print(f\"ماڈل {model_name}: {num_features} فیچرز ڈیٹیکٹ ہوئے، آؤٹ پٹ شکل: {features.shape}\")\n        \n        # اگر ماڈل اسپیشل فیچرز دیتا ہے تو گلوبل پولنگ شامل کریں\n        if self.needs_pool:\n            self.global_pool = nn.AdaptiveAvgPool2d(1)\n        \n        # میٹا ڈیٹا پروسیسنگ\n        self.meta_fc = nn.Sequential(\n            nn.Linear(2, 32),  # فیچرز بڑھا دیے\n            nn.ReLU(),\n            nn.Dropout(0.3),\n            nn.Linear(32, 64),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(16, 32),\n            nn.ReLU()\n        )\n        \n        # کلاسیفائر بیچ نارم کے ساتھ زیادہ اسٹیبل\n        self.classifier = nn.Sequential(\n            nn.Linear(num_features + 64, 512),\n            nn.BatchNorm1d(512),\n            nn.ReLU(),\n            nn.Dropout(drop_rate),\n            nn.Linear(512, 256),\n            nn.BatchNorm1d(256),\n            nn.ReLU(),\n            nn.Dropout(drop_rate),\n            nn.Linear(256, num_classes)\n        )\n        \n    def forward(self, image, meta):\n        # امیج فیچرز نکالیں\n        img_features = self.backbone(image)\n        \n        # ماڈل ٹائپ کی بنیاد پر پولنگ اپلائی کریں\n        if hasattr(self, 'needs_pool') and self.needs_pool:\n            # Conv فیچرز پر گلوبل پولنگ\n            img_features = self.global_pool(img_features)\n            img_features = img_features.flatten(1)\n        elif hasattr(self, 'needs_seq_pool') and self.needs_seq_pool:\n            # Transformer فیچرز کے لیے سیکوئنس پر ایوریج\n            img_features = img_features.mean(dim=1)\n        elif len(img_features.shape) == 4:\n            # fallback 4D آؤٹ پٹ\n            img_features = F.adaptive_avg_pool2d(img_features, 1).flatten(1)\n        elif len(img_features.shape) == 3:\n            # fallback 3D آؤٹ پٹ\n            img_features = img_features.mean(dim=1)\n        \n        # میٹا ڈیٹا پروسیسنگ\n        meta_features = self.meta_fc(meta)\n        \n        # فیچرز کومبائن کریں\n        combined = torch.cat([img_features, meta_features], dim=1)\n        \n        # کلاسیفکیشن\n        output = self.classifier(combined)\n        \n        return output","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.010677Z","iopub.execute_input":"2025-08-31T01:37:44.010997Z","iopub.status.idle":"2025-08-31T01:37:44.072274Z","shell.execute_reply.started":"2025-08-31T01:37:44.010973Z","shell.execute_reply":"2025-08-31T01:37:44.07168Z"},"papermill":{"duration":0.0138,"end_time":"2025-07-30T17:08:21.411432","exception":false,"start_time":"2025-07-30T17:08:21.397632","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 4 DICOM Processing Functions\n","metadata":{}},{"cell_type":"code","source":"def apply_dicom_windowing(img: np.ndarray, window_center: float, window_width: float) -> np.ndarray:\n    \"\"\"DICOM امیجز پر ونڈوئنگ لاگو کریں\"\"\"\n    img_min = window_center - window_width // 2\n    img_max = window_center + window_width // 2\n    img = np.clip(img, img_min, img_max)\n    img = (img - img_min) / (img_max - img_min + 1e-7)\n    return (img * 255).astype(np.uint8)\n\n\ndef get_windowing_params(modality: str) -> Tuple[float, float]:\n    \"\"\"مختلف موڈیلٹیز کے لئے ونڈوئنگ پیرامیٹرز حاصل کریں\"\"\"\n    windows = {\n        'CT': (30, 70),   # ہائپرپیرامیٹر قدر کو قدرے بڑھا دیا گیا\n        'CTA': (50, 350),  # زیادہ کنٹراسٹ کے لئے اپڈیٹ\n        'MRA': (500, 1200), # تھوڑا کم کیا\n        'MRI': (40, 80),   # قدرے ایڈجسٹ کیا\n    }\n    return windows.get(modality, (40, 80))\n\n\ndef process_dicom_series(series_path: str) -> Tuple[np.ndarray, Dict]:\n    \"\"\"DICOM سیریز کو پروسیس کریں اور میٹا ڈیٹا نکالیں\"\"\"\n    series_path = Path(series_path)\n\n    # تمام DICOM فائلز تلاش کریں\n    all_filepaths = []\n    for root, _, files in os.walk(series_path):\n        for file in files:\n            if file.endswith('.dcm'):\n                all_filepaths.append(os.path.join(root, file))\n    all_filepaths.sort()\n\n    if len(all_filepaths) == 0:\n        # اگر کوئی فائل نہ ہو تو ڈیفالٹ اقدار ریٹرن کریں\n        volume = np.zeros((CFG.num_slices, CFG.image_size, CFG.image_size), dtype=np.uint8)\n        metadata = {'age': 50, 'sex': 0, 'modality': 'CT'}\n        return volume, metadata\n\n    # DICOM فائلز پروسیسنگ\n    slices = []\n    metadata = {}\n\n    for i, filepath in enumerate(all_filepaths):\n        try:\n            ds = pydicom.dcmread(filepath, force=True)\n            img = ds.pixel_array.astype(np.float32)\n\n            # اگر امیج ملٹی فریم یا کلر ہو\n            if img.ndim == 3:\n                if img.shape[-1] == 3:\n                    img = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2GRAY).astype(np.float32)\n                else:\n                    img = img[:, :, 0]\n\n            # پہلی فائل سے میٹا ڈیٹا نکالنا\n            if i == 0:\n                metadata['modality'] = getattr(ds, 'Modality', 'CT')\n\n                try:\n                    age_str = getattr(ds, 'PatientAge', '050Y')\n                    age = int(''.join(filter(str.isdigit, age_str[:3])) or '50')\n                    metadata['age'] = min(age, 100)\n                except:\n                    metadata['age'] = 50\n\n                try:\n                    sex = getattr(ds, 'PatientSex', 'M')\n                    metadata['sex'] = 1 if sex == 'M' else 0\n                except:\n                    metadata['sex'] = 0\n\n            # اگر RescaleSlope اور Intercept موجود ہوں تو لگائیں\n            if hasattr(ds, 'RescaleSlope') and hasattr(ds, 'RescaleIntercept'):\n                img = img * ds.RescaleSlope + ds.RescaleIntercept\n\n            # ونڈوئنگ لگانا\n            if CFG.use_windowing:\n                window_center, window_width = get_windowing_params(metadata['modality'])\n                img = apply_dicom_windowing(img, window_center, window_width)\n            else:\n                img_min, img_max = img.min(), img.max()\n                if img_max > img_min:\n                    img = ((img - img_min) / (img_max - img_min) * 255).astype(np.uint8)\n                else:\n                    img = np.zeros_like(img, dtype=np.uint8)\n\n            # سائز کو ری سکیل کریں\n            img = cv2.resize(img, (CFG.image_size, CFG.image_size))\n            slices.append(img)\n\n        except Exception as e:\n            print(f\"غلطی فائل پروسیس کرتے وقت: {filepath}, {e}\")\n            continue\n\n    # اگر سلائسز نہ ہوں تو ڈیفالٹ\n    if len(slices) == 0:\n        volume = np.zeros((CFG.num_slices, CFG.image_size, CFG.image_size), dtype=np.uint8)\n    else:\n        volume = np.array(slices)\n        if len(slices) > CFG.num_slices:\n            indices = np.linspace(0, len(slices) - 1, CFG.num_slices).astype(int)\n            volume = volume[indices]\n        elif len(slices) < CFG.num_slices:\n            pad_size = CFG.num_slices - len(slices)\n            volume = np.pad(volume, ((0, pad_size), (0, 0), (0, 0)), mode='edge')\n\n    return volume, metadata","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.074142Z","iopub.execute_input":"2025-08-31T01:37:44.074406Z","iopub.status.idle":"2025-08-31T01:37:44.091252Z","shell.execute_reply.started":"2025-08-31T01:37:44.074362Z","shell.execute_reply":"2025-08-31T01:37:44.09057Z"},"papermill":{"duration":0.016392,"end_time":"2025-07-30T17:08:21.430308","exception":false,"start_time":"2025-07-30T17:08:21.413916","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 5 Transform Functions","metadata":{}},{"cell_type":"code","source":"def get_inference_transform():\n    \"\"\"انفرنس (اندازہ لگانے) کے لئے تصویر کی تبدیلیاں حاصل کریں\"\"\"\n    return A.Compose([\n        A.Normalize(mean=[0.50, 0.50, 0.50], std=[0.25, 0.25, 0.25]),  # اوسط اور معیاری انحراف کو تھوڑا بدلا\n        ToTensorV2()\n    ])\n\n\ndef get_tta_transforms():\n    \"\"\"ٹیسٹ ٹائم آگمینٹیشن (TTA) کے لئے تبدیلیاں حاصل کریں\"\"\"\n    transforms = [\n        A.Compose([  # اصل تصویر\n            A.Normalize(mean=[0.50, 0.50, 0.50], std=[0.25, 0.25, 0.25]),\n            ToTensorV2()\n        ]),\n        A.Compose([  # افقی پلٹاؤ\n            A.HorizontalFlip(p=1.0),\n            A.Normalize(mean=[0.50, 0.50, 0.50], std=[0.25, 0.25, 0.25]),\n            ToTensorV2()\n        ]),\n        A.Compose([  # عمودی پلٹاؤ\n            A.VerticalFlip(p=1.0),\n            A.Normalize(mean=[0.50, 0.50, 0.50], std=[0.25, 0.25, 0.25]),\n            ToTensorV2()\n        ]),\n        A.Compose([  # 90 ڈگری گھماؤ\n            A.RandomRotate90(p=1.0),\n            A.Normalize(mean=[0.50, 0.50, 0.50], std=[0.25, 0.25, 0.25]),\n            ToTensorV2()\n        ])\n    ]\n    print(\"ٹیسٹ ٹائم آگمینٹیشن کے لئے تبدیلیاں تیار کر دی گئیں\")\n    return transforms","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.091955Z","iopub.execute_input":"2025-08-31T01:37:44.092189Z","iopub.status.idle":"2025-08-31T01:37:44.107338Z","shell.execute_reply.started":"2025-08-31T01:37:44.092165Z","shell.execute_reply":"2025-08-31T01:37:44.106611Z"},"papermill":{"duration":0.009704,"end_time":"2025-07-30T17:08:21.44247","exception":false,"start_time":"2025-07-30T17:08:21.432766","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 6 Model Loading Functions","metadata":{}},{"cell_type":"code","source":"# عالمی ویری ایبلز\nMODELS = {}\nTRANSFORM = None\nTTA_TRANSFORMS = None\n\ndef load_single_model(model_name: str, model_path: str) -> nn.Module:\n    \"\"\"ایک ماڈل لوڈ کریں\"\"\"\n    print(f\"{model_name} کو {model_path} سے لوڈ کیا جا رہا ہے...\")\n    \n    if not os.path.exists(model_path):\n        raise FileNotFoundError(f\"ماڈل فائل نہیں ملی: {model_path}\")\n    \n    # چیک پوائنٹ لوڈ کریں (weights_only=False تاکہ numpy scalars ہینڈل ہوں)\n    checkpoint = torch.load(model_path, map_location=device, weights_only=False)\n    \n    # کنفیگریشن نکالیں\n    model_config = checkpoint.get('model_config', {})\n    training_config = checkpoint.get('training_config', {})\n    \n    # اگر ضرورت ہو تو عالمی کنفیگریشن اپڈیٹ کریں\n    if 'image_size' in training_config:\n        CFG.image_size = training_config['image_size']\n    \n    # ماڈل کو initialize کریں\n    model = MultiBackboneModel(\n        model_name=model_name,\n        num_classes=training_config.get('num_classes', 14),\n        pretrained=False,\n        drop_rate=0.2,   # ڈراپ ریٹ تھوڑا بڑھایا گیا\n        drop_path_rate=0.1  # ڈراپ پاتھ ریٹ بھی تھوڑا بڑھایا گیا\n    )\n    \n    # ویٹس لوڈ کریں\n    model.load_state_dict(checkpoint['model_state_dict'])\n    model = model.to(device)\n    model.eval()\n    \n    print(f\"{model_name} لوڈ ہو گیا بہترین سکور کے ساتھ: {checkpoint.get('best_score', 'N/A'):.4f}\")\n    \n    return model\n\ndef load_models():\n    \"\"\"کنفیگریشن کے مطابق ماڈل لوڈ کریں\"\"\"\n    global MODELS, TRANSFORM, TTA_TRANSFORMS\n    \n    print(\"ماڈلز لوڈ کیے جا رہے ہیں...\")\n    \n    if CFG.use_ensemble:\n        # انسمبل کے لئے سب ماڈل لوڈ کریں\n        for model_name, model_path in MODEL_PATHS.items():\n            try:\n                MODELS[model_name] = load_single_model(model_name, model_path)\n            except Exception as e:\n                print(f\"انتباہ: {model_name} لوڈ نہیں ہو سکا: {e}\")\n    else:\n        # ایک منتخب شدہ ماڈل لوڈ کریں\n        if CFG.model_selection in MODEL_PATHS:\n            model_path = MODEL_PATHS[CFG.model_selection]\n            MODELS[CFG.model_selection] = load_single_model(CFG.model_selection, model_path)\n        else:\n            raise ValueError(f\"نامعلوم ماڈل: {CFG.model_selection}\")\n    \n    # ٹرانسفارمز initialize کریں\n    TRANSFORM = get_inference_transform()\n    if CFG.use_tta:\n        TTA_TRANSFORMS = get_tta_transforms()\n    \n    print(f\"ماڈلز لوڈ ہو گئے: {list(MODELS.keys())}\")\n    \n    # ماڈلز کو وارم اپ کریں\n    print(\"ماڈلز وارم اپ کیے جا رہے ہیں...\")\n    dummy_image = torch.randn(1, 3, CFG.image_size, CFG.image_size).to(device)\n    dummy_meta = torch.randn(1, 2).to(device)\n    \n    with torch.no_grad():\n        for model in MODELS.values():\n            _ = model(dummy_image, dummy_meta)\n    \n    print(\"انفرنس کے لئے تیار!\")","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.108136Z","iopub.execute_input":"2025-08-31T01:37:44.108415Z","iopub.status.idle":"2025-08-31T01:37:44.121765Z","shell.execute_reply.started":"2025-08-31T01:37:44.108364Z","shell.execute_reply":"2025-08-31T01:37:44.121068Z"},"papermill":{"duration":0.012883,"end_time":"2025-07-30T17:08:21.457742","exception":false,"start_time":"2025-07-30T17:08:21.444859","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 7 Functions for Prediction","metadata":{}},{"cell_type":"code","source":"def predict_single_model(model: nn.Module, image: np.ndarray, meta_tensor: torch.Tensor) -> np.ndarray:\n    \"\"\"ایک سنگل ماڈل کے ساتھ پیشن گوئی کریں\"\"\"\n    predictions = []\n    \n    if CFG.use_tta and TTA_TRANSFORMS:\n        # ٹیسٹ ٹائم آگمینٹیشن (TTA)\n        for transform in TTA_TRANSFORMS[:CFG.tta_transforms]:\n            aug_image = transform(image=image)['image']\n            aug_image = aug_image.unsqueeze(0).to(device)\n            \n            with torch.no_grad():\n                with autocast(enabled=CFG.use_amp):\n                    output = model(aug_image, meta_tensor)\n                    pred = torch.sigmoid(output)\n                    predictions.append(pred.cpu().numpy())\n        \n        # TTA نتائج کا اوسط\n        return np.mean(predictions, axis=0).squeeze()\n    else:\n        # سادہ پیشن گوئی\n        image_tensor = TRANSFORM(image=image)['image']\n        image_tensor = image_tensor.unsqueeze(0).to(device)\n        \n        with torch.no_grad():\n            with autocast(enabled=CFG.use_amp):\n                output = model(image_tensor, meta_tensor)\n                return torch.sigmoid(output).cpu().numpy().squeeze()\n\n\ndef predict_ensemble(image: np.ndarray, meta_tensor: torch.Tensor) -> np.ndarray:\n    \"\"\"اینسمبل ماڈلز کے ساتھ پیشن گوئی کریں\"\"\"\n    all_predictions = []\n    weights = []\n    \n    for model_name, model in MODELS.items():\n        pred = predict_single_model(model, image, meta_tensor)\n        all_predictions.append(pred)\n        weights.append(CFG.ensemble_weights.get(model_name, 1.0))\n    \n    # وزن شدہ اوسط\n    weights = np.array(weights) / np.sum(weights)\n    predictions = np.array(all_predictions)\n    \n    return np.average(predictions, weights=weights, axis=0)\n\n\ndef _predict_inner(series_path: str) -> pl.DataFrame:\n    \"\"\"مین پیشن گوئی لاجک (اندرونی فنکشن)\"\"\"\n    global MODELS\n    \n    # اگر ماڈلز لوڈ نہیں ہیں تو انہیں لوڈ کریں\n    if not MODELS:\n        print(\"ماڈلز لوڈ کیے جا رہے ہیں...\")\n        load_models()\n    \n    # سیریز آئی ڈی نکالیں\n    series_id = os.path.basename(series_path)\n    \n    # DICOM سیریز کو پروسیس کریں\n    volume, metadata = process_dicom_series(series_path)\n    \n    # ملٹی چینل ان پٹ تیار کریں\n    middle_slice = volume[CFG.num_slices // 2]\n    mip = np.max(volume, axis=0)\n    std_proj = np.std(volume, axis=0).astype(np.float32)\n    \n    # اسٹینڈرڈ ڈیو پروجیکشن کو نورملائز کریں\n    if std_proj.max() > std_proj.min():\n        std_proj = ((std_proj - std_proj.min()) / (std_proj.max() - std_proj.min()) * 255).astype(np.uint8)\n    else:\n        std_proj = np.zeros_like(std_proj, dtype=np.uint8)\n    \n    image = np.stack([middle_slice, mip, std_proj], axis=-1)\n    \n    # میٹا ڈیٹا تیار کریں\n    age_normalized = metadata['age'] / 100.0  # زیادہ رینج کے لیے نورملائزیشن کو 100 سے 120 پر بدل دیا گیا\n    sex = metadata['sex']\n    meta_tensor = torch.tensor([[age_normalized, sex]], dtype=torch.float32).to(device)\n    \n    # پیشن گوئی کریں\n    if CFG.use_ensemble:\n        print(\"اینسمبل ماڈل سے پیشن گوئی کی جا رہی ہے...\")\n        final_pred = predict_ensemble(image, meta_tensor)\n    else:\n        print(f\"سنگل ماڈل {CFG.model_selection} استعمال ہو رہا ہے...\")\n        model = MODELS[CFG.model_selection]\n        final_pred = predict_single_model(model, image, meta_tensor)\n    \n    # آؤٹ پٹ ڈیٹا فریم بنائیں\n    predictions_df = pl.DataFrame(\n        data=[[series_id] + final_pred.tolist()],\n        schema=[ID_COL] + LABEL_COLS,\n        orient='row'\n    )\n\n    # API کی ضرورت کے مطابق آئی ڈی کالم کو ہٹا دیں\n    return predictions_df.drop(ID_COL)","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.122578Z","iopub.execute_input":"2025-08-31T01:37:44.123028Z","iopub.status.idle":"2025-08-31T01:37:44.141402Z","shell.execute_reply.started":"2025-08-31T01:37:44.123005Z","shell.execute_reply":"2025-08-31T01:37:44.140679Z"},"papermill":{"duration":0.014866,"end_time":"2025-07-30T17:08:21.475187","exception":false,"start_time":"2025-07-30T17:08:21.460321","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 8 Fallback and Error Handling","metadata":{}},{"cell_type":"code","source":"def predict_fallback(series_path: str) -> pl.DataFrame:\n    \"\"\"فالبیک پیش گوئی فنکشن\"\"\"\n    series_id = os.path.basename(series_path)\n    \n    # احتیاطی انداز میں پیش گوئی واپس کریں (کم اعتماد والی)\n    predictions = pl.DataFrame(\n        data=[[series_id] + [0.1] * len(LABEL_COLS)],  # ہائپر پیرامیٹر بدلا: پہلے 0.1 تھا اب 0.05\n        schema=[ID_COL] + LABEL_COLS,\n        orient='row'\n    )\n    \n    # عارضی فولڈرز صاف کریں\n    shutil.rmtree('/kaggle/shared', ignore_errors=True)\n    \n    return predictions.drop(ID_COL)\n\n\ndef predict(series_path: str) -> pl.DataFrame:\n    \"\"\"\n    اوپر کی سطح کا پیش گوئی فنکشن جو سرور کو دیا جاتا ہے۔\n    یہ اصل لاجک کو کال کرتا ہے اور آخر میں صفائی کو یقینی بناتا ہے۔\n    \"\"\"\n    try:\n        # اندرونی پیش گوئی لاجک کو کال کریں\n        return _predict_inner(series_path)\n    except Exception as e:\n        print(f\"پیش گوئی کے دوران خرابی: {os.path.basename(series_path)} - {e}\")\n        print(\"فالبیک پیش گوئی استعمال کی جا رہی ہے۔\")\n        \n        # درست اسکیما کے ساتھ فالبیک ڈیٹافریم واپس کریں\n        predictions = pl.DataFrame(\n            data=[[0.1] * len(LABEL_COLS)],\n            schema=LABEL_COLS,\n            orient='row'\n        )\n        return predictions\n    finally:\n        # ڈسک اسپیس کی کمی یا فولڈر نہ مٹنے کی خرابی سے بچنے کے لیے\n        # شیئرڈ فولڈر کو ڈیلیٹ کرکے دوبارہ بنائیں\n        shared_dir = '/kaggle/shared'\n        shutil.rmtree(shared_dir, ignore_errors=True)\n        os.makedirs(shared_dir, exist_ok=True)\n        \n        # میموری صاف کریں\n        if torch.cuda.is_available():\n            torch.cuda.empty_cache()\n        gc.collect()","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.142204Z","iopub.execute_input":"2025-08-31T01:37:44.142464Z","iopub.status.idle":"2025-08-31T01:37:44.158533Z","shell.execute_reply.started":"2025-08-31T01:37:44.14244Z","shell.execute_reply":"2025-08-31T01:37:44.157878Z"},"papermill":{"duration":0.010205,"end_time":"2025-07-30T17:08:21.488223","exception":false,"start_time":"2025-07-30T17:08:21.478018","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 9 Main Execution","metadata":{}},{"cell_type":"code","source":"load_models()\n\n# ہمارے مرکزی `predict` فنکشن کے ساتھ انفیرینس سرور کو انیشیالائز کریں\ninference_server = kaggle_evaluation.rsna_inference_server.RSNAInferenceServer(predict)\n\n# چیک کریں کہ نوٹ بُک مقابلے کے ماحول میں چل رہا ہے یا مقامی سیشن میں\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway()\n    \n    submission_df = pl.read_parquet('/kaggle/working/submission.parquet')\n    display(submission_df)\n    print(\"سبمشن فائل لوڈ ہو گئی ہے۔\")","metadata":{"execution":{"iopub.status.busy":"2025-08-31T01:37:44.15922Z","iopub.execute_input":"2025-08-31T01:37:44.159487Z","iopub.status.idle":"2025-08-31T01:38:31.258298Z","shell.execute_reply.started":"2025-08-31T01:37:44.159465Z","shell.execute_reply":"2025-08-31T01:38:31.257715Z"},"papermill":{"duration":24.918596,"end_time":"2025-07-30T17:08:46.419293","exception":false,"start_time":"2025-07-30T17:08:21.500697","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # --- ہائپرپیرامیٹرز میں کچھ تبدیلیاں ---\n# CFG.batch_size = 2         # بیچ سائز بڑھا دیا گیا (زیادہ رفتار کے لیے)\n# CFG.image_size = 384       # امیج سائز چھوٹا کیا گیا (کم میموری کے لیے)\n# CFG.num_slices = 48        # سلائسز کی تعداد بڑھائی گئی (زیادہ معلومات کے لیے)\n# CFG.tta_transforms = 8     # TTA ٹرانسفارمز کی تعداد بڑھائی گئی (زیادہ استحکام کے لیے)\n\n# print(\"ہائپرپیرامیٹرز اپڈیٹ ہو گئے ہیں۔\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-31T01:38:31.259808Z","iopub.execute_input":"2025-08-31T01:38:31.260056Z","iopub.status.idle":"2025-08-31T01:38:31.263486Z","shell.execute_reply.started":"2025-08-31T01:38:31.26004Z","shell.execute_reply":"2025-08-31T01:38:31.262698Z"}},"outputs":[],"execution_count":null}]}