{"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":"gpu","dataSources":[{"sourceId":117682,"databundleVersionId":15062069,"sourceType":"competition"},{"sourceId":14591369,"sourceType":"datasetVersion","datasetId":9276509}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-28T19:06:24.627588Z","iopub.execute_input":"2026-01-28T19:06:24.627816Z","iopub.status.idle":"2026-01-28T19:06:25.70325Z","shell.execute_reply.started":"2026-01-28T19:06:24.627794Z","shell.execute_reply":"2026-01-28T19:06:25.702701Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"This is test (vibe coding) fir PIX2PIX . All credits go tho PIX2PIX authors.\nI've used default resolution i order to see if has an impact on training results.\n\nAt a first glance: smaller is better. 400-5000 random samples vs full dataset. ","metadata":{}},{"cell_type":"markdown","source":"# Test for resnet_9blocks --netD pixel","metadata":{}},{"cell_type":"code","source":"import os\nimport random\nimport glob\nimport subprocess\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport numpy as np\nimport re\nimport time\n\n# --- SCALE CONFIGURATION ---\nDATASET_ROOT = '/kaggle/input/vesuvius-image-slices/single_channel_data/train/'\nPOC_DIR = '/kaggle/working/datasets/vesuvius_large'\nMODEL_NAME = 'vesuvius_pix2pix_2k'\nTRAIN_SIZE = 20000  \nTEST_SIZE = 20     \n\ndef initialize_environment():\n    print(\"--- 0. Initializing Environment ---\")\n    repo_dir = \"pytorch-CycleGAN-and-pix2pix\"\n    if not os.path.exists(repo_dir):\n        subprocess.run([\"git\", \"clone\", \"https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix\"], check=True)\n    os.chdir(repo_dir)\n    subprocess.run([\"pip\", \"-q\", \"install\", \"dominate\"], check=True)\n\ndef setup_large_dataset():\n    print(f\"\\n--- 1. Preparing Large Dataset ({TRAIN_SIZE} files) ---\")\n    base_poc = os.path.abspath(POC_DIR)\n    if os.path.exists(base_poc):\n        import shutil\n        shutil.rmtree(base_poc)\n        \n    for folder in ['train', 'test']:\n        os.makedirs(os.path.join(base_poc, folder), exist_ok=True)\n\n    all_images = glob.glob(os.path.join(DATASET_ROOT, '*.png'))\n    random.shuffle(all_images)\n    \n    # Cap at TRAIN_SIZE or total available\n    actual_train_size = min(TRAIN_SIZE, len(all_images) - TEST_SIZE)\n    \n    for img in all_images[:actual_train_size]:\n        os.symlink(img, os.path.join(base_poc, 'train', os.path.basename(img)))\n    for img in all_images[actual_train_size:actual_train_size+TEST_SIZE]:\n        os.symlink(img, os.path.join(base_poc, 'test', os.path.basename(img)))\n    print(f\"✅ Dataset Prepared. Train: {actual_train_size}, Test: {TEST_SIZE}\")\n\ndef run_large_training():\n    print(f\"\\n--- 2. Starting Large-Scale Training ---\")\n    # Using 3 epochs + 3 decay epochs for a total of 6 passes over 2000 images.\n    # This should stay within Kaggle time limits while providing deep learning.\n    cmd = (\n        f\"python train.py \"\n        f\"--dataroot {os.path.abspath(POC_DIR)} \"\n        f\"--name {MODEL_NAME} \"\n        f\"--model pix2pix \"\n        f\"--direction BtoA \"\n        f\"--netG unet_256 \"          # Changed from resnet to unet\n        f\"--norm instance \"          # Ensure instance norm for stability\n        f\"--input_nc 3 --output_nc 3 \"\n        f\"--load_size 256 --crop_size 256 \" # Increased resolution helps with fine ink\n        f\"--batch_size 4 \"           # Reduced for better Instance Norm effect\n        f\"--n_epochs 15 \"            \n        f\"--n_epochs_decay 15 \"      # Longer decay period\n        f\"--lr 0.0002 \"\n        f\"--lambda_L1 150 \"          # Stronger weight on ink matching\n        f\"--save_epoch_freq 5 \"\n        f\"--no_html\"\n    )\n    os.system(cmd)\n\ndef plot_loss():\n    print(f\"\\n--- 3. Plotting Final Convergence ---\")\n    log_path = f'checkpoints/{MODEL_NAME}/loss_log.txt'\n    if not os.path.exists(log_path): return\n\n    losses = {'G_GAN': [], 'G_L1': [], 'D_real': [], 'D_fake': []}\n    with open(log_path, 'r') as f:\n        for line in f:\n            for key in losses.keys():\n                match = re.search(fr'{key}: ([\\d\\.]+)', line)\n                if match: losses[key].append(float(match.group(1)))\n\n    if losses['G_GAN']:\n        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\n        ax1.plot(losses['G_GAN'], label='GAN (Realism)'); ax1.plot(losses['G_L1'], label='L1 (Ink Match)')\n        ax1.set_title('Generator Losses'); ax1.legend()\n        ax2.plot(losses['D_real'], label='D_Real'); ax2.plot(losses['D_fake'], label='D_Fake')\n        ax2.set_title('Discriminator Accuracy'); ax2.legend()\n        plt.show()\n\ndef run_test_and_visualize():\n    print(f\"\\n--- 4. Final Visual Results ---\")\n    cmd_test = (\n            f\"python test.py \"\n            f\"--dataroot {os.path.abspath(POC_DIR)} \"\n            f\"--name {MODEL_NAME} \"\n            f\"--model pix2pix \"\n            f\"--direction BtoA \"\n            f\"--netG unet_256 \"          # MUST match training\n            f\"--norm instance \"           # MUST match training\n            f\"--input_nc 3 --output_nc 3 \"\n            f\"--load_size 256 \"           # Matches new suggested resolution\n            f\"--crop_size 256 \"           # Matches new suggested resolution\n            f\"--num_test 10 \"\n            f\"--no_dropout\"               # Recommended for testing in Pix2Pix\n        )\n    os.system(cmd_test)\n\n    res_path = f'results/{MODEL_NAME}/test_latest/images/'\n    fakes = sorted(glob.glob(os.path.join(res_path, '*_fake_B.png')))\n    reals_in = sorted(glob.glob(os.path.join(res_path, '*_real_B.png')))\n    reals_tar = sorted(glob.glob(os.path.join(res_path, '*_real_A.png')))\n\n    if fakes:\n        num_display = min(len(fakes), 5)\n        fig, axes = plt.subplots(num_display, 3, figsize=(15, 4 * num_display))\n        for i in range(num_display):\n            axes[i, 0].imshow(Image.open(reals_tar[i]))\n            axes[i, 0].set_title(\"X-ray Input\")\n            axes[i, 1].imshow(Image.open(reals_in[i]))\n            axes[i, 1].set_title(\"Target (Ink=Red)\")\n            axes[i, 2].imshow(Image.open(fakes[i]))\n            axes[i, 2].set_title(\"Predicted Ink\")\n            for ax in axes[i]: ax.axis('off')\n        plt.tight_layout()\n        plt.show()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-30T12:05:10.114222Z","iopub.execute_input":"2026-01-30T12:05:10.114442Z","iopub.status.idle":"2026-01-30T12:05:10.136841Z","shell.execute_reply.started":"2026-01-30T12:05:10.114419Z","shell.execute_reply":"2026-01-30T12:05:10.136084Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Test for unet_256 ","metadata":{}},{"cell_type":"markdown","source":"Some continous lines can add some very little value ","metadata":{}},{"cell_type":"code","source":"if __name__ == \"__main__\":\n    initialize_environment()\n    setup_large_dataset()\n    run_large_training()\n    plot_loss()\n    run_test_and_visualize()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-30T12:05:10.138080Z","iopub.execute_input":"2026-01-30T12:05:10.138340Z","execution_failed":"2026-01-30T14:16:52.249Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}