Skip to content
mumusama75Public

About

CS33 Capstone: event-conditioned diffusion for structure-preserving low-light image enhancement.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

CS33 Capstone: Event-Conditioned Diffusion for Low-Light Image Enhancement

An independent, paper-guided implementation of EcDiff-LLIE for structure-preserving low-light image enhancement with event-camera conditioning. This repository also preserves the earlier HDRev / Stable Diffusion experimental branch that led to the current design. It contains the model, training and evaluation pipeline, reproducibility safeguards, ablation utilities, and experiment configurations used in the CS33 capstone project.

This is not the authors' official implementation. Architectural details not disclosed in the paper are documented as explicit reproduction choices.

Project highlights

  • Event-conditioned diffusion model trained directly on paired low-light RGB, event voxels, and normal-light targets.
  • Multi-scale image/event network with FEB feature extraction and CMAB cross-attention conditioning.
  • Numerically stable FP32 training with resumable checkpoints, validation-based model selection, gradient safeguards, and W&B experiment tracking.
  • Controlled investigations of DDIM timestep spacing, attention normalization, cropped versus full-frame training, and historical EvLight comparison.
  • Data-leakage checks, scene-disjoint validation, per-scene reporting, deterministic evaluation seeds, PSNR/SSIM/LPIPS metrics, and extensive automated tests.

Current best result

The best retained checkpoint is the 152,000-step EcDiff model, evaluated on a scene-disjoint 1,354-frame SDE indoor validation set with endpoint-spaced 30-step DDIM sampling:

Metric Result
PSNR 19.8825 dB
SSIM 0.6096
LPIPS (AlexNet) 0.2103

Relative to the 27,000-step starting checkpoint under the same evaluation protocol, it improved PSNR by 2.4092 dB, SSIM by 0.0706, and LPIPS by 0.1198. Results are reported under the repository's documented metric protocol and should not be interpreted as an official-paper reproduction score.

Repository scope

The repository intentionally excludes datasets, manifests containing machine-specific paths, checkpoints, W&B caches, generated images, and training outputs. Reproducing the reported result requires preparing the SDE data and supplying the trained checkpoint separately.

Project evolution

The project has two clearly separated research branches:

  1. Legacy HDRev branch (Experiments 1–5C): an event-conditioned Stable Diffusion / ControlNet pipeline adapted from the external HDRev architecture. It established zero-shot baselines, rigorous scene-separated fine-tuning, FEB-Lite event enhancement, and structure-loss ablations. The project-specific scripts and experiment notes are preserved in legacy_hdrev/; third-party source and weights are not redistributed.
  2. Current EcDiff branch: the standalone implementation at the repository root. It uses a compact multi-scale diffusion network with FEB and cross-attention and does not load an HDRev checkpoint.

The historical HDRev metrics and the current EcDiff metrics use different evaluation subsets/protocols, so they should not be treated as a direct leaderboard comparison.

The sections below preserve the implementation notes and experiment history used during development.

2026-09-22 W&B 实时日志与输出

configs/sde_indoor_recovery_logged_20260922.json 与稳定性试验配置的模型、训练、数据和采样参数完全相同,只开启 W&B 中文名称/备注、控制台日志与文件同步。训练从第 9,000 步检查点继续到累计 30,000 步,旧记录保留;切换时重放 1 个未保存更新。

  • Logs:实时控制台;SDK 同步完成后可下载 output.log。
  • Files/logs:每 100 步训练指标与每次验证结果;服务器 train.jsonl 仍保留每一步的完整记录,批次 ID 不上传到控制台或这些指标文件。
  • Files/outputs/validation_*.zip:预测图片、low / prediction / GT 对比图、逐图指标和汇总。
  • Files/checkpoints/latest.pt、best.pt:最近权重与固定 12 张验证监测图上的最优权重。各历史步数权重仍保存在服务器,不重复上传整个历史目录。
  • 这些上传选项默认关闭,仅新配置明确开启。文件通过训练进程中的 W&B SDK 持续同步,没有额外定时任务,也没有修改训练目标。

70 项测试通过,包含真实 SDK 离线控制台事件捕获、文件保存、恢复一致性和上传白名单检查。新运行:EcDiff - 3万步稳定性试验 - 日志与输出已连接。

2026-09-22 稳定性修复说明

