--- license: mit tags: - diffusers - ddpm-cd - change-detection - remote-sensing --- > [!WARNING] we do not have a full checkpoint conversion validation, if you encounter pipeline loading failure and unsidered output, please contact me via bili_sakura@zju.edu.cn # BiliSakura/ddpm-cd **Consolidated DDPM-CD change detection** — Single repo with shared UNet backbone and multiple cd_head variants (trained on different datasets and timestep configs). ## Model Structure - **Backbone**: Shared SR3-style UNet (same across all variants) - **cd_head**: Dataset-specific change detection heads in `cd_head/{variant}/` ### Available cd_head Variants | Variant | Dataset | Timesteps | Path | |---------|---------|-----------|------| | cdd-50-100 | CDD | [50, 100] | `cd_head/cdd-50-100/` | | cdd-50-100-400 | CDD | [50, 100, 400] | `cd_head/cdd-50-100-400/` | | cdd-50-100-400-650 | CDD | [50, 100, 400, 650] | `cd_head/cdd-50-100-400-650/` | | dsifn-50-100 | DSIFN | [50, 100] | `cd_head/dsifn-50-100/` | | dsifn-50-100-400 | DSIFN | [50, 100, 400] | `cd_head/dsifn-50-100-400/` | | dsifn-50-100-400-650 | DSIFN | [50, 100, 400, 650] | `cd_head/dsifn-50-100-400-650/` | | levir-50-100 | LEVIR | [50, 100] | `cd_head/levir-50-100/` | | levir-50-100-400 | LEVIR | [50, 100, 400] | `cd_head/levir-50-100-400/` | | levir-50-100-400-650 | LEVIR | [50, 100, 400, 650] | `cd_head/levir-50-100-400-650/` | | whu-50-100 | WHU | [50, 100] | `cd_head/whu-50-100/` | | whu-50-100-400 | WHU | [50, 100, 400] | `cd_head/whu-50-100-400/` | | whu-50-100-400-650 | WHU | [50, 100, 400, 650] | `cd_head/whu-50-100-400-650/` | ## Usage Load with explicit `custom_pipeline` (pipeline.py is in the repo, use relative path) and `cd_head_subfolder`: ```python from diffusers import DiffusionPipeline pipe = DiffusionPipeline.from_pretrained( "BiliSakura/ddpm-cd", custom_pipeline="pipeline", trust_remote_code=True, cd_head_subfolder="levir-50-100", ).to("cuda") # Images in [-1, 1], shape (B, 3, H, W) change_map = pipe(image_A, image_B, timesteps=[50, 100]) pred = change_map.argmax(1) # (B, H, W), 0=no-change, 1=change ``` **Important**: Pass the same `timesteps` used during training for each variant (see table above). ### Switching cd_head at Runtime ```python pipe = DiffusionPipeline.from_pretrained( "BiliSakura/ddpm-cd", custom_pipeline="pipeline", trust_remote_code=True, cd_head_subfolder="levir-50-100", ).to("cuda") # Load different cd_head pipe.load_cd_head(subfolder="whu-50-100-400") change_map = pipe(image_A, image_B, timesteps=[50, 100, 400]) ``` ## Citation ```bibtex @inproceedings{bandaraDDPMCDDenoisingDiffusion2025, title = {{{DDPM-CD}}: {{Denoising Diffusion Probabilistic Models}} as {{Feature Extractors}} for {{Remote Sensing Change Detection}}}, shorttitle = {{{DDPM-CD}}}, booktitle = {Proceedings of the {{Winter Conference}} on {{Applications}} of {{Computer Vision}}}, author = {Bandara, Wele Gedara Chaminda and Nair, Nithin Gopalakrishnan and Patel, Vishal}, year = 2025, pages = {5250--5262}, urldate = {2025-12-28} } ```