second-ckpts / README.md
chicagoypark's picture
Move VAE checkpoints into vae/
591554f verified
|
Raw
History Blame Contribute Delete
4.78 kB
---
license: apache-2.0
tags:
- vae
- autoencoder-kl
- medical-imaging
- latent-diffusion
library_name: pytorch
---
# kl16_mm3ch_gan_balanced — 130k
3-channel KL-16 VAE (LPIPS + patch-GAN) for multimodal medical imaging, trained with **balanced
cohort sampling** across BraTS 2023, SynthRAD 2023, CHAOS and AMOS 22.
Continued from `kl16_mm3ch_gan_410k.ckpt` (weights only), which had been trained with
*proportional* sampling and is therefore heavily BraTS-dominated. This checkpoint re-balances the
cohort marginal to 25% each. Snapshot at **optimizer step 130,000**.
## Architecture
`AutoencoderKL` — the LDM/CompVis encoder–decoder, matched to the MAR `kl16` layout:
| | |
|---|---|
| `embed_dim` / `z_channels` | 16 / 16 (`double_z=True`) |
| `ch` / `ch_mult` | 128 / `[1, 1, 2, 2, 4]` |
| `num_res_blocks` | 2 |
| `attn_resolutions` | `[16]` in the **encoder**, `[]` in the **decoder** |
| resolution / channels | 256 × 256, `in_channels=3`, `out_ch=3` |
| parameters | 66.46 M (312 tensors, fp32) |
Downsampling factor f = 16, so a 256×256×3 input maps to a 16×16×16 latent.
> The asymmetric attention (encoder has it, decoder does not) is inherited from the MAR `kl16`
> checkpoint this lineage started from. Instantiating a stock LDM `AutoencoderKL` with attention in
> the decoder will produce missing/unexpected keys.
## Usage
```python
import torch
from ldm.modules.diffusionmodules.model import Encoder, Decoder
DDCONFIG = dict(double_z=True, z_channels=16, resolution=256, in_channels=3, out_ch=3,
ch=128, ch_mult=[1, 1, 2, 2, 4], num_res_blocks=2,
attn_resolutions=[16], dropout=0.0)
encoder = Encoder(**DDCONFIG)
decoder = Decoder(**{**DDCONFIG, "attn_resolutions": []}) # no attention in the decoder
sd = torch.load("vae/kl16_mm3ch_gan_balanced_130k.ckpt", map_location="cpu")["model"]
# keys: encoder.* / decoder.* / quant_conv.* / post_quant_conv.*
```
Inputs are 3-channel, 256×256, scaled to `[-1, 1]`. Single-channel medical slices are replicated to
3 channels to match the backbone and the LPIPS/VGG perceptual loss.
## Training data
`content=both` — anatomical images **and** segmentation masks are both treated as samples.
| cohort | subjects (train) | train slices | natural share | sampled share |
|---|--:|--:|--:|--:|
| BraTS 2023 (GLI) | 1,188 | 736,560 | 87.5% | 25% |
| SynthRAD 2023 (Task 1) | 356 | 61,333 | 7.3% | 25% |
| AMOS 22 (abdomen) | 306 | 39,979 | 4.7% | 25% |
| CHAOS (abdomen) | 34 | 4,242 | 0.5% | 25% |
| **pooled** | **1,884** | **842,114** | | |
BraTS contributes 5 streams per subject (`t1n`, `t1c`, `t2w`, `t2f`, `seg`); SynthRAD contributes
MR + CT; CHAOS and AMOS contribute CT/MR plus liver masks. Sampling is multinomial with
replacement at a fixed per-cohort marginal, so CHAOS is oversampled roughly 25× per epoch and
BraTS is undersampled to ~0.14×.
Preprocessing: MRI normalized by per-volume non-zero (1, 99) percentiles, CT by a fixed
`[-1000, 1000]` HU window; body-bounding-box crop, pad to square, resize to 256, output in
`[-1, 1]`.
## Training configuration
| | |
|---|---|
| initialization | `kl16_mm3ch_gan_410k.ckpt`, weights only (step counter restarts at 0) |
| loss | L1 + LPIPS(VGG16) + KL (`kl_weight 1e-6`) + hinge GAN |
| discriminator | 3-layer patch critic, `disc_weight 0.5`, adaptive `d_weight = ‖∇nll‖ / ‖∇g‖ × 0.5` |
| optimizer | Adam(β = 0.5, 0.9), **constant lr 2.88e-4**, no schedule, no warm-up, fp32 |
| effective batch | 96 |
| step | 130,000 |
The 410k checkpoint carried no discriminator weights, so the critic was re-initialized. It was
first warmed up for 2,000 steps with `disc_weight = 0` — the critic trains while the generator
receives exactly zero adversarial gradient — before the full GAN objective was enabled.
## Caveats
- **The latent scale must be re-fit.** The scale factor `0.685155` belongs to
`kl16_mm3ch_gan_410k.ckpt` and is **not** valid here. Re-estimate the latent std before pairing
this VAE with any latent-space model.
- **Reconstruction-only validation drifts upward under adversarial training.** Validation scores
pure L1 + LPIPS with no GAN term; it moved from 0.0211 (10k) to ~0.0222 and then flattened. That
is the expected fidelity-for-sharpness trade, not divergence. Judge this checkpoint perceptually
or on a downstream task, not by that scalar.
- **Research use only.** Trained on public research datasets; not validated for, or intended for,
clinical use.
## Provenance
Derived from [CompVis/latent-diffusion](https://github.com/CompVis/latent-diffusion)
(`AutoencoderKL`, `LPIPSWithDiscriminator`) and the MAR `kl16` VAE lineage. Source datasets are
subject to their own licenses and access terms (BraTS 2023, SynthRAD 2023, CHAOS, AMOS 22).