原 400,000 步实验 sde_indoor_fp32_workers4_20260921 已结束,但训练失稳、原采样输出非有限值。该实验及原代码已备份,不能把权重存在或 W&B finished 视为复现成功。下方原有的“未训练”“无卡模式”等表述是 2026-09-18 的历史环境记录,不代表当前运行状态。

新变体配置为 configs/sde_indoor_recovery_20260922.json,原论文配置保持不变。变体使用学习率 1e-4、梯度裁剪 1.0、独立验证场景、历史检查点、验证图片和异常停止;仍为 FP32、batch 6、patch 200、epsilon MSE,不改变模型结构。它是稳定性实验,不宣称与论文训练协议相同。

  • 从原 train 用 seed 1234 留出 i_0/i_117/i_123/i_78 四个完整场景:训练 12,223 帧,完整验证 1,354 帧。周期性监测每个验证场景首/中/末三帧,共 12 帧;best 仅按这个固定监测子集选择,不是完整验证/测试集最优。原 test 2,741 帧未参与划分或调参。
  • 每步保存 loss、裁剪前梯度范数、噪声预测幅度、事件幅度与 batch ID;W&B 不上传 batch ID,只上传白名单数值与明确启用的验证对比图。对比图从左到右为 low / prediction / GT。
  • use_clipped_model_output=true 在裁剪预测 x0 后重新计算一致的 epsilon,避免继续使用原来不匹配的巨大预测值。此选项默认关闭,原配置行为不静默改变;无论是否启用,采样各步均检查非有限值并报出时间步。这个修正不能把训练坏的权重变成高质量模型。
  • loss 大于 10 立即停止;每 100 步取中位数,1,000 步后若连续 3 个窗口超过此前最佳窗口的 10 倍则停止。这些是本次试验的保护阈值,不是通用收敛标准。
  • 保存 initial.pt、latest.pt、best.pt 与 checkpoints/step_*.pt;恢复训练不覆盖历史日志,保护器状态随检查点恢复。多 worker 的随机增广仍不保证逐位续训。
  • 正常完成写 completion.json;运行期异常写 failure.json,包含阶段、步数和 batch ID。失败不会伪装为完成;应先查看验证图片与指标。
  • 先完成 500 步真实数据检查和权重重新加载出图,再决定是否继续 30,000 步稳定性试验。不会自动从短跑升级为 400,000 步长训。

修复后的 64 项测试已通过,记录为 verification/recovery_tests_20260922.txt。数据划分记录为 verification/recovery_split_20260922.json。本次配置同时改变了多项设置,后续效果变化不能仅归因于学习率。

数值处理参考:Diffusers DDIM 的 clipped-output 修正、PyTorch 梯度范数裁剪。

服务器项目:/root/autodl-tmp/projects/Ecdiff。这是依据用户提供论文重新实现的 paper-based baseline,不是作者官方源码,也不是把 HDR/HDRev 项目改名。

该段最初记录的是 2026-09-18 的预训练阶段。此后已完成正式训练与验证;当前最佳结果见本文顶部。数据集与 checkpoint 仍不包含在本仓库中。

1. 实现内容与边界

  • 双分支多尺度 MMDN:image path + event path,宽度 32/64/128/256/128/64/32。
  • FEB:1×1、3×3 depthwise、3×3 dilated 三支路,SE ratio 16。
  • CMAB:时间条件 ResNet、image Query / event Key-Value 通道交叉注意力、gated FFN。
  • Cosine DDPM,500 个训练时间步,唯一训练目标为 epsilon MSE;默认 30 步确定性 DDIM。
  • 5-bin event voxel、同步 crop/flip、manifest 驱动的 SDE/SDSD 配对读取。
  • Adam 训练、配置/seed/清单 hash 记录、断点恢复、验证集选模、独立推理评估。
  • PSNR、SSIM;可选已有缓存权重的 LPIPS。GT 不进入推理网络,只用于事后算指标。
  • 消融接口:conditioning=image_only、逐层 conditioning=concat、use_se=false。消融接口存在不代表已完成消融实验。

论文报告 8.25M 参数,本实现实测 7,127,097(约 7.13M)。论文没有公开每尺度重复数、heads、FFN 倍率等完整设置;当前实现不能保证与作者网络逐层一致,不通过随意加层凑参数量。所有缺失细节和选择见 论文规格。

重要区别:同学 Exp5B/C 的额外结构损失不是论文 baseline 的训练目标。参考范围和归属见 参考说明。

