{"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":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":21755,"databundleVersionId":1475600},{"sourceType":"datasetVersion","sourceId":14582880,"datasetId":9315390,"databundleVersionId":15416824},{"sourceType":"kernelVersion","sourceId":293320467}],"dockerImageVersionId":31236,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!nvidia-smi\nimport torch\nprint(\"CUDA available:\", torch.cuda.is_available())\nif torch.cuda.is_available():\n    print(\"GPU:\", torch.cuda.get_device_name(0))\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:49:59.026055Z","iopub.execute_input":"2026-01-04T14:49:59.026287Z","iopub.status.idle":"2026-01-04T14:50:03.341716Z","shell.execute_reply.started":"2026-01-04T14:49:59.026267Z","shell.execute_reply":"2026-01-04T14:50:03.340781Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!git clone https://github.com/hamdanyasser/cyclegan-monet-translation.git\n%cd cyclegan-monet-translation\n!ls\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:51:05.067083Z","iopub.execute_input":"2026-01-04T14:51:05.067407Z","iopub.status.idle":"2026-01-04T14:51:05.752658Z","shell.execute_reply.started":"2026-01-04T14:51:05.067376Z","shell.execute_reply":"2026-01-04T14:51:05.751626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -q -r requirements.txt\n!pip install -q scipy\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:51:21.971172Z","iopub.execute_input":"2026-01-04T14:51:21.971866Z","iopub.status.idle":"2026-01-04T14:52:38.617252Z","shell.execute_reply.started":"2026-01-04T14:51:21.971834Z","shell.execute_reply":"2026-01-04T14:52:38.616085Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torchvision\nprint(\"torch:\", torch.__version__)\nprint(\"torchvision:\", torchvision.__version__)\nprint(\"CUDA available:\", torch.cuda.is_available())\nprint(\"GPU:\", torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"NONE\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:53:19.052318Z","iopub.execute_input":"2026-01-04T14:53:19.052923Z","iopub.status.idle":"2026-01-04T14:53:22.497962Z","shell.execute_reply.started":"2026-01-04T14:53:19.052891Z","shell.execute_reply":"2026-01-04T14:53:22.497121Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\ndata_dir = \"/kaggle/input/gan-getting-started\"\nprint(\"Monet:\", len(os.listdir(f\"{data_dir}/monet_jpg\")))\nprint(\"Photo:\", len(os.listdir(f\"{data_dir}/photo_jpg\")))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:53:39.212951Z","iopub.execute_input":"2026-01-04T14:53:39.213735Z","iopub.status.idle":"2026-01-04T14:53:39.341366Z","shell.execute_reply.started":"2026-01-04T14:53:39.213705Z","shell.execute_reply":"2026-01-04T14:53:39.340694Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name smoke_test \\\n  --epochs 1 \\\n  --image_size 128 \\\n  --save_freq 1 \\\n  --sample_freq 1 \\\n  --amp\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T14:53:49.605917Z","iopub.execute_input":"2026-01-04T14:53:49.606485Z","iopub.status.idle":"2026-01-04T15:05:59.513209Z","shell.execute_reply.started":"2026-01-04T14:53:49.606462Z","shell.execute_reply":"2026-01-04T15:05:59.512285Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls outputs/smoke_test\n!ls outputs/smoke_test/samples\n!ls outputs/smoke_test/checkpoints\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T15:14:53.266849Z","iopub.execute_input":"2026-01-04T15:14:53.267457Z","iopub.status.idle":"2026-01-04T15:14:53.642501Z","shell.execute_reply.started":"2026-01-04T15:14:53.267423Z","shell.execute_reply":"2026-01-04T15:14:53.641684Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import glob\nfrom PIL import Image\nfrom IPython.display import display\n\npaths = sorted(glob.glob(\"outputs/smoke_test/samples/*.png\"))[:5]\nfor p in paths:\n    display(Image.open(p))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T15:15:05.379257Z","iopub.execute_input":"2026-01-04T15:15:05.379914Z","iopub.status.idle":"2026-01-04T15:15:05.425822Z","shell.execute_reply.started":"2026-01-04T15:15:05.379882Z","shell.execute_reply":"2026-01-04T15:15:05.424746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256 \\\n  --epochs 60 \\\n  --image_size 256 \\\n  --lambda_cycle 10 \\\n  --use_identity \\\n  --amp \\\n  --save_freq 5 \\\n  --sample_freq 2\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T15:15:23.520932Z","iopub.execute_input":"2026-01-04T15:15:23.521806Z","execution_failed":"2026-01-04T21:12:39.048Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install -q -r requirements.txt\n!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256_v2 \\\n  --epochs 20 \\\n  --image_size 256 \\\n  --lambda_cycle 10 \\\n  --use_identity \\\n  --amp \\\n  --save_freq 1 \\\n  --sample_freq 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T21:59:35.975455Z","iopub.execute_input":"2026-01-04T21:59:35.976295Z","iopub.status.idle":"2026-01-04T22:05:08.307446Z","shell.execute_reply.started":"2026-01-04T21:59:35.976258Z","shell.execute_reply":"2026-01-04T22:05:08.306779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256 \\\n  --epochs 20 \\\n  --image_size 256 \\\n  --lambda_cycle 10 \\\n  --use_identity \\\n  --amp \\\n  --save_freq 1 \\\n  --sample_freq 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-04T22:05:12.265776Z","iopub.execute_input":"2026-01-04T22:05:12.266476Z","iopub.status.idle":"2026-01-05T06:46:55.708334Z","shell.execute_reply.started":"2026-01-04T22:05:12.266444Z","shell.execute_reply":"2026-01-05T06:46:55.707603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -R outputs/baseline_256 | head -n 200\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T06:46:55.828655Z","iopub.execute_input":"2026-01-05T06:46:55.828895Z","iopub.status.idle":"2026-01-05T06:46:55.944679Z","shell.execute_reply.started":"2026-01-05T06:46:55.828871Z","shell.execute_reply":"2026-01-05T06:46:55.944061Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# See if anything was saved\n!ls -la /kaggle/working/\n!ls -la /kaggle/output/ 2>/dev/null || echo \"No output saved\"\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T08:35:09.786959Z","iopub.execute_input":"2026-01-05T08:35:09.787648Z","iopub.status.idle":"2026-01-05T08:35:10.013725Z","shell.execute_reply.started":"2026-01-05T08:35:09.787610Z","shell.execute_reply":"2026-01-05T08:35:10.013117Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n    --data_dir /kaggle/input/gan-getting-started \\\n    --run_name baseline_v2 \\\n    --epochs 20 \\\n    --amp \\\n    --save_freq 5 \\\n    --sample_freq 2\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T08:52:50.027983Z","iopub.execute_input":"2026-01-05T08:52:50.028565Z","iopub.status.idle":"2026-01-05T17:57:37.689599Z","shell.execute_reply.started":"2026-01-05T08:52:50.028529Z","shell.execute_reply":"2026-01-05T17:57:37.688617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256 \\\n  --epochs 20 \\\n  --image_size 256 \\\n  --lambda_cycle 10 \\\n  --use_identity \\\n  --amp \\\n  --save_freq 1 \\\n  --sample_freq 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-05T19:57:22.952652Z","iopub.execute_input":"2026-01-05T19:57:22.953252Z","execution_failed":"2026-01-06T05:06:23.802Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256 \\\n  --epochs 20 \\\n  --image_size 256 \\\n  --lambda_cycle 10 \\\n  --use_identity \\\n  --amp \\\n  --save_freq 1 \\\n  --sample_freq 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-10T08:01:46.158659Z","iopub.execute_input":"2026-01-10T08:01:46.158976Z","iopub.status.idle":"2026-01-10T09:56:35.757973Z","shell.execute_reply.started":"2026-01-10T08:01:46.158945Z","shell.execute_reply":"2026-01-10T09:56:35.757267Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --resume outputs/baseline_256/checkpoints/checkpoint_epoch_0004.pth \\\n  --run_name baseline_256 \\\n  --output_dir outputs \\\n  --amp\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-10T10:19:41.645747Z","iopub.execute_input":"2026-01-10T10:19:41.646066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --resume outputs/baseline_256/checkpoints/checkpoint_epoch_0004.pth \\\n  --run_name baseline_256 \\\n  --output_dir outputs \\\n  --amp\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-10T11:55:44.653639Z","iopub.execute_input":"2026-01-10T11:55:44.654447Z","iopub.status.idle":"2026-01-10T11:55:55.020866Z","shell.execute_reply.started":"2026-01-10T11:55:44.654411Z","shell.execute_reply":"2026-01-10T11:55:55.020139Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --resume outputs/baseline_256/checkpoints/checkpoint_epoch_0004.pth \\\n  --epochs 20 \\\n  --lr_decay_start 10 \\\n  --batch_size 4 \\\n  --num_workers 0 \\\n  --run_name baseline_256 \\\n  --output_dir outputs \\\n  --amp\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-10T12:07:09.369241Z","iopub.execute_input":"2026-01-10T12:07:09.369586Z","iopub.status.idle":"2026-01-10T13:36:43.148269Z","shell.execute_reply.started":"2026-01-10T12:07:09.369550Z","shell.execute_reply":"2026-01-10T13:36:43.147519Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --resume outputs/baseline_256/checkpoints/checkpoint_epoch_0004.pth \\\n  --epochs 20 \\\n  --lr_decay_start 10 \\\n  --batch_size 4 \\\n  --num_workers 0 \\\n  --run_name baseline_256 \\\n  --output_dir outputs \\\n  --amp\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-10T14:54:30.110258Z","iopub.execute_input":"2026-01-10T14:54:30.110574Z","iopub.status.idle":"2026-01-10T22:29:11.376118Z","shell.execute_reply.started":"2026-01-10T14:54:30.110543Z","shell.execute_reply":"2026-01-10T22:29:11.375194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n  --data_dir /kaggle/input/gan-getting-started \\\n  --run_name baseline_256 \\\n  --output_dir outputs \\\n  --epochs 20 \\\n  --amp \\\n  --save_freq 1 \\\n  --sample_freq 1\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-11T07:13:27.238744Z","iopub.execute_input":"2026-01-11T07:13:27.239075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls -lh outputs/baseline_256/checkpoints/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-11T11:20:06.687874Z","iopub.execute_input":"2026-01-11T11:20:06.688190Z","iopub.status.idle":"2026-01-11T11:20:06.817677Z","shell.execute_reply.started":"2026-01-11T11:20:06.688127Z","shell.execute_reply":"2026-01-11T11:20:06.816477Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 1: Create 3000 photo subset\nimport os, random, shutil\n\nos.makedirs('data/photo_subset', exist_ok=True)\nos.makedirs('data/monet_jpg', exist_ok=True)\n\nphotos = os.listdir('/kaggle/input/gan-getting-started/photo_jpg')\nselected = random.sample(photos, 3000)\n\nfor p in selected:\n    shutil.copy(f'/kaggle/input/gan-getting-started/photo_jpg/{p}', f'data/photo_subset/{p}')\n\nfor m in os.listdir('/kaggle/input/gan-getting-started/monet_jpg'):\n    shutil.copy(f'/kaggle/input/gan-getting-started/monet_jpg/{m}', f'data/monet_jpg/{m}')\n\nprint(f\"Photos: {len(os.listdir('data/photo_subset'))}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-18T22:05:06.839086Z","iopub.execute_input":"2026-01-18T22:05:06.839729Z","iopub.status.idle":"2026-01-18T22:05:42.944050Z","shell.execute_reply.started":"2026-01-18T22:05:06.839694Z","shell.execute_reply":"2026-01-18T22:05:42.943397Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!git clone https://github.com/hamdanyasser/cyclegan-monet-translation.git\n%cd cyclegan-monet-translation\n!pip install -q torch torchvision pillow pyyaml tqdm\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:34:19.279270Z","iopub.execute_input":"2026-01-22T13:34:19.279597Z","iopub.status.idle":"2026-01-22T13:34:25.745690Z","shell.execute_reply.started":"2026-01-22T13:34:19.279564Z","shell.execute_reply":"2026-01-22T13:34:25.744975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os, random, shutil\n\nos.makedirs('data/photo_subset', exist_ok=True)\nos.makedirs('data/monet_jpg', exist_ok=True)\n\nphotos = os.listdir('/kaggle/input/gan-getting-started/photo_jpg')\nselected = random.sample(photos, 3000)\n\nfor p in selected:\n    shutil.copy(f'/kaggle/input/gan-getting-started/photo_jpg/{p}', f'data/photo_subset/{p}')\n\nfor m in os.listdir('/kaggle/input/gan-getting-started/monet_jpg'):\n    shutil.copy(f'/kaggle/input/gan-getting-started/monet_jpg/{m}', f'data/monet_jpg/{m}')\n\nprint(f\"Photos: {len(os.listdir('data/photo_subset'))}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-18T22:07:06.688778Z","iopub.execute_input":"2026-01-18T22:07:06.689175Z","iopub.status.idle":"2026-01-18T22:07:30.134868Z","shell.execute_reply.started":"2026-01-18T22:07:06.689133Z","shell.execute_reply":"2026-01-18T22:07:30.134069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/train.py \\\n    --data_dir data \\\n    --run_name final_30ep \\\n    --epochs 30 \\\n    --image_size 256 \\\n    --batch_size 1 \\\n    --amp \\\n    --save_freq 5 \\\n    --sample_freq 5\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-18T22:08:52.080859Z","iopub.execute_input":"2026-01-18T22:08:52.081191Z","iopub.status.idle":"2026-01-18T22:14:05.930143Z","shell.execute_reply.started":"2026-01-18T22:08:52.081167Z","shell.execute_reply":"2026-01-18T22:14:05.929008Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ===== TRAINING: 12:15 AM → ~9:25 AM =====\n\nimport os, random, shutil\n\n# Step 1: Setup data\nprint(\"Setting up data...\")\nos.makedirs('data/photo_jpg', exist_ok=True)\nos.makedirs('data/monet_jpg', exist_ok=True)\n\nif len(os.listdir('data/photo_jpg')) == 0:\n    photos = os.listdir('/kaggle/input/gan-getting-started/photo_jpg')\n    selected = random.sample(photos, 3000)\n    for p in selected:\n        shutil.copy(f'/kaggle/input/gan-getting-started/photo_jpg/{p}', f'data/photo_jpg/{p}')\n    for m in os.listdir('/kaggle/input/gan-getting-started/monet_jpg'):\n        shutil.copy(f'/kaggle/input/gan-getting-started/monet_jpg/{m}', f'data/monet_jpg/{m}')\n\nprint(f\"Photos: {len(os.listdir('data/photo_jpg'))}\")\nprint(f\"Monet: {len(os.listdir('data/monet_jpg'))}\")\n\n# Step 2: Train 55 epochs (~9h 10m)\n!python src/train.py \\\n    --data_dir data \\\n    --run_name final_55ep \\\n    --epochs 55 \\\n    --image_size 256 \\\n    --batch_size 1 \\\n    --amp \\\n    --save_freq 10 \\\n    --sample_freq 10\n\n# Step 3: Auto-save outputs\n!cp -r outputs /kaggle/working/\n!ls /kaggle/working/outputs/\n\n# Step 4: Keep alive until you wake up\nimport time\nfrom datetime import datetime\n\nprint(\"\\n\" + \"=\"*50)\nprint(\"✅ TRAINING COMPLETE!\")\nprint(\"Keeping session alive until you wake up...\")\nprint(\"=\"*50 + \"\\n\")\n\nfor i in range(60):\n    print(f\"[{datetime.now().strftime('%H:%M:%S')}] Alive - Click SAVE VERSION when ready!\")\n    time.sleep(300)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-18T22:16:30.432970Z","iopub.execute_input":"2026-01-18T22:16:30.433792Z","iopub.status.idle":"2026-01-19T08:27:19.552106Z","shell.execute_reply.started":"2026-01-18T22:16:30.433749Z","shell.execute_reply":"2026-01-19T08:27:19.551045Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from IPython.display import Image\nImage('outputs/final_55ep/samples/epoch_0050.png')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-19T08:41:23.048356Z","iopub.execute_input":"2026-01-19T08:41:23.048753Z","iopub.status.idle":"2026-01-19T08:41:23.077045Z","shell.execute_reply.started":"2026-01-19T08:41:23.048716Z","shell.execute_reply":"2026-01-19T08:41:23.075976Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/infer.py \\\n    --checkpoint outputs/final_55ep/checkpoints/G_A2B_final.pth \\\n    --input_dir /kaggle/input/gan-getting-started/photo_jpg \\\n    --output_dir outputs/final_55ep/generated_monet \\\n    --direction A2B\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-19T08:42:28.436102Z","iopub.execute_input":"2026-01-19T08:42:28.436732Z","iopub.status.idle":"2026-01-19T08:46:23.436362Z","shell.execute_reply.started":"2026-01-19T08:42:28.436699Z","shell.execute_reply":"2026-01-19T08:46:23.435653Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python src/eval_fid.py \\\n    --real_dir /kaggle/input/gan-getting-started/monet_jpg \\\n    --fake_dir outputs/final_55ep/generated_monet\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:34:32.682561Z","iopub.execute_input":"2026-01-22T13:34:32.682877Z","iopub.status.idle":"2026-01-22T13:34:45.716259Z","shell.execute_reply.started":"2026-01-22T13:34:32.682844Z","shell.execute_reply":"2026-01-22T13:34:45.715537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!cp -r outputs /kaggle/working/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:34:29.511520Z","iopub.execute_input":"2026-01-22T13:34:29.512115Z","iopub.status.idle":"2026-01-22T13:34:29.650514Z","shell.execute_reply.started":"2026-01-22T13:34:29.512081Z","shell.execute_reply":"2026-01-22T13:34:29.649826Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls /kaggle/working/outputs/final_55ep/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:34:26.604136Z","iopub.execute_input":"2026-01-22T13:34:26.604456Z","iopub.status.idle":"2026-01-22T13:34:26.738841Z","shell.execute_reply.started":"2026-01-22T13:34:26.604426Z","shell.execute_reply":"2026-01-22T13:34:26.738200Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!git clone https://github.com/hamdanyasser/cyclegan-monet-translation.git temp_check\n!ls temp_check/\n!ls temp_check/outputs 2>/dev/null || echo \"No outputs folder in GitHub\"\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:36:36.601155Z","iopub.execute_input":"2026-01-22T13:36:36.601509Z","iopub.status.idle":"2026-01-22T13:36:37.503266Z","shell.execute_reply.started":"2026-01-22T13:36:36.601478Z","shell.execute_reply":"2026-01-22T13:36:37.502517Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls /kaggle/input/image-generator-with-gans/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:53:32.951182Z","iopub.execute_input":"2026-01-22T13:53:32.951468Z","iopub.status.idle":"2026-01-22T13:53:33.101199Z","shell.execute_reply.started":"2026-01-22T13:53:32.951444Z","shell.execute_reply":"2026-01-22T13:53:33.100355Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls /kaggle/input/image-generator-with-gans/outputs/final_55ep/checkpoints/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:53:44.273454Z","iopub.execute_input":"2026-01-22T13:53:44.274254Z","iopub.status.idle":"2026-01-22T13:53:44.417337Z","shell.execute_reply.started":"2026-01-22T13:53:44.274217Z","shell.execute_reply":"2026-01-22T13:53:44.416644Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!python /kaggle/input/image-generator-with-gans/cyclegan-monet-translation/src/infer.py \\\n    --checkpoint /kaggle/input/image-generator-with-gans/outputs/final_55ep/checkpoints/G_A2B_final.pth \\\n    --input_dir /kaggle/input/gan-getting-started/photo_jpg \\\n    --output_dir /kaggle/working/generated_monet \\\n    --direction A2B\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:54:31.875448Z","iopub.execute_input":"2026-01-22T13:54:31.875974Z","iopub.status.idle":"2026-01-22T13:58:37.837987Z","shell.execute_reply.started":"2026-01-22T13:54:31.875935Z","shell.execute_reply":"2026-01-22T13:58:37.837050Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom PIL import Image\nimport os\n\nfig, axes = plt.subplots(2, 4, figsize=(16, 8))\nimages = os.listdir('/kaggle/working/generated_monet')[:8]\n\nfor ax, img in zip(axes.flat, images):\n    ax.imshow(Image.open(f'/kaggle/working/generated_monet/{img}'))\n    ax.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:59:15.850022Z","iopub.execute_input":"2026-01-22T13:59:15.850834Z","iopub.status.idle":"2026-01-22T13:59:16.288976Z","shell.execute_reply.started":"2026-01-22T13:59:15.850787Z","shell.execute_reply":"2026-01-22T13:59:16.287998Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install torch-fidelity -q\n!python /kaggle/input/image-generator-with-gans/cyclegan-monet-translation/src/eval_fid.py \\\n    --real_dir /kaggle/input/gan-getting-started/monet_jpg \\\n    --fake_dir /kaggle/working/generated_monet\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T13:59:32.837395Z","iopub.execute_input":"2026-01-22T13:59:32.838142Z","iopub.status.idle":"2026-01-22T14:00:25.835483Z","shell.execute_reply.started":"2026-01-22T13:59:32.838110Z","shell.execute_reply":"2026-01-22T14:00:25.834679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!ls /kaggle/working/\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T14:02:04.023098Z","iopub.execute_input":"2026-01-22T14:02:04.023753Z","iopub.status.idle":"2026-01-22T14:02:04.157755Z","shell.execute_reply.started":"2026-01-22T14:02:04.023718Z","shell.execute_reply":"2026-01-22T14:02:04.157119Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!cp /kaggle/input/image-generator-with-gans/outputs/final_55ep/samples/*.png /kaggle/working/\n!ls /kaggle/working/*.png\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T14:30:53.760542Z","iopub.execute_input":"2026-01-22T14:30:53.761121Z","iopub.status.idle":"2026-01-22T14:30:54.064935Z","shell.execute_reply.started":"2026-01-22T14:30:53.761087Z","shell.execute_reply":"2026-01-22T14:30:54.064263Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from IPython.display import FileLink, display\n\n# Download links for all samples\ndisplay(FileLink('/kaggle/working/epoch_0010.png'))\ndisplay(FileLink('/kaggle/working/epoch_0020.png'))\ndisplay(FileLink('/kaggle/working/epoch_0030.png'))\ndisplay(FileLink('/kaggle/working/epoch_0040.png'))\ndisplay(FileLink('/kaggle/working/epoch_0050.png'))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T14:32:27.220589Z","iopub.execute_input":"2026-01-22T14:32:27.220939Z","iopub.status.idle":"2026-01-22T14:32:27.231853Z","shell.execute_reply.started":"2026-01-22T14:32:27.220907Z","shell.execute_reply":"2026-01-22T14:32:27.231077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!zip /kaggle/working/all_samples.zip /kaggle/working/epoch_*.png\n\nfrom IPython.display import FileLink\nFileLink('/kaggle/working/all_samples.zip')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T14:32:59.286229Z","iopub.execute_input":"2026-01-22T14:32:59.286763Z","iopub.status.idle":"2026-01-22T14:32:59.555605Z","shell.execute_reply.started":"2026-01-22T14:32:59.286737Z","shell.execute_reply":"2026-01-22T14:32:59.554906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!zip -j /kaggle/working/samples.zip /kaggle/working/epoch_*.png\n!ls -la /kaggle/working/samples.zip\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T14:33:17.656398Z","iopub.execute_input":"2026-01-22T14:33:17.656712Z","iopub.status.idle":"2026-01-22T14:33:18.043739Z","shell.execute_reply.started":"2026-01-22T14:33:17.656681Z","shell.execute_reply":"2026-01-22T14:33:18.042892Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.transforms as transforms\nimport torchvision.models as models\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport os\n\n# Check device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using: {device}\")\n\n# Load images\ncontent_path = \"/kaggle/input/image1/landscape_photography_tips_featured_image.webp\"\nmonet_dir = \"/kaggle/input/gan-getting-started/monet_jpg\"\nstyle_path = os.path.join(monet_dir, os.listdir(monet_dir)[0])\n\n# Image size (smaller = faster)\nimsize = 512\n\nloader = transforms.Compose([\n    transforms.Resize((imsize, imsize)),\n    transforms.ToTensor()\n])\n\ndef load_image(path):\n    image = Image.open(path).convert('RGB')\n    image = loader(image).unsqueeze(0)\n    return image.to(device, torch.float)\n\ncontent_img = load_image(content_path)\nstyle_img = load_image(style_path)\n\n# VGG19 for feature extraction\ncnn = models.vgg19(pretrained=True).features.to(device).eval()\n\n# Normalization\ncnn_normalization_mean = torch.tensor([0.485, 0.456, 0.406]).to(device)\ncnn_normalization_std = torch.tensor([0.229, 0.224, 0.225]).to(device)\n\nclass Normalization(nn.Module):\n    def __init__(self, mean, std):\n        super().__init__()\n        self.mean = mean.view(-1, 1, 1)\n        self.std = std.view(-1, 1, 1)\n    def forward(self, img):\n        return (img - self.mean) / self.std\n\n# Content and style layers\ncontent_layers = ['conv_4']\nstyle_layers = ['conv_1', 'conv_2', 'conv_3', 'conv_4', 'conv_5']\n\ndef gram_matrix(input):\n    b, c, h, w = input.size()\n    features = input.view(b * c, h * w)\n    G = torch.mm(features, features.t())\n    return G.div(b * c * h * w)\n\nclass ContentLoss(nn.Module):\n    def __init__(self, target):\n        super().__init__()\n        self.target = target.detach()\n    def forward(self, input):\n        self.loss = nn.functional.mse_loss(input, self.target)\n        return input\n\nclass StyleLoss(nn.Module):\n    def __init__(self, target_feature):\n        super().__init__()\n        self.target = gram_matrix(target_feature).detach()\n    def forward(self, input):\n        G = gram_matrix(input)\n        self.loss = nn.functional.mse_loss(G, self.target)\n        return input\n\ndef get_model_and_losses(cnn, content_img, style_img):\n    normalization = Normalization(cnn_normalization_mean, cnn_normalization_std).to(device)\n    content_losses = []\n    style_losses = []\n    model = nn.Sequential(normalization)\n    \n    i = 0\n    for layer in cnn.children():\n        if isinstance(layer, nn.Conv2d):\n            i += 1\n            name = f'conv_{i}'\n        elif isinstance(layer, nn.ReLU):\n            name = f'relu_{i}'\n            layer = nn.ReLU(inplace=False)\n        elif isinstance(layer, nn.MaxPool2d):\n            name = f'pool_{i}'\n        elif isinstance(layer, nn.BatchNorm2d):\n            name = f'bn_{i}'\n        else:\n            continue\n            \n        model.add_module(name, layer)\n        \n        if name in content_layers:\n            target = model(content_img).detach()\n            content_loss = ContentLoss(target)\n            model.add_module(f\"content_loss_{i}\", content_loss)\n            content_losses.append(content_loss)\n            \n        if name in style_layers:\n            target_feature = model(style_img).detach()\n            style_loss = StyleLoss(target_feature)\n            model.add_module(f\"style_loss_{i}\", style_loss)\n            style_losses.append(style_loss)\n    \n    return model, style_losses, content_losses\n\nmodel, style_losses, content_losses = get_model_and_losses(cnn, content_img, style_img)\n\n# Start with content image\ninput_img = content_img.clone()\n\n# Run optimization\noptimizer = optim.LBFGS([input_img.requires_grad_()])\nstyle_weight = 1000000  # High = more Monet style\ncontent_weight = 1\n\nprint(\"Creating Monet-style image...\")\nrun = [0]\nwhile run[0] <= 300:\n    def closure():\n        input_img.data.clamp_(0, 1)\n        optimizer.zero_grad()\n        model(input_img)\n        \n        style_score = sum(sl.loss for sl in style_losses) * style_weight\n        content_score = sum(cl.loss for cl in content_losses) * content_weight\n        loss = style_score + content_score\n        loss.backward()\n        \n        run[0] += 1\n        if run[0] % 50 == 0:\n            print(f\"Step {run[0]}: Style={style_score.item():.2f}, Content={content_score.item():.2f}\")\n        return loss\n    \n    optimizer.step(closure)\n\ninput_img.data.clamp_(0, 1)\nprint(\"Done!\")\n\n# Show results\ndef show_tensor(tensor):\n    image = tensor.cpu().clone().squeeze(0)\n    image = transforms.ToPILImage()(image)\n    return image\n\nfig, axes = plt.subplots(1, 3, figsize=(18, 6))\n\naxes[0].imshow(show_tensor(content_img))\naxes[0].set_title(\"Your Original Photo\", fontsize=14)\naxes[0].axis('off')\n\naxes[1].imshow(show_tensor(style_img))\naxes[1].set_title(\"Monet Style Reference\", fontsize=14)\naxes[1].axis('off')\n\naxes[2].imshow(show_tensor(input_img))\naxes[2].set_title(\"YOUR PHOTO IN MONET STYLE!\", fontsize=14, fontweight='bold')\naxes[2].axis('off')\n\nplt.tight_layout()\nplt.savefig('neural_style_result.png', dpi=150, bbox_inches='tight')\nplt.show()\n\nprint(\"\\n✅ THIS is what dramatic Monet-style looks like!\")\nprint(\"The right image is your photo transformed to look like a Monet painting.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T15:16:25.760831Z","iopub.execute_input":"2026-01-22T15:16:25.761168Z","iopub.status.idle":"2026-01-22T15:17:07.850584Z","shell.execute_reply.started":"2026-01-22T15:16:25.761143Z","shell.execute_reply":"2026-01-22T15:17:07.849790Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport torchvision.transforms as transforms\n\n# Correct model architecture (matching your trained model)\nclass ResidualBlock(nn.Module):\n    def __init__(self, channels):\n        super().__init__()\n        self.block = nn.Sequential(\n            nn.ReflectionPad2d(1),\n            nn.Conv2d(channels, channels, kernel_size=3, padding=0, bias=True),\n            nn.InstanceNorm2d(channels, affine=True),\n            nn.ReLU(inplace=True),\n            nn.ReflectionPad2d(1),\n            nn.Conv2d(channels, channels, kernel_size=3, padding=0, bias=True),\n            nn.InstanceNorm2d(channels, affine=True)\n        )\n    def forward(self, x):\n        return x + self.block(x)\n\nclass ResNetGenerator(nn.Module):\n    def __init__(self, input_channels=3, output_channels=3, ngf=64, n_residual=9):\n        super().__init__()\n        \n        # Initial convolution\n        self.initial = nn.Sequential(\n            nn.ReflectionPad2d(3),\n            nn.Conv2d(input_channels, ngf, kernel_size=7, padding=0, bias=True),\n            nn.InstanceNorm2d(ngf, affine=True),\n            nn.ReLU(inplace=True)\n        )\n        \n        # Downsampling\n        self.downsample = nn.Sequential(\n            nn.Conv2d(ngf, ngf * 2, kernel_size=3, stride=2, padding=1, bias=True),\n            nn.InstanceNorm2d(ngf * 2, affine=True),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(ngf * 2, ngf * 4, kernel_size=3, stride=2, padding=1, bias=True),\n            nn.InstanceNorm2d(ngf * 4, affine=True),\n            nn.ReLU(inplace=True)\n        )\n        \n        # Residual blocks\n        self.residual = nn.Sequential(\n            *[ResidualBlock(ngf * 4) for _ in range(n_residual)]\n        )\n        \n        # Upsampling\n        self.upsample = nn.Sequential(\n            nn.ConvTranspose2d(ngf * 4, ngf * 2, kernel_size=3, stride=2, padding=1, output_padding=1, bias=True),\n            nn.InstanceNorm2d(ngf * 2, affine=True),\n            nn.ReLU(inplace=True),\n            nn.ConvTranspose2d(ngf * 2, ngf, kernel_size=3, stride=2, padding=1, output_padding=1, bias=True),\n            nn.InstanceNorm2d(ngf, affine=True),\n            nn.ReLU(inplace=True)\n        )\n        \n        # Final convolution\n        self.final = nn.Sequential(\n            nn.ReflectionPad2d(3),\n            nn.Conv2d(ngf, output_channels, kernel_size=7, padding=0),\n            nn.Tanh()\n        )\n    \n    def forward(self, x):\n        x = self.initial(x)\n        x = self.downsample(x)\n        x = self.residual(x)\n        x = self.upsample(x)\n        x = self.final(x)\n        return x\n\n# Load models\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\nG_A2B = ResNetGenerator(n_residual=9).to(device)  # Photo to Monet\nG_B2A = ResNetGenerator(n_residual=9).to(device)  # Monet to Photo\n\n# Load checkpoint\ncheckpoint_path = \"/kaggle/input/image-generator-with-gans/outputs/final_55ep/checkpoints/latest.pth\"\ncheckpoint = torch.load(checkpoint_path, map_location=device)\nG_A2B.load_state_dict(checkpoint['G_A2B'])\nG_B2A.load_state_dict(checkpoint['G_B2A'])\nG_A2B.eval()\nG_B2A.eval()\nprint(\"Models loaded!\")\n\n# Load your image\ntransform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n])\n\nimg_path = \"/kaggle/input/image1/landscape_photography_tips_featured_image.webp\"\noriginal = Image.open(img_path).convert('RGB')\ninput_tensor = transform(original).unsqueeze(0).to(device)\n\n# Run the FULL CYCLE\nwith torch.no_grad():\n    # Step 1: Photo → Monet\n    monet_style = G_A2B(input_tensor)\n    \n    # Step 2: Monet → Back to Photo\n    reconstructed = G_B2A(monet_style)\n\n# Convert tensors to images\ndef tensor_to_image(tensor):\n    img = tensor.cpu().squeeze(0)\n    img = img * 0.5 + 0.5  # Denormalize\n    img = img.clamp(0, 1)\n    img = transforms.ToPILImage()(img)\n    return img\n\nmonet_img = tensor_to_image(monet_style)\nreconstructed_img = tensor_to_image(reconstructed)\noriginal_resized = original.resize((256, 256))\n\n# Show all 3 images\nfig, axes = plt.subplots(1, 3, figsize=(15, 5))\n\naxes[0].imshow(original_resized)\naxes[0].set_title(\"1. ORIGINAL PHOTO\", fontsize=14, fontweight='bold')\naxes[0].axis('off')\n\naxes[1].imshow(monet_img)\naxes[1].set_title(\"2. → MONET STYLE\", fontsize=14, fontweight='bold', color='blue')\naxes[1].axis('off')\n\naxes[2].imshow(reconstructed_img)\naxes[2].set_title(\"3. → BACK TO PHOTO\", fontsize=14, fontweight='bold', color='green')\naxes[2].axis('off')\n\nplt.suptitle(\"CYCLEGAN FULL CYCLE: Photo → Monet → Photo\", fontsize=16, fontweight='bold')\nplt.tight_layout()\nplt.savefig('cyclegan_full_cycle.png', dpi=150, bbox_inches='tight')\nplt.show()\n\nprint(\"\\n✅ Full cycle complete!\")\nprint(\"1. Original photo\")\nprint(\"2. Converted to Monet style\")\nprint(\"3. Converted back to photo\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-01-22T15:29:15.970700Z","iopub.execute_input":"2026-01-22T15:29:15.971437Z","iopub.status.idle":"2026-01-22T15:29:18.076270Z","shell.execute_reply.started":"2026-01-22T15:29:15.971409Z","shell.execute_reply":"2026-01-22T15:29:18.075516Z"}},"outputs":[],"execution_count":null}]}