Image-to-Image
Diffusers
Safetensors
sar-to-eo
remote-sensing
flow-matching
synthetic-aperture-radar
Instructions to use JeonghyeokDo/ReFlowSET with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use JeonghyeokDo/ReFlowSET with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline from diffusers.utils import load_image # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("JeonghyeokDo/ReFlowSET", dtype=torch.bfloat16, device_map="cuda") prompt = "Turn this cat into a dog" input_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png") image = pipe(image=input_image, prompt=prompt).images[0] - Notebooks
- Google Colab
- Kaggle
| # Conditional Diffusion — SAR2Opt | |
| **Conditional Diffusion for SAR to Optical Image Translation**, Bai, Pu and Xu, | |
| *IEEE Geoscience and Remote Sensing Letters*, 2023 | |
| ([doi:10.1109/LGRS.2023.3337143](https://doi.org/10.1109/LGRS.2023.3337143); the | |
| year is the one in the authors' own citation block — a table that labels this | |
| row with a later issue year is referring to the same paper). | |
| Upstream code: | |
| [`Coordi777/Conditional-Diffusion-for-SAR-to-Optical-Image-Translation`](https://github.com/Coordi777/Conditional-Diffusion-for-SAR-to-Optical-Image-Translation), | |
| a modified copy of [`openai/guided-diffusion`](https://github.com/openai/guided-diffusion). | |
| **The exact upstream commit is not recoverable** — see the licence section. | |
| This is the pixel-space conditional diffusion model we retrained ourselves on | |
| SAR2Opt, and it is the checkpoint behind the Conditional Diffusion row of the | |
| ReFlowSET comparison table. | |
| ## What is in this folder | |
| | file | bytes | what it is | | |
| |---|---|---| | |
| | `ema_final.pt` | 662,459,343 | EMA (decay 0.9999) of the UNet at update 50,000 — a **bare state dict**, no wrapper key | | |
| `ema_final.pt` is the EMA of a **164.3 M-parameter guided-diffusion UNet**: | |
| `num_channels` 128, `num_res_blocks` 3, `learn_sigma` **False**, attention at | |
| resolutions 16 and 8. It is a plain `state_dict` — load it directly, with no | |
| `['model']` or `['ema']` indirection. | |
| The QXS-SAROPT and SAR2Opt files differ in size (657,495,287 vs 662,459,343 | |
| bytes) purely because of the 256 px versus 512 px positional and attention | |
| buffers; the parameter count is otherwise the same. | |
| **Conditioning.** The SAR image is concatenated to the noisy state **noise-free** | |
| at every reverse step and at training time — that is the paper's claim, and the | |
| code does exactly that. | |
| ## Training budget we used | |
| | | | | |
| |---|---| | |
| | **generator updates released** | **50,000** | | |
| | batch size / resolution | 6 @ 512 px | | |
| | optimizer | Adam, **constant** lr 1e-4 with `--lr_anneal_steps 50000` (linear decay to zero, which is also the only stop mechanism in the released code) | | |
| | EMA | decay 0.9999 | | |
| | diffusion | T = 2,000, linear β schedule, eps-prediction, `learn_sigma` False | | |
| | sampler (test) | **respaced DDPM, 250 steps**, `clip_denoised` on | | |
| | augmentation | none — the released code has none | | |
| | input | deterministic centre 512 crops of the 600 px tiles | | |
| **The paper and the released code disagree about the learning-rate schedule.** | |
| The paper describes warmup plus cosine; the released code implements neither. We | |
| ran the code. | |
| ## Measured on the SAR2Opt test set (n = 627, 512 px) | |
| | FID↓ | DISTS↓ | LPIPS↓ | SSIM↑ | PSNR↑ | | |
| |---|---|---|---|---| | |
| | 211.8 | 0.415 | 0.686 | 0.248 | 12.48 | | |
| Evaluated on the official split's 627 test tiles, centre-cropped to 512 px. | |
| The tiles are 600 px natively; this benchmark crops and never resizes, in every | |
| method's training and in the evaluation. No subsampling: every metric on this | |
| page is measured over all 627 pairs. | |
| These are our own re-evaluation numbers, measured by us on the images this | |
| checkpoint produced. **No number here is copied from any paper.** PSNR and SSIM | |
| are per-image torchmetrics with `data_range=1`; LPIPS is **LPIPS-VGG on inputs | |
| mapped to [-1, 1]** (the `normalize=False` convention); DISTS is the standard | |
| implementation on the same pairs; FID is `pytorch-fid` against the size-matched | |
| ground-truth test set. The LPIPS convention matters: the alternative [0, 1] | |
| convention gives a systematically different number and the two must never be | |
| mixed, or compared against a paper that used the other one. | |
| ## Load it and translate one SAR image | |
| ```python | |
| import torch | |
| from guided_diffusion.script_util import (create_model_and_diffusion, | |
| model_and_diffusion_defaults) | |
| d = model_and_diffusion_defaults() | |
| d.update(image_size=512, num_channels=128, num_res_blocks=3, learn_sigma=False, | |
| diffusion_steps=2000, noise_schedule='linear', timestep_respacing='250') | |
| model, diffusion = create_model_and_diffusion(**d) | |
| model.load_state_dict(torch.load('ema_final.pt', map_location='cpu')) | |
| model.cuda().eval() | |
| # sar: (1, 3, 512, 512) float tensor in [-1, 1] | |
| sample = diffusion.p_sample_loop(model, (1, 3, 512, 512), | |
| clip_denoised=True, model_kwargs={}, | |
| noise=None, condition=sar) | |
| ``` | |
| The repository imports `blobfile` and `mpi4py` unconditionally; a single-process | |
| run on a local filesystem needs either those packages or small local stand-ins on | |
| `PYTHONPATH`. | |
| **Never pass `use_ddim=True`.** See below. | |
| ## Read before using this checkpoint | |
| * **DDIM is broken upstream, and that is not a choice we made.** | |
| `p_sample_loop(..., condition=None, ...)` accepts and threads the SAR | |
| condition; `ddim_sample_loop(...)` has **no `condition` parameter at all**, so | |
| passing `--use_ddim True` raises `TypeError`. Sampling is respaced DDPM with | |
| 250 steps, which is also what the authors' own `sample.sh` uses. | |
| * **A correctness bug in the released sampler, which we fixed.** Upstream paired | |
| each SAR image with an EO image by **unsorted `os.listdir` position** — i.e. by | |
| filesystem order. Any number produced with the unpatched sampler is measured | |
| against effectively arbitrary ground truth. We sort both listings. If you | |
| reproduce this row from a clean upstream checkout, apply that fix or your | |
| metrics are meaningless. | |
| * **Three further changes we made**, all commented in place: the | |
| distributed-init helper no longer overwrites `CUDA_VISIBLE_DEVICES` (upstream | |
| pins rank % 8, which on a shared machine hijacks another user's device); the | |
| noise tensor for a partial last batch is shaped from the batch rather than from | |
| the `--batch_size` flag; and the sampler takes explicit input/output directories | |
| and builds its resize transform at run time, because the module-level transform | |
| hard-codes 256 px and would silently downsize the 512 px cell. | |
| * **The training loader requires integer filenames.** It sorts with | |
| `int(stem)`, so any non-numeric stem raises `ValueError`. Feed it an | |
| integer-named adapter directory and keep a manifest to map back to the real | |
| stems. | |
| * **Do not let the released 512 px path resize.** The fork's `center_crop_arr` | |
| *resizes* 600 → 512. We wrote deterministic centre-512 crops instead, to keep a | |
| crop-not-resize protocol across the whole benchmark. | |
| * Passes the identity-collapse audit on both datasets. | |
| ## Licence — stated factually ⚠ no upstream licence exists | |
| **The upstream code base publishes no licence.** | |
| [`Coordi777/Conditional-Diffusion-for-SAR-to-Optical-Image-Translation`](https://github.com/Coordi777/Conditional-Diffusion-for-SAR-to-Optical-Image-Translation) | |
| has no LICENSE, LICENCE, COPYING or NOTICE file anywhere in the tree we trained | |
| from, no licence section in its README, and the GitHub API reports no declared | |
| licence, with the `/license` endpoint returning 404. Checked 2026-08-28. | |
| Under default copyright that means **all rights are reserved by the authors and | |
| no express permission to redistribute derived work has been granted** to us or | |
| to you. We publish this checkpoint anyway and state the position plainly. Assess | |
| redistribution for yourself; consider asking the authors. | |
| **A second gap, which is about reproducibility rather than licensing.** Our | |
| vendored copy of this repository carries no version control and records no | |
| upstream URL inside its tree, so **the exact commit these weights were trained | |
| from cannot be recovered**. A "clone upstream, then apply our patch" recipe is | |
| therefore not possible for this row. | |
| **Lineage.** The README states the repository is based on | |
| `openai/guided-diffusion` with modifications, and the tree is visibly that code | |
| base — OpenAI provenance comments survive in `guided_diffusion/logger.py` and | |
| `guided_diffusion/unet.py`. `openai/guided-diffusion` is **MIT**; the unmodified | |
| guided-diffusion parts carry that licence, which does **not** extend to the | |
| authors' modifications. We do not ship the guided-diffusion licence text here | |
| because it is not vendored in the tree we trained from — take it from that | |
| repository if you need it, and make sure the copyright line you carry is | |
| OpenAI's rather than another project's MIT file. | |
| **We modified the code further**, and say so as a matter of discipline rather | |
| than because any licence compels it: the four changes listed in the section | |
| above, of which the sorted-listing fix is a correctness fix. | |
| Please cite: Bai, Pu and Xu, *Conditional Diffusion for SAR to Optical Image | |
| Translation*, IEEE Geoscience and Remote Sensing Letters, | |
| [doi:10.1109/LGRS.2023.3337143](https://doi.org/10.1109/LGRS.2023.3337143). | |
| The full record of what we checked, per method, is in | |
| `licenses/NO-UPSTREAM-LICENSE.md` at the root of this repository. | |
| --- | |
| Part of the **ReFlowSET** release. This folder holds one comparison-method | |
| checkpoint that we retrained ourselves on SAR2Opt; it is not ReFlowSET | |
| itself. Every comparison method in this repository was retrained by us on the | |
| same splits at the same resolution and scored through one evaluation pipeline, | |
| so the rows are directly comparable to each other — and, for the same reason, | |
| **not** directly comparable with the numbers in the methods' own papers. | |