2. 目录

Ecdiff/
├── README.md
├── requirements.txt           # 依赖声明;本轮没有执行安装
├── train.py                   # 训练与恢复
├── evaluate.py                # 有 GT 评估 / 无 GT 推理
├── legacy_hdrev/              # 早期 HDRev/SD/ControlNet 实验增量与 4A–5C
├── ecdiff/
│   ├── models.py              # MMDN / FEB / CMAB
│   ├── diffusion.py           # DDPM / DDIM
│   ├── data.py                # 图像/事件/清单读取
│   ├── runtime.py             # 配置、随机状态、checkpoint
│   ├── tracking.py            # 可选 W&B 标量日志与安全恢复关联
│   ├── metrics.py
│   └── evaluation.py
├── configs/
│   ├── sde_indoor.json
│   ├── sde_outdoor.json
│   ├── sdsd_indoor.json
│   ├── sdsd_outdoor.json
│   └── smoke.json             # 小网络,仅用于流程测试
├── scripts/
│   ├── build_manifest.py
│   ├── split_manifest.py
│   ├── smoke_test.py
│   └── check_real_samples.py  # 四个指定序列各一个样本
├── tests/
├── docs/
│   ├── PAPER_SPEC.md
│   └── REFERENCE_NOTES.md
└── verification/              # 本轮服务器验证记录

# 以下是未来使用时生成,不是复制 Dataset:
# manifests/                  # 样本路径/配对规则 JSON
# runs/                       # checkpoint、日志、预测结果

默认 outputs 位于数据盘项目内。Dataset 只通过现有绝对路径读取,不复制、不移动、不写入原始数据。相对 config 中的 manifest/output 路径以项目根目录为基准;命令行显式路径以当前目录为基准。

3. 现有环境与验证

已使用服务器 /root/miniconda3/bin/python,Python 3.12.3、PyTorch 2.8.0+cu128。当前无卡模式 torch.cuda.is_available()==False 正常;没有进行 RTX 5090 的运行验证。

2026-09-18 已实测:39 项自动测试全部通过(0 failures / 0 errors / 0 skipped);包括使用已有缓存且禁止下载的 LPIPS 测试,以及跨 epoch 的逐位一致续训测试。SDE indoor/outdoor、SDSD indoor/outdoor 各读取一帧 346×260,5-bin 体素和 32×32 crop 前向均通过;SDE indoor 还通过反向梯度与默认 30 步 DDIM 检查。没有进行真实数据参数更新。

最终验证记录位于 verification/smoke_cpu_release_20260918.json、verification/real_samples_verified_20260918/report.json。早期 real_samples_20260918/ 是路径修正前中断留下的单帧诊断清单,不是完整通过报告;保留记录,没有混入正式训练清单。

日常阅读、代码开发、小型测试可以无卡运行。正式训练应切换 RTX 5090 32GB 后先检查 GPU,验证默认 batch 6 / patch 200 的实际显存占用再长跑。当前容器内存限制约 2GiB;不要在无卡模式启动正式规模训练。

小规模验证入口(每次报告用一个新文件名):

cd /root/autodl-tmp/projects/Ecdiff
OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 PYTHONDONTWRITEBYTECODE=1 \
  /root/miniconda3/bin/python scripts/smoke_test.py

测试包括数据异常检查、扩散数值公式、条件/梯度、DDIM oracle、训练/恢复、测试集泄漏保护、无 GT 推理和 SSIM 独立数值对照。测试中的优化只使用自建小型合成数据和小网络,临时文件由测试清理;不用于声称论文性能。

4. 数据配对:先确认,再生成完整清单

Domain 现有数据入口 明确选择的配对模式
SDE indoor /root/autodl-tmp/datasets/SDE/aligned/indoor evlight-sde-order
SDE outdoor /root/autodl-tmp/datasets/SDE/aligned/outdoor evlight-sde-order
SDSD indoor /root/autodl-tmp/datasets/SDSD/evlight_ready/indoor evlight-sdsd-order
SDSD outdoor /root/autodl-tmp/datasets/SDSD/evlight_ready/outdoor evlight-sdsd-order

