# 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 ```