llir / RESTORMER_FGP_IMPROVEMENTS.md
linxin02's picture
Upload portable Low_light_rainy_new code export
4336727 verified
# Restormer FGP 改进说明
本文档总结当前低光照去雨任务中,基于原始 Restormer baseline 所做的网络、训练、验证和日志保存改进。
## 1. 总体变化
原始版本:
```text
Restormer
RGB input
-> Restormer Encoder-Decoder
-> RGB output
Loss: L1
Val: 每个 epoch 测试
Checkpoint: 每个 epoch 保存
```
当前改进版:
```text
RestormerLowLightRain / FGP-Restormer
RGB input
-> illumination / structure / frequency prior extraction
-> multi-scale prior encoder
-> soft/hard mixture-of-frequency experts
-> global-local degradation router
-> Restormer Encoder-Decoder with multi-scale prior fusion
-> RGB output
Loss: Charbonnier + Edge + FFT
Val: 每 5 epoch 测试
Checkpoint: 每 5 epoch 保存,best 单独保存
Metrics: metrics.csv 逐 epoch 记录
```
对应核心文件:
- `net/restormer_lowlight_rain.py`:网络结构改进。
- `train_restormer.py`:训练、loss、EMA、验证、日志保存。
- `utils/inference_utils.py`:验证阶段 padding、crop、PSNR、TTA。
- `run_restormer_fgp.sh`:当前 FGP 版本启动脚本。
## 2. 网络结构改进
### 2.1 从原始 Restormer 改到 FGP-Restormer
从:
```text
Restormer()
```
改到:
```text
RestormerLowLightRain()
```
训练入口中通过参数选择:
```bash
--model fgp_restormer
```
对应代码位置:
```text
train_restormer.py
build_model()
```
原始 Restormer 只使用 RGB 图像本身作为输入特征,当前版本在 Restormer 主干之外增加了一个先验分支,用于显式建模低光照和雨纹退化。
## 3. 先验提取改进
### 3.1 从单纯 RGB 输入改到五类退化先验
从:
```text
RGB input only
```
改到:
```text
RGB input
-> luminance
-> darkness
-> high-frequency response
-> structure edge response
-> rain residual
```
对应模块:
```text
net/restormer_lowlight_rain.py
PriorMapExtractor
```
具体五类先验:
| 先验 | 作用 |
|---|---|
| `luminance` | 表示亮度分布,用于低光照恢复 |
| `darkness` | 表示暗区域强度,引导曝光/照明增强 |
| `high` | Laplacian 高频响应,用于捕捉雨纹和细节 |
| `structure` | Sobel 边缘结构,用于保护物体轮廓 |
| `rain_residual` | `luminance - low_frequency` 的正残差,用于突出局部雨纹/亮 streak |
原始 Restormer 没有显式区分低频照明和高频雨纹;当前版本把低光和去雨拆成不同先验,更符合低光照去雨的退化特性。
## 4. 多尺度先验编码
### 4.1 从无先验分支改到 MultiPriorEncoder
从:
```text
RGB -> patch_embed -> encoder
```
改到:
```text
RGB -> PriorMapExtractor -> MultiPriorEncoder
-> prior_1 H x W
-> prior_2 H/2 x W/2
-> prior_3 H/4 x W/4
-> prior_4 H/8 x W/8
```
对应模块:
```text
net/restormer_lowlight_rain.py
MultiPriorEncoder
```
这让先验可以在 Restormer 的 4 个 encoder scale 上逐层注入,而不是只在输入层简单拼接。
## 5. 频率专家 MoE 改进
### 5.1 从单一特征变换改到 Mixture-of-Frequency Experts
从:
```text
main feature -> conv/attention -> output feature
```
改到:
```text
main feature
-> low-frequency expert
-> high-frequency expert
-> structure expert
-> router selects / blends experts
-> expert feature
```
对应模块:
```text
net/restormer_lowlight_rain.py
FrequencyExpertMixer
```
三个专家分别负责:
| Expert | 作用 |
|---|---|
| Low-frequency expert | 处理低光照、曝光、照明不均 |
| High-frequency expert | 处理雨纹、高频退化、细节恢复 |
| Structure expert | 处理边缘、轮廓、结构保持 |
### 5.2 从统一 soft 路由改到浅层 soft + 深层 hard 路由
从:
```text
所有层使用同一种融合方式
```
改到:
```text
浅层 encoder: soft expert routing
深层 encoder / latent: hard expert routing
```
对应代码:
```text
RestormerLowLightRain.__init__()
fuse1 = FrequencyPriorFusion(..., hard_expert=False)
fuse2 = FrequencyPriorFusion(..., hard_expert=False)
fuse3 = FrequencyPriorFusion(..., hard_expert=True)
fuse4 = FrequencyPriorFusion(..., hard_expert=True)
```
设计动机:
- 浅层特征保留更多低级纹理和退化线索,适合 soft routing。
- 深层特征更接近语义和重建决策,适合 hard routing 强化专家分工。
这个设计参考了近期 all-in-one restoration / adverse weather restoration 中的 MoE routing 思路。
## 6. Global-Local Router 改进
### 6.1 从普通 concat fusion 改到全局-局部动态路由
从:
```text
concat(main_feat, prior_feat) -> conv -> residual add
```
改到:
```text
main_feat + prior_feat
-> global degradation router -> channel gate
-> local weather/texture router -> spatial mask
-> global-local gate
-> gated prior fusion
```
对应模块:
```text
net/restormer_lowlight_rain.py
GlobalLocalRouter
FrequencyPriorFusion
```
其中:
- `global_router` 通过全局平均池化感知整图退化类型,例如整体低光、整体雨强。
- `local_router` 通过卷积生成局部空间 mask,关注局部雨纹、边缘、暗区。
这样可以同时处理:
- 全局低光照问题。
- 局部雨纹/高频 streak。
- 结构边缘恢复。
## 7. 多尺度融合方式
### 7.1 从 Restormer 原始 encoder 改到 encoder 每层注入先验
从:
```text
out_enc_level1 = encoder_level1(inp_enc_level1)
out_enc_level2 = encoder_level2(inp_enc_level2)
out_enc_level3 = encoder_level3(inp_enc_level3)
latent = latent(inp_enc_level4)
```
改到:
```text
out_enc_level1 = encoder_level1(inp_enc_level1)
out_enc_level1 = fuse1(out_enc_level1, prior_1)
out_enc_level2 = encoder_level2(inp_enc_level2)
out_enc_level2 = fuse2(out_enc_level2, prior_2)
out_enc_level3 = encoder_level3(inp_enc_level3)
out_enc_level3 = fuse3(out_enc_level3, prior_3)
latent = latent(inp_enc_level4)
latent = fuse4(latent, prior_4)
```
这样主干仍然是 Restormer,但每个 scale 都受到低光/雨纹/结构先验引导。
## 8. 训练数据改进
### 8.1 从依赖旧 DataLoader 改到显式 paired dataset
从:
```text
get_training_data(opt.TRAINING.TRAIN_DIR, ...)
```
改到:
```text
PairedPatchDataset(
train_inp = ./dataset/train/syn+real/input,
train_tar = ./dataset/train/syn+real/target
)
```
对应代码:
```text
train_restormer.py
PairedPatchDataset
```
当前训练集明确为:
```text
/media/home/songmeixi_insta360.com/Low_light_rainy_new/dataset/train/syn+real/input
->
/media/home/songmeixi_insta360.com/Low_light_rainy_new/dataset/train/syn+real/target
```
不使用:
```text
dataset/train/syn+real/target_smoke
```
这样可以避免 smoke 任务和低光照去雨任务混杂。
## 9. Loss 改进
### 9.1 从 L1 Loss 改到 Charbonnier + Edge + FFT Loss
从:
```text
loss = L1(output, target)
```
改到:
```text
loss = Charbonnier(output, target)
+ edge_weight * L1(edge(output), edge(target))
+ fft_weight * L1(FFT_amp(output), FFT_amp(target))
```
对应代码:
```text
train_restormer.py
RestorationLoss
```
启动参数:
```bash
--loss_mode charbonnier_edge_fft
```
各项作用:
| Loss | 作用 |
|---|---|
| Charbonnier | 比 L1 更平滑,常用于图像复原 |
| Edge loss | 保持边缘和结构,减少去雨后的模糊 |
| FFT loss | 约束频率幅度,提升高频细节和雨纹去除一致性 |
## 10. EMA 改进
### 10.1 从直接验证当前权重改到 EMA 权重验证
从:
```text
validate(model)
```
改到:
```text
ema.update(model)
validate(ema_model)
```
对应代码:
```text
train_restormer.py
ModelEma
```
启动参数:
```bash
--use_ema
```
EMA 可以降低训练震荡,让验证 PSNR 更稳定。
## 11. 验证协议改进
### 11.1 从直接整图推理改到 factor-8 padding + crop
从:
```text
output = model(input)
psnr = PSNR(output, target)
```
改到:
```text
padded_input = pad_to_factor(input, factor=8)
output = model(padded_input)
output = crop_to_original_size(output)
output = clamp(output, 0, 1)
psnr = RGB_PSNR(output, target)
```
对应代码:
```text
utils/inference_utils.py
pad_to_factor
crop_to_size
run_model
batch_rgb_psnr
```
Restormer 有多次 downsample/upsample,factor-8 padding 可以避免尺寸不能被 8 整除时的潜在问题。
### 11.2 从每个 epoch 测试改到每 5 epoch 测试
从:
```bash
--val_every 1
```
改到:
```bash
--val_every 5
```
这样减少测试时间开销,适合长时间训练。
## 12. Checkpoint 保存改进
### 12.1 从每个 epoch 保存改到每 5 epoch 保存
从:
```text
model_1.pth
model_2.pth
model_3.pth
...
```
改到:
```text
model_5.pth
model_10.pth
model_15.pth
...
model_best.pth
```
对应参数:
```bash
--save_every 5
```
说明:
- `model_{epoch}.pth`:每 5 个 epoch 保存一次。
- `model_best.pth`:只要验证 PSNR 创新高就保存。
## 13. 指标记录改进
### 13.1 从只打印终端改到保存 metrics.csv
从:
```text
terminal only:
Epoch loss / Val PSNR
```
改到:
```text
checkpoint_restormer_fgp/Deraining/models/RestormerFGP/metrics.csv
```
字段:
```text
epoch,train_loss,lr,val_psnr,best_psnr,epoch_time,saved_checkpoint,is_best
```
对应代码:
```text
train_restormer.py
append_metrics_csv
```
说明:
- 每个 epoch 都会写一行。
- 非测试 epoch 的 `val_psnr` 为空。
- 保存普通 checkpoint 的 epoch,`saved_checkpoint=1`
- PSNR 刷新 best 的 epoch,`is_best=1`
## 14. 当前启动方式
当前使用:
```bash
bash run_restormer_fgp.sh
```
脚本内容等价于:
```bash
python train_restormer.py \
--config training.yml \
--model fgp_restormer \
--session RestormerFGP \
--save_dir ./checkpoint_restormer_fgp \
--loss_mode charbonnier_edge_fft \
--use_ema \
--val_every 5 \
--val_pad_factor 8 \
--save_every 5 \
--metrics_file metrics.csv \
--resume ./checkpoint_restormer_fgp/Deraining/models/RestormerFGP/model_5.pth
```
## 15. 当前版本的一句话概括
当前版本从原始 Restormer 改成了一个面向低光照去雨的结构感知频率专家 Restormer:
```text
Plain Restormer
-> Structure-aware Mixture-of-Frequency Prior Restormer
-> Low-light / rain / structure prior guided multi-scale restoration
```
核心 novelty 可以概括为:
```text
Structure-aware Mixture-of-Frequency Prior Guidance
for Low-Light Rainy Image Restoration
```