{"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":"import os\nprint(os.listdir(\"/kaggle/input/competitions/carvana-image-masking-challenge\"))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:37:19.158319Z","iopub.execute_input":"2026-06-03T06:37:19.158508Z","iopub.status.idle":"2026-06-03T06:37:19.166642Z","shell.execute_reply.started":"2026-06-03T06:37:19.158487Z","shell.execute_reply":"2026-06-03T06:37:19.165869Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!unzip -q /kaggle/input/competitions/carvana-image-masking-challenge/train.zip -d .\n!unzip -q /kaggle/input/competitions/carvana-image-masking-challenge/train_masks.zip -d .","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:37:24.052472Z","iopub.execute_input":"2026-06-03T06:37:24.052817Z","iopub.status.idle":"2026-06-03T06:37:36.437242Z","shell.execute_reply.started":"2026-06-03T06:37:24.052778Z","shell.execute_reply":"2026-06-03T06:37:36.436090Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!unzip -q /kaggle/input/competitions/carvana-image-masking-challenge/test.zip -d .","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:37:40.680169Z","iopub.execute_input":"2026-06-03T06:37:40.680988Z","iopub.status.idle":"2026-06-03T06:41:32.301714Z","shell.execute_reply.started":"2026-06-03T06:37:40.680950Z","shell.execute_reply":"2026-06-03T06:41:32.300571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install segmentation-models-pytorch","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:41:53.068099Z","iopub.execute_input":"2026-06-03T06:41:53.068553Z","iopub.status.idle":"2026-06-03T06:41:56.724030Z","shell.execute_reply.started":"2026-06-03T06:41:53.068516Z","shell.execute_reply":"2026-06-03T06:41:56.722999Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport numpy as np\nfrom PIL import Image\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as transforms\nimport matplotlib.pyplot as plt\n\nclass CarvanaDataset(Dataset):\n    def __init__(self, image_dir, mask_dir):\n        self.image_dir = image_dir\n        self.mask_dir = mask_dir\n        # لیست کردن تصاویر موجود در پوشه train\n        self.images = os.listdir(image_dir)\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, index):\n        img_name = self.images[index]\n        img_path = os.path.join(self.image_dir, img_name)\n        \n        # پیدا کردن ماسک متناظر\n        mask_name = img_name.replace(\".jpg\", \"_mask.gif\")\n        mask_path = os.path.join(self.mask_dir, mask_name)\n\n        # باز کردن تصاویر\n        image = Image.open(img_path).convert(\"RGB\")\n        mask = Image.open(mask_path).convert(\"L\")\n\n        # تغییر سایز برای افزایش سرعت یادگیری در اجرای اول\n        image = image.resize((256, 256))\n        mask = mask.resize((256, 256))\n\n        # نرمال‌سازی و تبدیل به آرایه\n        image = np.array(image, dtype=np.float32) / 255.0\n        mask = np.array(mask, dtype=np.float32) / 255.0\n        \n        # تبدیل به تنسور پایتورچ\n        image = transforms.ToTensor()(image)\n        mask = transforms.ToTensor()(mask)\n            \n        return image, mask\n\n# آدرس پوشه‌های آنزیپ شده در محیط محلی کگل\nIMAGE_DIR = \"./train\"\nMASK_DIR = \"./train_masks\"\n\n# ساخت دیتالودر\ndataset = CarvanaDataset(image_dir=IMAGE_DIR, mask_dir=MASK_DIR)\ntrain_loader = DataLoader(dataset, batch_size=8, shuffle=True)\n\n# تست و نمایش خروجی\nimages, masks = next(iter(train_loader))\nprint(\"تنسور تصاویر:\", images.shape)\nprint(\"تنسور ماسک‌ها:\", masks.shape)\n\nfig, ax = plt.subplots(1, 2, figsize=(10, 5))\nax[0].imshow(images[0].permute(1, 2, 0))\nax[0].set_title(\"Original Car Image\")\nax[1].imshow(masks[0].squeeze(), cmap=\"gray\")\nax[1].set_title(\"Ground Truth Mask\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:42:06.118047Z","iopub.execute_input":"2026-06-03T06:42:06.118539Z","iopub.status.idle":"2026-06-03T06:42:19.826400Z","shell.execute_reply.started":"2026-06-03T06:42:06.118503Z","shell.execute_reply":"2026-06-03T06:42:19.825710Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import segmentation_models_pytorch as smp\nimport torch.optim as optim\nimport torch.nn as nn\nimport torch\n\n# 1. Definition of the model using SMP\nmodel = smp.Unet(\n    encoder_name=\"resnet34\",        \n    encoder_weights=\"imagenet\",     \n    in_channels=3,                  \n    classes=1,                      \n)\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n\n# 2. Loss and Optimizer\ncriterion = smp.losses.DiceLoss(mode='binary')\noptimizer = optim.Adam(model.parameters(), lr=1e-4)\n\n# 3. Training Loop (1 Epoch for testing)\nEPOCHS = 1\n\nprint(\"Starting training...\")\nmodel.train()\nfor epoch in range(EPOCHS):\n    running_loss = 0.0\n    for i, (images, masks) in enumerate(train_loader):\n        images, masks = images.to(device), masks.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, masks)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        \n        if (i+1) % 10 == 0:\n            print(f\"Batch {i+1}, Loss: {loss.item():.4f}\")\n\n    print(f\"Epoch {epoch+1} finished. Avg Loss: {running_loss/len(train_loader):.4f}\")\n\nprint(\"Training completed successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:42:26.811542Z","iopub.execute_input":"2026-06-03T06:42:26.812587Z","iopub.status.idle":"2026-06-03T06:48:17.566013Z","shell.execute_reply.started":"2026-06-03T06:42:26.812553Z","shell.execute_reply":"2026-06-03T06:48:17.565295Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# این کد را در یک سلول جدید بنویس ولی تا پایان آموزش قبلی اجرا نکن\nimport matplotlib.pyplot as plt\n\n# تغییر حالت مدل به ارزیابی (Evaluation Mode)\nmodel.eval()\n\n# گرفتن یک عکس تست از دیتالودر\nwith torch.no_grad():\n    test_images, test_masks = next(iter(train_loader))\n    test_images, test_masks = test_images.to(device), test_masks.to(device)\n    \n    # پیش‌بینی مدل\n    predictions = model(test_images)\n    # اعمال تابع سیگموئید برای تبدیل خروجی به احتمالات بین 0 و 1\n    predictions = torch.sigmoid(predictions) \n\n# انتقال داده‌ها به سی‌پی‌یو برای نمایش تصویری\nimg = test_images[0].cpu().permute(1, 2, 0)\ntrue_mask = test_masks[0].cpu().squeeze()\npred_mask = predictions[0].cpu().squeeze()\n\n# آستانه‌گذاری روی پیش‌بینی (پیکسل‌های بالای 0.5 سفید و بقیه سیاه)\nbinary_pred_mask = (pred_mask > 0.5).float()\n\n# نمایش همزمان عکس اصلی، ماسک واقعی و ماسک پیش‌بینی شده توسط مدل تو\nfig, ax = plt.subplots(1, 3, figsize=(15, 5))\nax[0].imshow(img)\nax[0].set_title(\"Original Car\")\nax[1].imshow(true_mask, cmap=\"gray\")\nax[1].set_title(\"Real Mask (Ground Truth)\")\nax[2].imshow(binary_pred_mask, cmap=\"gray\")\nax[2].set_title(\"Model's Prediction\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:48:25.263555Z","iopub.execute_input":"2026-06-03T06:48:25.264368Z","iopub.status.idle":"2026-06-03T06:48:26.101824Z","shell.execute_reply.started":"2026-06-03T06:48:25.264323Z","shell.execute_reply":"2026-06-03T06:48:26.101225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport torch\nimport os\nfrom PIL import Image\nimport numpy as np\nimport torchvision.transforms as transforms\n\n# ۱. تابع تبدیل ماسک به فرمت RLE که کگل درخواست می‌کند\ndef rle_encode(mask):\n    pixels = mask.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[0::-2]\n    return ' '.join(str(x) for x in runs)\n\n# ۲. خواندن چند نمونه از فایل‌های تست برای ساخت فایل نمونه\ntest_dir = \"./test\"\n# برای تست سریع، فقط روی ۵۰ عکس اول فولدر تست خروجی می‌گیریم\ntest_images = os.listdir(test_dir)[:50] \n\nmodel.eval()\nrle_results = []\nimg_ids = []\n\nprint(\"در حال پیش‌بینی روی داده‌های تست...\")\nwith torch.no_grad():\n    for img_name in test_images:\n        img_path = os.path.join(test_dir, img_name)\n        img = Image.open(img_path).convert(\"RGB\").resize((256, 256))\n        \n        # تبدیل به تنسور و انتقال به GPU\n        img_tensor = transforms.ToTensor()(img).unsqueeze(0).to(device)\n        \n        # پیش‌بینی مدل\n        pred = model(img_tensor)\n        pred = torch.sigmoid(pred).squeeze().cpu().numpy()\n        \n        # تبدیل به ماسک باینری (۰ و ۱)\n        binary_pred = (pred > 0.5).astype(np.uint8)\n        \n        # برگرداندن به سایز اصلی مسابقه (1280x1918) برای امتیازدهی درست\n        binary_pred_resized = np.array(Image.fromarray(binary_pred).resize((1918, 1280), resample=Image.NEAREST))\n        \n        # تبدیل به RLE\n        rle = rle_encode(binary_pred_resized)\n        \n        rle_results.append(rle)\n        img_ids.append(img_name)\n\n# ۳. ذخیره نتایج در فایل CSV\nsubmission_df = pd.DataFrame({\n    'img': img_ids,\n    'rle_mask': rle_results\n})\nsubmission_df.to_csv('submission.csv', index=False)\nprint(\"فایل submission.csv با موفقیت ساخته شد!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-03T06:48:38.109676Z","iopub.execute_input":"2026-06-03T06:48:38.110409Z","iopub.status.idle":"2026-06-03T06:48:41.558285Z","shell.execute_reply.started":"2026-06-03T06:48:38.110377Z","shell.execute_reply":"2026-06-03T06:48:41.557453Z"}},"outputs":[],"execution_count":null}]}