Pixel-level binary change detection between pre-event optical (EO) and post-event radar (SAR) satellite images.
Outputs a mask where 1 = change (damage/flood) and 0 = no change.
1import torch
2from huggingface_hub import hf_hub_download
3from model import DualEncoderUNet
4
5device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
6
7# Download V9 weights
8ckpt_path = hf_hub_download(
9 repo_id="Rohit7901/galaxeye-change-detection",
10 filename="best_v9.pth",
11)
12
13# Instantiate model
14model = DualEncoderUNet(
15 eo_channels=3,
16 sar_channels=6,
17 num_classes=1,
18).to(device)
19
20model.load_state_dict(torch.load(ckpt_path, map_location=device, weights_only=True))
21model.eval()
22
23# 4-pass TTA inference (images: B, C, H, W tensor on device)
24with torch.no_grad():
25 pred_orig = torch.sigmoid(model(images))
26
27 pred_hflip = torch.sigmoid(model(torch.flip(images, dims=[3])))
28 pred_hflip = torch.flip(pred_hflip, dims=[3])
29
30 pred_vflip = torch.sigmoid(model(torch.flip(images, dims=[2])))
31 pred_vflip = torch.flip(pred_vflip, dims=[2])
32
33 pred_hvflip = torch.sigmoid(model(torch.flip(images, dims=[2, 3])))
34 pred_hvflip = torch.flip(pred_hvflip, dims=[2, 3])
35
36 avg_pred = (pred_orig + pred_hflip + pred_vflip + pred_hvflip) / 4.0
37 binary_mask = (avg_pred > 0.45).float()
Earlier experiments with a single ResNet34-UNet encoder, kept for comparison.
1from model import ResNet34UNet
2
3model = ResNet34UNet(in_channels=9, num_classes=1)
4model.load_state_dict(
5 torch.load("best_v5.pth", map_location="cpu", weights_only=True)
6)
7model.eval()