{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":113558,"databundleVersionId":14174843,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    👋 Greetings to all!\n</h1>\n\n<div style=\"\n    background: rgba(53, 141, 230, 0.1);\n    border-left: 4px solid #358de6;\n    border-radius: 8px;\n    padding: 20px;\n    margin: 20px 0;\n    position: relative;\n    z-index: 1;\n\">\n    <h3 style=\"\n        color: #358de6;\n        margin-top: 0;\n        font-size: 1.3em;\n        display: flex;\n        align-items: center;\n        gap: 10px;\n    \">\n        🎯 What can be improved:\n    </h3>\n    <ul style=\"\n        color: #f1f5f9;\n        font-size: 1.1em;\n        line-height: 1.6;\n        margin-bottom: 0;\n    \">\n        <li>Download ultralytics and numpy dependencies and import the finished <a href=\"https://www.kaggle.com/models/ultralytics/yolo11-seg\" style=\"color: #a3d5ff; text-decoration: none; font-weight: 600;\">YOLO11 model</a></li>\n        <li>Don't forget to turn off the Internet❗</li>\n        <li>Improve the parameters for training. I have a full guide in my profile, the notebook starts with ⭐.</li>\n        <li>Take a different approach</li>\n        <li>make improvements because the images are of different sizes</li>\n    </ul>\n</div>\n\n<p style=\"\n    text-align: center; \n    font-size: 1.1em;\n    margin: 25px 0 0 0;\n    position: relative;\n    z-index: 1;\n    font-weight: 500;\n    color: #a3d5ff;\n\">\n    Good luck in improving! 🚀\n</p>","metadata":{}},{"cell_type":"code","source":"import os\n\nos.makedirs('/kaggle/working/ultralytics', exist_ok=True)\n\n!pip download ultralytics \"numpy<2\" --dest /kaggle/working/ultralytics","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:31:28.799409Z","iopub.execute_input":"2025-11-02T09:31:28.799864Z","iopub.status.idle":"2025-11-02T09:32:55.883217Z","shell.execute_reply.started":"2025-11-02T09:31:28.799839Z","shell.execute_reply":"2025-11-02T09:32:55.882181Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install --no-index --find-links /kaggle/working/ultralytics ultralytics \"numpy<2\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:32:55.884713Z","iopub.execute_input":"2025-11-02T09:32:55.885007Z","iopub.status.idle":"2025-11-02T09:35:18.741506Z","shell.execute_reply.started":"2025-11-02T09:32:55.884981Z","shell.execute_reply":"2025-11-02T09:35:18.740802Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Import libs\n</h1>","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport json\nimport yaml\nimport torch\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom PIL import Image\nfrom tqdm import tqdm\nfrom pathlib import Path\nfrom ultralytics import YOLO\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:18.742486Z","iopub.execute_input":"2025-11-02T09:35:18.742728Z","iopub.status.idle":"2025-11-02T09:35:21.833739Z","shell.execute_reply.started":"2025-11-02T09:35:18.742705Z","shell.execute_reply":"2025-11-02T09:35:21.833182Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Main paths\n</h1>","metadata":{}},{"cell_type":"code","source":"train_authentic = '/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/authentic'\ntrain_forged = '/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_images/forged'\ntrain_masks = '/kaggle/input/recodai-luc-scientific-image-forgery-detection/train_masks'\n\ntest_images = '/kaggle/input/recodai-luc-scientific-image-forgery-detection/test_images'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:21.835198Z","iopub.execute_input":"2025-11-02T09:35:21.835490Z","iopub.status.idle":"2025-11-02T09:35:21.839036Z","shell.execute_reply.started":"2025-11-02T09:35:21.835475Z","shell.execute_reply":"2025-11-02T09:35:21.838285Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Create paths for learning yolo\n</h1>","metadata":{}},{"cell_type":"code","source":"output_dir = '/kaggle/working/yolo_dataset'\nimages_dir = os.path.join(output_dir, 'images')\nlabels_dir = os.path.join(output_dir, 'labels')\n\nos.makedirs(os.path.join(images_dir, 'train'), exist_ok=True)\nos.makedirs(os.path.join(images_dir, 'val'), exist_ok=True)\nos.makedirs(os.path.join(labels_dir, 'train'), exist_ok=True)\nos.makedirs(os.path.join(labels_dir, 'val'), exist_ok=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:21.839678Z","iopub.execute_input":"2025-11-02T09:35:21.839895Z","iopub.status.idle":"2025-11-02T09:35:21.856417Z","shell.execute_reply.started":"2025-11-02T09:35:21.839879Z","shell.execute_reply":"2025-11-02T09:35:21.855923Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Read images into a single sample. Set is_forged=False for authentic images (images without a mask)\n</h1>","metadata":{}},{"cell_type":"code","source":"samples = []\nimg_size = 640\n\n# Authentic images\nauthentic_files = [f for f in os.listdir(train_authentic) if f.endswith(('.png', '.jpg', '.jpeg'))]\nprint(f\"Found {len(authentic_files)} authentic images\")\n\nfor file in authentic_files:\n    img_path = os.path.join(train_authentic, file)\n    base_name = os.path.splitext(file)[0]\n    \n    samples.append({\n        'image_path': img_path,\n        'mask_path': None,\n        'is_forged': False,\n        'image_id': base_name\n    })\n\n# Forged images\nforged_files = [f for f in os.listdir(train_forged) if f.endswith(('.png', '.jpg', '.jpeg'))]\nprint(f\"Found {len(forged_files)} forged images\")\n\nfor file in forged_files:\n    img_path = os.path.join(train_forged, file)\n    base_name = os.path.splitext(file)[0]\n    mask_path = os.path.join(train_masks, f\"{base_name}.npy\")\n    \n    samples.append({\n        'image_path': img_path,\n        'mask_path': mask_path,\n        'is_forged': True,\n        'image_id': base_name\n    })\n\nprint(f\"Total samples: {len(samples)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:21.857127Z","iopub.execute_input":"2025-11-02T09:35:21.857374Z","iopub.status.idle":"2025-11-02T09:35:21.931179Z","shell.execute_reply.started":"2025-11-02T09:35:21.857352Z","shell.execute_reply":"2025-11-02T09:35:21.930619Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Split into train/val\ntrain_samples, val_samples = train_test_split(\n    samples, test_size=0.1, random_state=42, \n    stratify=[s['is_forged'] for s in samples]\n)\n\nprint(f\"Train samples: {len(train_samples)}\")\nprint(f\"Val samples: {len(val_samples)}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:21.931822Z","iopub.execute_input":"2025-11-02T09:35:21.932040Z","iopub.status.idle":"2025-11-02T09:35:21.951330Z","shell.execute_reply.started":"2025-11-02T09:35:21.932017Z","shell.execute_reply":"2025-11-02T09:35:21.950788Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Save images and masks in output directory\n</h1>","metadata":{}},{"cell_type":"code","source":"for sample in tqdm(train_samples):\n    image_id = sample['image_id']\n    \n    # Resize and save image\n    img = Image.open(sample['image_path']).convert('RGB')\n    img_resized = img.resize((img_size, img_size), Image.Resampling.LANCZOS)\n    img_save_path = os.path.join(images_dir, 'train', f\"{image_id}.jpg\")\n    img_resized.save(img_save_path, 'JPEG', quality=95)\n    \n    # Create label file\n    label_path = os.path.join(labels_dir, 'train', f\"{image_id}.txt\")\n    \n    if sample['is_forged'] and sample['mask_path'] and os.path.exists(sample['mask_path']):\n        # Load and process mask\n        mask = np.load(sample['mask_path'])\n        \n        # Handle multi-channel masks\n        if mask.ndim == 3:\n            if mask.shape[0] <= 10:\n                mask = np.any(mask, axis=0)\n            elif mask.shape[-1] <= 10:\n                mask = np.any(mask, axis=-1)\n            else:\n                mask = mask[0] if mask.shape[0] <= 10 else mask[:, :, 0]\n        \n        mask = (mask > 0).astype(np.uint8)\n        \n        if mask.sum() > 0:\n            # Resize mask\n            mask_resized = cv2.resize(mask, (img_size, img_size), interpolation=cv2.INTER_NEAREST)\n            \n            # Convert to YOLO format\n            contours, _ = cv2.findContours(mask_resized, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n            \n            annotations = []\n            for contour in contours:\n                if len(contour) > 0:\n                    x, y, w, h = cv2.boundingRect(contour)\n                    if w > 5 and h > 5:\n                        # Normalize coordinates\n                        normalized_contour = contour.astype(np.float32)\n                        normalized_contour[:, :, 0] /= img_size\n                        normalized_contour[:, :, 1] /= img_size\n                        \n                        # Create annotation string\n                        points = normalized_contour.reshape(-1, 2)\n                        points_str = ' '.join([f'{x:.6f} {y:.6f}' for x, y in points])\n                        annotation = f\"0 {points_str}\"\n                        annotations.append(annotation)\n            \n            # Save annotations\n            with open(label_path, 'w') as f:\n                for annotation in annotations:\n                    f.write(annotation + '\\n')\n            continue\n    \n    # Create empty file for authentic images or images without masks\n    open(label_path, 'w').close()\n\nfor sample in tqdm(val_samples):\n    image_id = sample['image_id']\n    \n    # Resize and save image\n    img = Image.open(sample['image_path']).convert('RGB')\n    img_resized = img.resize((img_size, img_size), Image.Resampling.LANCZOS)\n    img_save_path = os.path.join(images_dir, 'val', f\"{image_id}.jpg\")\n    img_resized.save(img_save_path, 'JPEG', quality=95)\n    \n    # Create label file\n    label_path = os.path.join(labels_dir, 'val', f\"{image_id}.txt\")\n    \n    if sample['is_forged'] and sample['mask_path'] and os.path.exists(sample['mask_path']):\n        # Load and process mask\n        mask = np.load(sample['mask_path'])\n        \n        # Handle multi-channel masks\n        if mask.ndim == 3:\n            if mask.shape[0] <= 10:\n                mask = np.any(mask, axis=0)\n            elif mask.shape[-1] <= 10:\n                mask = np.any(mask, axis=-1)\n            else:\n                mask = mask[0] if mask.shape[0] <= 10 else mask[:, :, 0]\n        \n        mask = (mask > 0).astype(np.uint8)\n        \n        if mask.sum() > 0:\n            # Resize mask\n            mask_resized = cv2.resize(mask, (img_size, img_size), interpolation=cv2.INTER_NEAREST)\n            \n            # Convert to YOLO format\n            contours, _ = cv2.findContours(mask_resized, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n            \n            annotations = []\n            for contour in contours:\n                if len(contour) > 0:\n                    x, y, w, h = cv2.boundingRect(contour)\n                    if w > 5 and h > 5:\n                        # Normalize coordinates\n                        normalized_contour = contour.astype(np.float32)\n                        normalized_contour[:, :, 0] /= img_size\n                        normalized_contour[:, :, 1] /= img_size\n                        \n                        # Create annotation string\n                        points = normalized_contour.reshape(-1, 2)\n                        points_str = ' '.join([f'{x:.6f} {y:.6f}' for x, y in points])\n                        annotation = f\"0 {points_str}\"\n                        annotations.append(annotation)\n            \n            # Save annotations\n            with open(label_path, 'w') as f:\n                for annotation in annotations:\n                    f.write(annotation + '\\n')\n            continue\n    \n    # Create empty file for authentic images or images without masks\n    open(label_path, 'w').close()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:35:21.952072Z","iopub.execute_input":"2025-11-02T09:35:21.952330Z","iopub.status.idle":"2025-11-02T09:41:22.784989Z","shell.execute_reply.started":"2025-11-02T09:35:21.952313Z","shell.execute_reply":"2025-11-02T09:41:22.784401Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Create YAML config\ndata_yaml = f\"\"\"\npath: {output_dir}\n\ntrain: images/train\nval: images/val\n\nnames:\n  0: forgery\n\"\"\"\n\nwith open('data.yaml', 'w') as file:\n    file.write(data_yaml)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:41:22.785802Z","iopub.execute_input":"2025-11-02T09:41:22.786076Z","iopub.status.idle":"2025-11-02T09:41:22.790693Z","shell.execute_reply.started":"2025-11-02T09:41:22.786050Z","shell.execute_reply":"2025-11-02T09:41:22.789965Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    Learn Yolo11n(small) model\n</h1>","metadata":{}},{"cell_type":"code","source":"model = YOLO('yolo11x-seg.pt')\n\nresults = model.train(\n    data='data.yaml',\n    epochs=50,\n    imgsz=img_size, # 640\n    batch=16,\n    device=[0,1] if torch.cuda.is_available() else 'cpu',\n    \n    optimizer='Adam',\n    lr0=0.001,\n    lrf=0.01,\n    momentum=0.9,\n    weight_decay=0.05,\n    \n    warmup_epochs=3.0,\n    warmup_momentum=0.8,\n    warmup_bias_lr=0.1,\n    \n    hsv_h=0.015,\n    hsv_s=0.7,\n    hsv_v=0.4,\n    degrees=45.0,\n    translate=0.2,\n    scale=0.5,\n    shear=0.0,\n    perspective=0.0001,\n    flipud=0.0,\n    fliplr=0.5,\n    mosaic=1.0,\n    mixup=0.1,\n    copy_paste=0.1,\n    \n    box=7.5,\n    cls=0.5,\n    dfl=1.5,\n    mask_ratio=4,\n    overlap_mask=True,\n    \n    save=True,\n    save_period=5,\n    cache=False,\n    workers=8,\n    single_cls=False,\n    rect=False,\n    cos_lr=False,\n    close_mosaic=10,\n    \n    seed=42,\n    deterministic=True,\n    val=True,\n    plots=True,\n    patience=50\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:41:22.792814Z","iopub.execute_input":"2025-11-02T09:41:22.793023Z","iopub.status.idle":"2025-11-02T09:45:51.575358Z","shell.execute_reply.started":"2025-11-02T09:41:22.793008Z","shell.execute_reply":"2025-11-02T09:45:51.574552Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<div style=\"\n    background: linear-gradient(135deg, #0c1f2f 0%, #1a3a4a 50%, #1a2f4a 100%);\n    border: 2px solid #358de6;\n    border-radius: 15px;\n    padding: 25px;\n    margin: 20px 0;\n    box-shadow: 0 0 30px rgba(53, 141, 230, 0.4),\n                inset 0 0 20px rgba(255, 255, 255, 0.1);\n    color: #f1f5f9;\n    font-family: 'Segoe UI', system-ui, sans-serif;\n    position: relative;\n    overflow: hidden;\n\">\n\n<div style=\"\n    position: absolute;\n    top: -20px;\n    right: -20px;\n    width: 100px;\n    height: 100px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.25) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<div style=\"\n    position: absolute;\n    bottom: -40px;\n    left: -40px;\n    width: 120px;\n    height: 120px;\n    background: radial-gradient(circle, rgba(53, 141, 230, 0.2) 0%, transparent 70%);\n    border-radius: 50%;\n\"></div>\n\n<h1 style=\"\n    color: #358de6;\n    margin: 0 0 20px 0;\n    text-align: center;\n    font-weight: 700;\n    font-size: 1.8em;\n    text-shadow: 0 0 15px rgba(53, 141, 230, 0.6);\n    position: relative;\n    z-index: 1;\n\">\n    🔥 Check our results\n</h1>","metadata":{}},{"cell_type":"code","source":"def visualize_predictions(model, image_dir, counts=5, conf_threshold=0.1):\n    image_paths = list(Path(image_dir).glob('*.*'))\n    image_paths = [p for p in image_paths if p.suffix.lower() in {'.png', '.jpg', '.jpeg'}]\n    \n    if not image_paths:\n        print(\"No images found in\", image_dir)\n        return\n    \n    image_paths = image_paths[:counts]\n    \n    for img_path in image_paths:\n        # load images\n        img = cv2.imread(str(img_path))\n        if img is None:\n            continue\n        img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        h, w = img.shape[:2]\n        \n        # predict\n        result = model.predict(\n            source=img_rgb,\n            imgsz=img_size, # 512\n            conf=conf_threshold,\n            iou=0.45,\n            verbose=False\n        )[0]\n        \n        # create mask\n        mask_vis = np.zeros((h, w), dtype=np.uint8)\n        if result.masks is not None:\n            for mask_tensor in result.masks.data:\n                mask = mask_tensor.cpu().numpy()\n                mask_resized = cv2.resize(mask, (w, h), interpolation=cv2.INTER_NEAREST)\n                mask_vis = np.maximum(mask_vis, (mask_resized > 0.5).astype(np.uint8))\n        \n        plt.figure(figsize=(10, 5))\n        plt.subplot(1, 2, 1)\n        plt.imshow(img_rgb)\n        plt.title(f\"{img_path.name}\")\n        plt.axis('off')\n        \n        plt.subplot(1, 2, 2)\n        plt.imshow(mask_vis, cmap='gray')\n        plt.title(\"Predicted Mask\")\n        plt.axis('off')\n        \n        plt.tight_layout()\n        plt.show()\n\nvisualize_predictions(model, image_dir=train_forged, counts=3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-02T09:45:51.576427Z","iopub.execute_input":"2025-11-02T09:45:51.576620Z","iopub.status.idle":"2025-11-02T09:45:54.305937Z","shell.execute_reply.started":"2025-11-02T09:45:51.576607Z","shell.execute_reply":"2025-11-02T09:45:54.305070Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}