默认 exact 要求 low / event / GT 同 stem,失败不会偷偷改为顺序配对。

  • SDE:low 与 NPZ 同 timestamp;GT 使用另一组 timestamp,显式按 release 排序配对。
  • SDSD:low / normal 起始索引有偏移,NPZ 从零重新编号;显式采用等长发布顺序。--trim-start 3 --trim-end 2 才启用 EvLight 的 [3:-2],不是自动套用的论文已知设置。
  • SDE 若存在恰好多一张末尾 RGB 的序列,须核对后显式指定 --drop-trailing-image;不会静默截断。
  • 当前 SDSD outdoor 的 NPZ 在 low,而官方 EvLight loader 指向 normal;当前代码不自动换源。事件模拟参数是否等于论文的 v2e default noisy、实际曝光/事件时间窗同步仍待核验。
  • HDF5 连续事件流需要帧时间窗元数据和显式导出。这里不把整段 H5 当作单帧事件,不用 HDR-EVS H5 替代 SDE/SDSD。
  • 事件读入默认 [t,x,y,p],支持其他显式列顺序;0/1 polarity 转为 -1/+1。事件非零标准化、RGB [-1,1] 是公开的实现选择。

只检查一个序列的两个样本:

python scripts/build_manifest.py \
  --root /root/autodl-tmp/datasets/SDE/aligned/indoor \
  --dataset SDE-indoor --split train --sequences i_0 \
  --pairing evlight-sde-order --max-samples 2 \
  --output manifests/sde_indoor_sample.json

未来确认配对与划分后,完整训练清单才去掉 --sequences / --max-samples,输出 manifests/sde_indoor_train.json。另用 --split test 生成测试清单。其他三域分别使用表中路径/模式。构建器只枚举所选序列的浅层文件名,不加载全部图片;现有输出文件拒绝覆盖。

如果需要验证集,从原 train 按明确场景留出,不能从 test 挑参数:

python scripts/split_manifest.py \
  --manifest manifests/sde_indoor_train_full.json \
  --val-scenes i_0 \
  --train-output manifests/sde_indoor_train_holdout.json \
  --val-output manifests/sde_indoor_val.json

i_0 仅为命令示例,不是本项目替你选定的验证集。留出会减少论文原训练集,必须作为不同协议报告;默认论文配置没有自动留出。训练入口拒绝 train/val 场景或图像/事件路径交叠、拒绝把 test 用作验证集。

5. 正式训练(本轮未执行)

配置保留论文值:Adam 1e-3,batch 6,patch 200,SDE 400k / SDSD 350k updates,每 500k 乘 0.8。因此默认总步数内不会发生第一次学习率衰减,不能擅自把 500k 改成 50k。

python train.py --config configs/sde_indoor.json --device cuda

切换其他数据域时用对应 config。默认不启用 AMP、EMA、额外 loss、classifier-free guidance、梯度裁剪或 event 去噪过滤。需要提速时可以显式修改配置,但要记录为实验设置;推荐在 tmux 内长跑。

每个新 run 拒绝复用已有目录。保存 latest.pt、JSONL loss、实际配置、manifest SHA-256、运行环境。仅 hash 小型清单,不 hash Dataset。只有配置了独立 val manifest 且 training.validate_every > 0 才产生验证指标和 best.pt;默认用固定训练步数结束的 latest.pt,不在 test 上挑模型。

恢复示例:

python train.py --config configs/sde_indoor.json --device cuda \
  --resume runs/sde_indoor_seed1234/latest.pt

恢复 model/Adam/scheduler/scaler/随机状态与样本批次位置。中断后比 checkpoint 新的日志不删除;重放步骤的新日志写入 resumes/ 分段。允许 --output 指向一个新目录保留分支实验;旧 checkpoint 不能覆盖更晚的同目录 run。

默认 num_workers=0 可精确恢复本实现的数据增广随机序列;多 worker 的预取/随机增广无法保证逐位恢复。GPU 跨版本/硬件也不保证逐位一致。checkpoint 使用 pickle 保存 RNG/优化器,只能加载可信文件。

6. 推理与评估(需要自己的已训练权重)

python evaluate.py \
  --checkpoint runs/sde_indoor_seed1234/latest.pt \
  --manifest manifests/sde_indoor_test.json \
  --output runs/sde_indoor_test_seed1234 --device cuda --lpips

输出逐图 PNG、per_image.csv、summary.json 和评估配置;输出目录必须是新的。没有 gt 的清单也可以推理,但不会计算有参考指标。--max-samples 仅用于调试子集,不算完整 benchmark。

