ddpm-cd / README.md
BiliSakura's picture
Add files using upload-large-folder tool
62a941d verified
---
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}
}
```