恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

SOTS数据集8:2划分与去雾权重加载:从训练到推理全流程解析

  • 首页
  • 资讯中心
  • /
  • SOTS数据集8:2划分与去雾权重加载:从训练到推理全流程解析

相关资讯

工艺智能规划的数据底座:CAPP与切削磨削数据库设计实践 2026/10/11 19:23:17
华为智慧电厂解决方案:从边缘采集到数据治理的落地指南 2026/10/11 19:23:17
专用线缆组件解决方案:从需求拆解到量产落地的工程实践 2026/10/11 19:23:17

最新资讯

业务同义词词库自动化维护:基于大模型挖掘用户提问中的方言与行业简称
土豆去皮机三维设计:SolidWorks建模装配与运动仿真指南
钢索缺陷检测数据集与YOLO小目标训练实战指南
为什么程序员的猫喜欢敲键盘:我的猫 Null 曾经误删测试库的惊魂一刻
ClickHouse 物化视图踩坑记:隐蔽的二次写入放大与聚合函数选择
向量数据库与图数据库协同:构建智能问答系统的混合检索架构

今日推荐

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

SOTS数据集8:2划分与去雾权重加载:从训练到推理全流程解析

发布时间:2026/10/11 19:23:17
SOTS数据集8:2划分与去雾权重加载:从训练到推理全流程解析 简介面向图像去雾与深度学习研究者这份资源包将SOTS数据集的八比二划分结果、训练完成的去雾权重以及配套推理代码整合在一起可直接用于单图像去雾实验和算法效果对比。压缩包内共有一千二百零二个文件核心是五百九十五张png与五百张jpg图像构成的数据集另有四十一个py格式的脚本覆盖模型训练、测试与推理流程整体体积约三百九十一MB。目前已有八百一十七人学习下载可见其在去雾社区具备一定参考价值。通过这份资源使用者无需自行划分数据集和重新训练模型即可加载权重对雾图进行快速推理并依据客观指标评估去雾质量同时包内训练日志与配置文件有助于分析模型收敛过程可进一步用于网络调优或作为对比实验的基线方便二次开发。1. 图像去雾最磨人的不是网络结构而是数据划分与权重可复现性图像去雾最磨人的不是网络结构选型而是数据和权重的可复现性。很多项目卡在同一个地方SOTS 原始素材拿到了但不知道怎么把有雾图和清晰图按 8:2 切好或者模型训了一轮验证集 PSNR 涨得不错换到真实场景推理偏色严重你甚至说不清是数据问题还是权重没配好。你手上这套材料——SOTS 划分好的 8:2 数据集、训练好的去雾权重、包含推理代码——正好把三件事一次补齐。数据不用重切权重不用重训推理代码拿到图就能直接出结果。这篇笔记按数据划分、权重加载、推理链路和验收指标四步讲参数和坑位一次说清。适合刚接手去雾任务的算法工程师也适合在工控机上做视觉预研的嵌入式开发者。2. SOTS 划分好的 8:2 数据集长什么样目录结构、对齐规则和训练验证边界2.1 8:2 的本质同一批清晰图拆出训练域和验证域SOTSSynthetic Objective Testing Set是 RESIDE 数据集里为客观评测去雾效果单独划出来的子集。8:2 的划分逻辑和图像分类里把作物病害图像数据集划分成训练集验证集的做法是同一套方法论先把原始图像按场景或拍摄条件分组再用固定随机种子做 shuffle最终才按 8:2 的比例切成 train 和 val 两份文件清单。你听到的“SOTS 划分好的 8:2 数据集”一般指的是代码已经把原始 SOTS 的 indoor 和 outdoor 子集整理过有雾图放 input 目录对应的清晰图放 gt 目录然后用 train.txt 和 val.txt 两份清单记录划分结果。训练脚本按清单读文件而不是临时去扫描目录这就保证了每次实验拿到的训练验证边界完全一致。这段划分的工程意义在于去雾模型非常容易过拟合。有雾图和清晰图是像素级配对如果划分时随机种子没有固定每次启动训练都会得到不同的数据集分布跑十次实验九个结果无法复现。反过来只要 8:2 的划分清单和权重绑定别人拿到同一份权重和同一份 8:2 划分推理输出完全可复现。这也是为什么我每次拿到别人整理好的去雾工程第一件事不是跑推理而是确认 train.txt 和 val.txt 里的文件行数与目录里实际文件数对得上。文件数对不上权重就成了黑匣子后面所有的效果分析都没有意义。这里有一个去雾任务特有的细节雾是附着在场景上的同一个场景的不同裁剪块雾浓度在局部差异很大。如果划分时只按文件名 shuffle 而不按场景分组训练域和验证域里可能出现同一栋楼、不同雾浓度的两个图验证集指标虚高。我处理过的项目里较规范的划分是按场景 ID 做 group split确保同一场景不会同时出现在训练和验证两侧。你在复现这份 8:2 数据集时要先确认它到底是按文件名简单切还是按场景组切——这决定了后续所有实验结论的可信度。顺带说一句这套拆法跟叶片病害图像数据集划分时强调的“同一植株不跨集”是同一个原则都是为了避免数据泄漏。如果发现清单里存在场景混串最稳的办法是重新生成划分不要硬着头皮往下训。2.2 目录结构怎么辨认input 与 gt 的命名配对SOTS 原始素材的命名并不统一室内室外两个子集各有自己的序号编码。整理好的工程一般会先把两列清单写出来第一列是有雾图路径第二列是清晰图路径行号一一对应。我处理过的去雾项目里整理后的目录结构长这样dataset_sots_8_2/ ├── train/ │ ├── input/ # 有雾图如 SOTS_indoor_001.png │ └── gt/ # 清晰图文件名与 input 严格同名 ├── val/ │ ├── input/ │ └── gt/ ├── train.txt # 每行input 路径 空格 gt 路径 └── val.txt文件清单的格式有两种常见约定一种是两列路径另一种是单列文件名脚本默认去同名目录找。两种都能用但你要先确认脚本那头是哪种解析方式。我一般会写一个 30 秒的校验脚本把 train.txt 里每一行映射到的物理文件都检查一遍存在性和尺寸一致性防止训练中途才暴雷。校验脚本逻辑import os from PIL import Image def check_pairs(list_path, base_dir): with open(list_path, encodingutf-8) as f: lines [line.strip() for line in f if line.strip()] problems [] for idx, line in enumerate(lines): parts line.split() if len(parts) 2: problems.append(f第 {idx} 行列数不足: {line}) continue haze_path os.path.join(base_dir, parts[0]) gt_path os.path.join(base_dir, parts[1]) for p in (haze_path, gt_path): if not os.path.exists(p): problems.append(f缺失文件: {p}) continue with Image.open(p) as im: if im.size[0] 100 or im.size[1] 100: problems.append(f尺寸异常: {p} {im.size}) return problems # 用法check_pairs(train.txt)这段代码做的事情很简单逐行解析两列路径检查文件是否存在顺带验证图像尺寸是否低于合理下限。参数说明里有一条值得强调清单文件不要出现空行或带尾随空格的路径。Windows 换行符\r也会让os.path.exists判断失败跨平台共享数据集时最容易踩到这个坑。如果你看到校验脚本报出来一堆路径不存在先不要怀疑脚本八成是换行符或路径分隔符的问题。2.3 划分边界容易混淆的地方室内室外子集不混合很多人第一次接触时把 SOTS 的室内室外当成一个连续数据集直接混合做 8:2 划分这是最常见的翻车点。SOTS-Indoor 生成雾的散射系数 β 分布和 SOTS-Outdoor 完全不同室内子集的雾浓度范围窄、亮度变化平缓室外子集的雾浓度变化剧烈还伴有光照方向干扰。如果混合划分验证集里可能室内占多数把模型放到户外场景推理权重对浓雾的响应会彻底失效。标准做法是室内室外各自独立做 8:2 划分模型训练时再按场景标签做加权采样。另有一个整理版本带来的坑部分 SOTS 清理版会在图像里混入带透明通道的 PNG或者带 EXIF 旋转信息。读取时如果直接cv2.imread()默认会丢 alpha 通道转到 RGB 后亮度和边缘都变了去雾输出跟着偏。处理办法是在数据加载器里统一用 PIL 打开再转 RGB并且强制忽略 EXIF 方向。数据加载和尺寸归一化要写在一个函数里不允许不同子集各写一套否则你在训练阶段看到的是无 EXIF 的图推理阶段读的却是被旋转过的图结果怎么对都对不上。提示拿到划分好的数据先跑一遍校验脚本再碰权重。一个连文件数都对不齐的数据集后面任何调参都是在沙滩上盖楼。3. 从数据集到去雾权重预训练模型选型、权重加载和超参校准3.1 去雾权重的选型AOD-Net、FFA-Net 与轻量网络的取舍SOTS 划分好的 8:2 数据集是配着一套训练好的去雾权重来的。拿到权重之前先搞清楚这套权重是什么网络结构因为推理代码里的模型定义必须和权重完全一致。去雾领域常见的权重来源有这么几类AOD-Net、FFA-NetFeature Fusion Attention Network、GridDehazeNet以及部分工程里自研的轻量卷积网络。它们对部署端的诉求差异很大。AOD-Net 走的是“重铸大气散射模型”路线把散射模型的参数估计融合进一个端到端的卷积里结构非常轻适合嵌入式设备或实时前视相机。代价是它对于浓雾场景的去雾能力偏弱细节保留一般。FFA-Net 引入了通道注意力和像素注意力机制对浓雾、非均匀雾的处理效果明显更好但参数量和计算量都上了一个台阶在 512×512 输入下对 GPU 显存有一定要求。GridDehazeNet 把多尺度特征和网格结构结合起来对非均匀雾较鲁棒一般作为效果上限更高的候选。权重属于哪一类直接决定你推理阶段的预处理方式和性能预期。选型的判断方法不复杂先打开权重文件看 state_dict 的键名和 shape。AOD-Net 内部是若干个 1×1 卷积叠加卷积核尺寸小、层数少FFA-Net 的 state_dict 里会有明显的 attention 模块权重比如feature_attention.att之类的键名GridDehazeNet 则带有 grid 结构的下采样上采样层。如果推理代码里模型定义和权重不匹配加载时load_state_dict会直接报 size mismatch这反而是好事至少说明问题暴露得早。3.2 用 PyTorch 加载去雾权重的最小可靠代码路径无论权重是.pth还是.pt加载路径都遵循同一套逻辑。要注意的是很多训练脚本保存的是完整 checkpoint里面除了model_state_dict还混有 optimizer、epoch 和调度器状态。如果你直接torch.load后硬塞给load_state_dict会报 key 不匹配。所以统一先判断一次import torch def load_dehaze_weights(model, weights_path, devicecpu): checkpoint torch.load(weights_path, map_locationdevice) # 兼容两种保存方式完整 checkpoint 或只保存权重 if isinstance(checkpoint, dict) and state_dict in checkpoint: state_dict checkpoint[state_dict] else: state_dict checkpoint # 去掉可能存在的 module. 前缀兼容 DataParallel 保存的权重 fixed_dict {} for k, v in state_dict.items(): if k.startswith(module.): k k[7:] fixed_dict[k] v model.load_state_dict(fixed_dict, strictTrue) model.to(device) model.eval() return model这里有几个参数需要按场景调整。device默认给cpu是为了让没有 GPU 的人先验证链路通不通有 GPU 时改成cuda:0。strictTrue保持默认不要轻易改成 False。strictFalse会允许权重缺失或冗余静默吞掉问题这在推理阶段是定时炸弹。如果加载报 size mismatch优先怀疑模型结构定义和训练用的不一致其次是数据并行保存时带module.前缀。前缀问题我已经在代码里处理了你主要排查结构不一致即可。我自己的习惯是加载完顺手把权重里常量打印出来for name, param in model.named_parameters(): if param.requires_grad: print(name, param.data.mean().item())打印每个参数张量的均值能快速判断权重是不是已经收敛过的状态。如果均值全是 0 或接近 0大概率是随机初始化权重被错当成了训练权重先别急着推理。3.3 训练超参怎么跟着 8:2 划分走批次、学习率和验证轮次虽然你已经拿到了训练好的权重但复现实验时还是要对着这套 8:2 的划分调训练超参。因为你手里的权重对应一个固定的训练配置换数据集比例最优超参也会漂。以我验证过的去雾训练流程为例几个关键参数的经验值如下表参数常见取值说明batch size8~16去雾模型输入分辨率大显存优先learning rate1e-4 起步瓶颈轮再降Adam 通常比 SGD 稳epochs50~100以验证集 PSNR 不再上升为停止点crop size256×256 或 512×512和推理尺寸保持一致固定随机种子必须固定否则 8:2 划分无意义这里特别强调 crop size 和推理尺寸的一致性。很多训练时用随机裁剪 256×256推理时直接喂原始 512×512 甚至 1080p 全图模型对分辨率变化的泛化能力不足去雾结果会出现网格伪影或雾残留。如果你拿到的推理代码里没有 resize 操作先补上一个和训练一致的尺寸缩放再往下走。验证轮次的设置也值得注意。常规做法是每个 epoch 结束跑一次验证集但验证集合的 20% 数据在 8:2 划分下可能只有一两百张图单轮验证耗时很短跑一次 PSNR 即可。不要只盯 PSNR训练曲线的边际收益比绝对数值更重要。如果训练到 30 epoch 后 PSNR 还在小幅上升权重可能还没有完全收敛如果已经震荡说明学习率偏大或批次偏小需要用 StepLR 或 ReduceLROnPlateau 调低学习率再续训。你手上这份权重到底训了多少轮可以在 checkpoint 里的epoch键里查到如果没有这个键就直接用验证集跑一次和论文指标对比。4. 推理代码怎么组织从读入有雾图到输出无雾图的完整管道4.1 推理主流程预处理、归一化、Tensor 维度对齐推理代码是这套材料里最直接能验证价值的部分。它的目标只有一个输入一张有雾图输出一张和输入同尺寸的无雾图。实际工程里推理代码通常由五段组成加载权重、读图、预处理、前向、后处理。常见的错误集中在预处理和后处理两段尤其是归一化方式不匹配。import torch import numpy as np from PIL import Image import torchvision.transforms as T def inference_one(model, input_path, output_path, size(512, 512), devicecuda): # 读图统一转 RGB忽略 EXIF 方向 img Image.open(input_path).convert(RGB) img img.resize(size, Image.BILINEAR) # 预处理PIL - Tensor值域归一化到 [0, 1] tensor T.ToTensor()(img) # [C, H, W]数值范围 [0, 1] tensor tensor.unsqueeze(0) # [1, C, H, W] tensor tensor.to(device) with torch.no_grad(): out model(tensor) # 输出形状 [1, 3, H, W] # 后处理裁剪到 [0, 1] - 转成 HWC - 放大到 0-255 整数 out out.squeeze(0).clamp(0, 1) out_np out.permute(1, 2, 0).cpu().numpy() out_np (out_np * 255.0).round().astype(np.uint8) result Image.fromarray(out_np, modeRGB) result.save(output_path)这段代码的逻辑按顺序拆开PIL 打开图像并转 RGB丢弃透明通道和 EXIF 信息ToTensor()把像素整数转成浮点并归一化到 [0,1]同时把 HWC 变成 CHWunsqueeze(0)增加 batch 维满足 PyTorch 的 [N,C,H,W] 约定。clamp(0, 1)是因为模型输出可能出现小于 0 或大于 1 的浮点直接乘 255 会导致像素溢出或黑斑。permute(1, 2, 0)把 CHW 转回 HWCround().astype(np.uint8)做浮点到整数的转换舍弃小数部分能避免astype直接截断带来的负值改写。参数说明里最值得注意的就是size。模型在训练时有固定的输入尺寸约定推理代码里写size(512, 512)绝不代表所有图像都必须 512×512你需要打开训练配置确认。如果训练时用 256×256 crop推理尺寸设成 256 反而更稳如果推理对象是 1080p 工业相机图先下采样到模型输入尺寸推理完再上采样回原分辨率不要直接喂原图。这个尺寸信息通常在权重的 checkpoint 里能间接判断比如模型里的全局池化层输出特征图尺寸倒推不出训练尺寸最可靠的办法还是查训练脚本的 transform。4.2 后处理与回写颜色空间、裁剪边界和浮点转 uint8推理代码的后处理部分容易出问题因为模型输出的数值分布和人类视觉感知不是一回事。很多去雾模型直接回归的是 RGB 像素值输出值域自然落在 [0, 1] 附近但也有模型比如部分基于大气散射模型的实现输出的是传输率 t 和大气光 A需要你先用J (I - A) / max(t, t0)重建设雾前的清晰图。这两种模型的代码路径完全不同后者必须带着散射模型重建公式一起推理少了这一步输出会是灰蒙蒙的半成品。浮点转 uint8 的边界处理值得展开。直接用astype(np.uint8)会先截断再转换假如某个像素值是 256.7会被截断成 256再转成 uint8 变成 1产生极亮或极暗的杂点。所以我在代码里先用round()做四舍五入再用clamp(0, 1)把范围卡死最后才astype。如果你偏好用 OpenCV 的后处理np.clip(out_np * 255, 0, 255).astype(np.uint8)也是常见做法效果等价但要注意 out_np 的通道顺序是 RGB 还是 BGROpenCV 的imwrite默认按 BGR 解释颠倒通道会导致输出图像红蓝互换。颜色空间的问题在去雾里经常被忽略。训练时如果用的是 RGB 空间的 L1 或 MSE loss网络输出的颜色分布自然偏近 sRGB。如果训练时做了 YUV 或 Lab 空间的转换推理阶段就必须做对应的逆变换。我见过不少推理代码只做了一半模型输出后直接存成 jpg结果图像偏绿或偏紫。你拿到这套材料后第一件事就是确认训练脚本里 transform 的最后一步是什么推理代码必须完全复刻。4.3 把推理代码封装成命令行接口方便批量验证单张图推理验证没问题后批量处理一张目录下的所有雾图能让效率提升不少。工程里最顺手的做法是写一个 argparse 驱动的命令行入口让推理脚本接受权重路径、输入目录和输出目录三个参数import argparse import glob import os def main(): parser argparse.ArgumentParser() parser.add_argument(--weights, typestr, requiredTrue) parser.add_argument(--input, typestr, requiredTrue) parser.add_argument(--output, typestr, requiredTrue) parser.add_argument(--size, typeint, nargs2, default[512, 512]) args parser.parse_args() model load_dehaze_weights(...) os.makedirs(args.output, exist_okTrue) for img_path in sorted(glob.glob(os.path.join(args.input, *.png))): out_path os.path.join(args.output, os.path.basename(img_path)) inference_one(model, img_path, out_path, sizetuple(args.size))封装成命令行接口的好处有两个。第一是可复现性别人拿到同一行命令加同一份权重输出完全一致第二是便于批量评测验证集 20% 的图一键全跑完然后统一计算 PSNR 和 SSIM。命令行参数里的--size用两个整数接收默认给 512×512你在实际跑之前用一张真实雾图先测一版确认尺寸不会导致模型输出错位。输入目录的 glob 可以只匹配*.png但部分数据集的雾图是 jpg 格式如果一张没跑出来先检查扩展名。5. 去雾避坑与常见问题排查从权重失效到输出偏色5.1 推理输出全灰或全黑先查归一化和权重加载路径现象是推理输出的图像是一整块灰色或者全黑雾没了但细节也没了。原因通常有三个一是网络输出值没有做 clamp 直接存图负值被 uint8 截断成 255 或 0二是权重没有正确加载模型还在用随机初始化参数输出当然是一堆无意义的浮点三是预处理归一化方式和训练不一致比如训练时用的均值 0.5、标准差 0.5推理时直接ToTensor()没减均值输出整体偏移到灰度区间。解决步骤按顺序做先打印len(model.state_dict())对比权重文件里的键数量确认加载完全不缺再把网络输出用print(out.min(), out.max())打印出来如果最小值和最大值都在 0 附近说明网络本身输出饱和去查归一化最后把out.clamp(0, 1)改成(out1)/2试一版如果你训练时用的是 tanh 输出层这个转换能直接解决问题。这三步里九成情况是归一化或权重加载问题跟模型结构无关不用急着换网络。5.2 输出偏黄或偏蓝大气散射模型的 A 值估计漂移现象是去雾后的图像整体偏色室内偏蓝、室外偏黄色温偏移感明显。原因是去雾模型在训练时对大气光的估计有偏或者推理时图像本身的白平衡和训练分布差异太大。尤其当你用基于 AOD-Net 或暗通道先验的模型时大气光 A 的估计偏差直接叠加到输出 RGB 三通道上产生整体偏色。解决办法分两步。第一步是检查推理输入是否做了颜色校正先对输入图做一次简单的白平衡再送进模型比如用灰度世界假设把三通道均值拉到同一水平。第二步是调整模型的输出重建方式如果代码里有J (I - A)/t这类公式输出前对 A 做一个平滑约束把 A 限制在 [0.7, 1.0] 的合理区间。注意不要盲目在输出后加饱和度增强那会让偏色变得更不可控。排查顺序是先对比输入输出在天空区域的像素值差异若输出区域色差大于 ±10基本可以锁定是大气光估计问题。5.3 训练指标在涨但真实场景翻车SOTS 合成雾和真实雾的边界现象是这套权重在 SOTS 验证集上 PSNR 28 以上拿到户外真实雾天照片上却出现浓雾残留和水印状纹理。原因是 SOTS 的合成雾是均匀散射的真实雾往往伴随非均匀浓度和大气散射的多路径干扰网络在 SOTS 上学到的映射关系没法迁移到分布外数据。这个问题不是权重文件坏了是数据域差异。解决思路是接受这套权重只适合在合成雾数据集上做验证不要直接上真实场景。如果你确实需要真实场景去雾有两个可行方向一是用这套 8:2 权重做初始化再用少量带雾真实图对做微调学习率降到 1e-5二是引入一个轻量的后处理模块比如对输出做一次引导滤波平滑减少块状伪影。不要期望调推理代码能解决域差异那是训练侧的问题。5.4 验证阶段 OOM 或显存溢出批次和分辨率双重挤压现象是推理单张图没问题但批量跑验证集时 GPU 内存溢出或者训练时显存直接打满后 OOM。原因通常是验证时没有把 batch size 降到 1或者输入分辨率 512×512 在 FFA-Net 这类注意力网络上特征图占用了大量显存。部分实现还会在验证时保留梯度计算图torch.no_grad()没用上显存翻倍。解决方式很直接推理代码里统一用with torch.no_grad()包住前向验证 dataloader 的 batch size 设为 1如果还溢出把输入尺寸降到 256×256推理完成后再用img.resize(original_size)恢复。降分辨率虽然会损失一些细节但能在显存和效果之间找到折中。另一个更低成本的方案是把模型切换到半精度model.half()在支持的 GPU 上显存占用直接减半。半精度推理的输出记得转回 float 再做后处理否则clamp和astype的精度都有偏差。提示碰到任何输出异常第一步永远是打印输出值域和权重统计量别急着调后处理顺序。去雾排错的大多数时间浪费在没有数据的猜谜上。6. 用 PSNR 和 SSIM 给去雾结果打分差多少值就该重训推理跑通了怎么确认这套权重值不值得继续用别用眼睛判断去雾验证有两条硬指标PSNR峰值信噪比和 SSIM结构相似性。PSNR 衡量像素级重建误差数值越高越好SSIM 衡量结构纹理保留程度越接近 1 越好。SOTS 验证集上的常见及格线是 PSNR 高于 25dB、SSIM 高于 0.85室内子集模型通常会比室外高 2~3dB。我见过不少权重在单张样例图上效果惊艳但一算 PSNR 只有 21dB——那只能说明样例被精心挑过权重本身并不可靠。计算指标前需要先确保你对比的两张图尺寸完全一致且不包含黑边。以下是我常用的验证脚本片段import cv2 import numpy as np from skimage.metrics import structural_similarity as ssim def batch_eval(pred_dir, gt_dir, file_list): psnr_list, ssim_list [], [] for name in file_list: pred cv2.imread(f{pred_dir}/{name}, cv2.IMREAD_COLOR) gt cv2.imread(f{gt_dir}/{name}, cv2.IMREAD_COLOR) pred cv2.resize(pred, (gt.shape[1], gt.shape[0])) pred pred.astype(np.float32) gt gt.astype(np.float32) mse np.mean((pred - gt) ** 2) if mse 0: psnr_list.append(100.0) else: psnr_list.append(10 * np.log10(255.0**2 / mse)) ssim_list.append(ssim(gt, pred, channel_axis-1)) return np.mean(psnr_list), np.mean(ssim_list)代码里值得注意的参数是channel_axis-1老版本 skimage 里叫multichannelTrue两者取决于你的库版本。如果库版本不兼容直接pip install scikit-image -U解决。另一个注意点是cv2.imread读出来的是 BGR但 PSNR 和 SSIM 对通道顺序不敏感只要 pred 和 gt 顺序一致就行。拿到指标后的判断逻辑我一般这么用如果 PSNR 在 25dB 以下说明这套权重在 SOTS 8:2 验证集上明显欠拟合或过拟合不值得往业务里集成直接重训。如果 PSNR 在 25~30dB 之间且 SSIM 高于 0.85可以继续用但要知道它可能在真实场景翻车。只有 PSNR 高于 30dB 且 SSIM 高于 0.92我才敢把推理结果交给下游检测或分割模块。这个阈值经验是从很多次复现试验里积累下来的血泪经验——去雾模型 PSNR 虚高很容易SSIM 虚高较难因为结构损失不撒谎。最后的习惯是验证完把指标存档跟权重文件名绑在一起比如ffa_psnr29_ssim0.89.pth。下次换数据、换训练参数拿指标一比就能立刻判断改动是提升了还是回退了。这样即使是黑匣子一样的第三方权重也能被数字化语言描述清楚边界。希望这个验证习惯对你有用也祝你少踩几个去雾的坑。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号