默认全帧 RGB float [0,1]、不裁边、不做亮度匹配;PSNR 按图算后平均;SSIM 为 Gaussian 11×11/sigma1.5、population covariance。LPIPS 使用 AlexNet v0.1;只允许使用已缓存的 backbone,不自动下载。论文没公开这些指标的完整实现,必须注明协议。

DDIM 默认遵循论文 Algorithm 2 的表达式并向下取整:500/30 时最高采样时间步为 484 而非 500。--timestep-spacing endpoint 是包含 500 的可比较变体。配置中 clip_denoised=true 表示每步对估计 x0 做范围裁剪,这是实现选择,不是论文明确参数;评估可用 --no-clip-denoised 关闭逐步裁剪,最终输出图像仍会裁至显示范围。

7. 下一阶段

  1. 核验发布数据的完整 scene 划分、SDSD 事件来源与配对规则,再生成完整清单。
  2. 对未公开的网络细节建立可追踪的配置对照,解释与 8.25M 的参数差异。
  3. GPU 模式验证完整尺寸、显存、吞吐,再进行正式训练和独立 test 评估。
  4. 记录多 seed、quantitative / qualitative / ablation 实验,最后再加入自己的改进。

HUE 的具体数据适配、BRISQUE、论文 Table 2 的独立 generic-diffusion 对照和完整三 seed 实验尚未完成;不要把接口已写好等同于论文实验已完成。

8. W&B 实验记录

已配置到用户指定的现有项目:

2026-09-18 使用服务器已有登录,通过只读 Public API 确认可访问并查到 22 个 runs。使用现有 wandb==0.29.0,没有重新登录、输出/存储 API Key 或更改账号配置;没有创建云端连接测试 run,也没有修改原 runs 的配置、指标或可见性。只读访问不代表已经实测云端写入权限,第一次正式 online run 才会验证写入。

接入后的 50 项自动测试已通过,包含真实 SDK 的离线训练/恢复/评估检查、与不启用 W&B 时逐位一致的权重对照,以及隐私与随机状态的假 SDK 测试。记录见 verification/wandb_integration_final_20260918.json;只读连接报告见 verification/wandb_access_20260918.json。没有启动正式训练。

四个正式数据域配置的 wandb.mode 默认是 online,只有执行训练/评估入口时才会创建新的 run。configs/smoke.json 默认 disabled;自动测试中的 SDK 集成检查被强制设为 offline,只用临时合成数据,不向云端上传测试 runs。

记录白名单超参和标量:训练 loss、learning rate、更新步数、耗时;独立验证/评估的 PSNR、SSIM,以及实际启用计算时的 LPIPS。无 GT 推理不会伪造这些精度指标。只保存 manifest 的小型 SHA-256 标识,不上传 manifest 内容、Dataset、图片、checkpoint、源码、终端输出或环境变量;自动 Git、机器元数据和系统采集均关闭。SDK 自身仍保留运行所需的服务日志。

默认在每个本地 run/恢复分段目录保存 wandb.json(run ID、URL、父 run ID 等非敏感记录)以及 SDK 日志。每次启动/恢复生成新的 segment run,以 train/global_step 为指标横轴,父 run ID 仅作关联;不会重写历史 run,也不会因 checkpoint 重放而覆盖旧历史。SDK 调用隔离训练随机状态。

# 仅检查连接,不创建/修改 runs
python scripts/check_wandb.py

# 正式 GPU 训练:按配置自动连接上述项目(本轮没有执行)
python train.py --config configs/sde_indoor.json --device cuda

# 暂时只在本地保存 W&B 日志,不自动同步
python train.py --config configs/sde_indoor.json --device cuda --wandb-mode offline

# 完全关闭 W&B(不导入 SDK、不联网)
python train.py --config configs/sde_indoor.json --device cuda --wandb-mode disabled

evaluate.py 继承 checkpoint 中的 W&B 配置,并支持同样的 --wandb-mode 覆盖;评估用新 run,标为 eval,与训练 run 关联。旧 checkpoint 不含 W&B 配置时默认关闭,可显式传 --wandb-mode online 使用上述项目。

如认证失效,应在服务器自己的终端完成安全登录,不要将 API Key 粘贴进聊天、代码或 Git。离线记录只有在你明确决定同步时才同步。

接入依据:W&B init、SDK Settings、只读 Public API。

About

CS33 Capstone: event-conditioned diffusion for structure-preserving low-light image enhancement.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages