{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# استيراد المكتبات اللازمة\nimport pandas as pd\nimport numpy as np\nimport cv2\nimport os\n\n# استيراد مكتبة Albumentations لمعالجة الصور وتحسينها\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\n\n# استيراد مكتبات PyTorch للعمل مع الشبكات العصبية\nimport torch\nimport torchvision\nfrom torchvision.ops import box_iou, MultiScaleRoIAlign\nfrom torchvision import models\n\n# استيراد العناصر ذات الصلة لنموذج Faster R-CNN\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\n\n# استيراد عناصر البيانات والتحميل والمقايس\nfrom torch.utils.data import DataLoader, Dataset\nimport pytorch_lightning as pl\nfrom pytorch_lightning.metrics import AveragePrecision\n\n# تحديد قيمة البذرة للتكرارية لضمان تكرارية النتائج\nSEED = 2484\n\n# تحديد الجهاز المستخدم (GPU إذا متاح)\nDEVICE = torch.device('cuda')\n\n# تحديد البذرة للعمليات العشوائية في PyTorch ومكتبات أخرى\npl.utilities.seed.seed_everything(SEED)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class VBDDataset(Dataset):\n    def __init__(self, dataframe, image_dir, transforms=None, phase='train'):\n        super().__init__()\n\n        # قائمة بمعرفات الصور المتاحة في البيانات\n        self.image_ids = dataframe['image_id'].unique()\n        self.df = dataframe\n        self.image_dir = image_dir\n        self.transforms = transforms\n        self.phase = phase\n\n    def __getitem__(self, idx):\n        # استخراج معرف الصورة\n        image_id = self.image_ids[idx]\n        records = self.df[self.df['image_id'] == image_id]\n\n        # قراءة الصورة وتحويلها إلى الصيغة المناسبة\n        image = cv2.imread(f'{self.image_dir}/{image_id}.png', cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image /= 255.0\n\n        # إذا كانت المرحلة هي \"test\"، قم بتطبيق التحويلات إذا تم توفرها وإرجاع الصورة مع معرفها\n        if self.phase == 'test':\n            if self.transforms:\n                sample = {\n                    'image': image,\n                }\n                sample = self.transforms(**sample)\n                image = sample['image']\n            return image, image_id\n\n        # إذا كانت المرحلة مختلفة عن \"test\" (على سبيل المثال، \"train\")، قم بتجهيز بيانات الصناديق والتصنيفات\n        boxes = records[['x_min', 'y_min', 'x_max', 'y_max']].values\n        \n        # حساب مساحة الصناديق\n        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0])\n        area = torch.as_tensor(area, dtype=torch.float32)\n        \n        # تعيين التصنيفات (مع تعديل بسيط للتوافق مع التصنيف بالمؤشر 0 للخلفية)\n        labels = torch.squeeze(torch.as_tensor((records.class_id.values+1,), dtype=torch.int64))\n        iscrowd = torch.zeros((records.shape[0],), dtype=torch.int64)\n        \n        # تجهيز البيانات المستهدفة لنموذج Faster R-CNN\n        target = {}\n        target['boxes'] = boxes\n        target['labels'] = labels\n        target['area'] = area\n        target['image_id'] = torch.tensor([idx])\n        target['iscrowd'] = iscrowd\n        \n        # إذا كانت هناك تحويلات، قم بتطبيقها على الصورة وتحديث بيانات الصناديق\n        if self.transforms:\n            sample = {\n                'image': image,\n                'bboxes': target['boxes'],\n                'labels': labels\n            }\n            sample = self.transforms(**sample)\n            image = sample['image']\n            \n            target['boxes'] = torch.as_tensor(sample['bboxes'])\n\n        return image, target\n\n    def __len__(self):\n        # عدد الصور المتاحة في مجموعة البيانات\n        return self.image_ids.shape[0]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# وظيفة للحصول على تحويلات لتدريب البيانات\ndef get_train_transform():\n    return A.Compose([\n        A.Flip(0.5),  # تدوير الصور بزاوية 50% (اعتمادًا على الاحتمال)\n        ToTensorV2(p=1.0)  # تحويل الصورة إلى تنسور بصيغة PyTorch\n    ], bbox_params={'format': 'pascal_voc', 'label_fields': ['labels']})\n\n# وظيفة للحصول على تحويلات للتقييم (الاختبار)\ndef get_valid_transform():\n    return A.Compose([\n        ToTensorV2(p=1.0)  # تحويل الصورة إلى تنسور بصيغة PyTorch\n    ])\n\n# وظيفة لجمع الدُفعات (batches) من البيانات\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\n# وظيفة لتنسيق سلسلة النتائج المتوقعة من النموذج Faster R-CNN\ndef format_prediction_string(labels, boxes, scores):\n    pred_strings = []\n    for j in zip(labels, scores, boxes):\n        pred_strings.append(\"{0} {1:.4f} {2} {3} {4} {5}\".format(\n            j[0], j[1], j[2][0], j[2][1], j[2][2], j[2][3]))\n    return \" \".join(pred_strings)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class VinDetector(pl.LightningModule):\n    def __init__(self, **kwargs):\n        super().__init__()\n\n        # تحميل نموذج Faster R-CNN مع تغيير عدد الفئات\n        self.model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\n        num_classes = 15\n        in_features = self.model.roi_heads.box_predictor.cls_score.in_features\n        self.model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n        \n        # تحديد معدل التعلم وحجم الدُفعة (batch size)\n        self.learning_rate = 1e-3\n        self.batch_size = 4\n\n    def forward(self, x):\n        return self.model(x)\n\n    def prepare_data(self):\n        # قراءة البيانات من ملف CSV وتهيئة مجموعة البيانات للتدريب\n        df = pd.read_csv('../input/vinbigdata-chest-xray-abnormalities-detection/train.csv')\n        df = df[df['class_id'] != 14].reset_index(drop=True)\n        self.train_dataset = VBDDataset(df, '../input/vinbigdata-chest-xray-original-png/train', get_train_transform())\n\n    def train_dataloader(self):\n        # إعداد مولد البيانات للتدريب\n        return DataLoader(self.train_dataset, batch_size=self.batch_size, shuffle=True, pin_memory=True, num_workers=4, collate_fn=collate_fn)\n\n    def training_step(self, batch, batch_idx):\n        images, targets = batch\n        targets = [{k: v for k, v in t.items()} for t in targets]\n        \n        # حساب الخسارة وتسجيلها\n        loss_dict = self.model(images, targets)\n        loss = sum(loss for loss in loss_dict.values())\n        self.log('Loss', loss, on_step=True, on_epoch=True, prog_bar=True)\n        return {\"loss\": loss}\n\n    def configure_optimizers(self):\n        # تكوين المحسن والمجدول (optimizer and scheduler)\n        optimizer = torch.optim.SGD(self.model.parameters(), lr=self.learning_rate, momentum=0.95, weight_decay=1e-5, nesterov=True)\n        scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=6, eta_min=0, verbose=True)\n        return [optimizer], [scheduler]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# إنشاء نموذج VinDetector\nnet = VinDetector()\n\n# تكوين معلم التدريب (trainer) وبدء التدريب لمدة 5 حلقات (epochs) باستخدام وحدة المعالجة الرسومية (GPU) الواحدة\ntrainer = pl.Trainer(max_epochs=5, gpus=1, progress_bar_refresh_rate=100)\ntrainer.fit(net)\n\n# تمكين تدريب جميع الطبقات في النموذج\nfor p in net.model.parameters():\n    p.requires_grad = True\n\n# مواصلة التدريب لمدة 5 حلقات إضافية باستخدام دقة 16 بت\ntrainer = pl.Trainer(max_epochs=5, gpus=1, progress_bar_refresh_rate=50, precision=16)\ntrainer.fit(net)","metadata":{},"execution_count":null,"outputs":[]}],"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}}