JeonghyeokDo's picture
Upload folder using huggingface_hub
bf48bd4 verified
|
Raw
History Blame Contribute Delete
9.28 kB

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; 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, a modified copy of 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

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 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. 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.