资讯动态

深度多尺度GAN压缩感知图像重建源码解析与实战

发布时间:2026/10/1 13:12:47 来源:尧图企业网站定制
简介本资源为吉林大学学报工学版投稿论文《深度多尺度生成对抗网络下图像压缩感知重建》的配套源码面向图像处理、信号处理方向的研究生与算法开发者用于复现并理解基于GAN的压缩感知重建流程。压缩包共28个文件、约151KB以8个Python源文件为核心覆盖模型构建、训练、数据处理与性能评估等模块另含6张JPEG图片作为训练验证数据、3个CSV记录训练与测试指标、4个pyc编译文件及LICENSE、readme说明文档目录按data、train、valid、test等分层组织便于按模块检索。已有324人学习下载。读者可据此搭建多尺度生成对抗网络观察生成器与判别器对抗训练对边缘纹理的保留效果并借助SSIM等指标评估重建质量为图像超分辨率、修复等任务提供可迁移的代码基础与实验参考。1. 从稀疏采样到多尺度重建这套源码到底能跑出什么压缩感知重建这件事理论课上讲的是「用远低于奈奎斯特率的采样点恢复原信号」但真到自己动手十有八九卡在同一个地方传统迭代算法跑一张 256×256 的图要几分钟调参调到怀疑人生重建出来的边缘还是糊的。这套来自吉林大学学报工学版投稿论文的源码走的是另一条路——用深度多尺度生成对抗网络把重建过程整体学出来生成器负责从稀疏测量值里把图像「长」回来判别器负责盯着生成结果别跑偏。它适合两类人一类是图像处理/信号处理方向的研究生想复现论文里的 SSIM、PSNR 指标另一类是做深度学习落地的工程师想找一个结构完整、模块拆得清楚的 GAN 压缩感知工程模板直接改自己的数据。源码包一共 23 个文件8 个 Python 源文件把模型、训练、推理、评估全串起来了不是那种只丢一个 model.py 的半成品。2. 拆开 upload.zip模块职责与多尺度 GAN 的选型逻辑2.1 八个 Python 文件各自管什么拿到一个源码包我习惯先按「数据怎么进、模型怎么建、训练怎么跑、结果怎么出」四条线把文件归类而不是上来就python train.py。这套源码的模块划分相当规整基本符合论文级工程的组织方式文件职责关键点model.py生成器与判别器网络定义多尺度特征提取的核心卷积核尺寸分层train.py训练主循环对抗损失 重建损失的联合优化loss.py损失函数像素级损失与对抗损失的加权组合data_utils.py数据加载与预处理采样矩阵生成、归一化、批处理inferce_image.py单图推理输入测量值输出重建图inferce_benchmark.py批量基准测试跑测试集并输出指标mod.py辅助模块通用工具函数pytorch_ssim/__init__.pySSIM 计算评估重建质量的核心指标这里有个容易忽略的点pytorch_ssim是作为子目录存在的说明作者把 SSIM 实现内嵌进了工程而不是依赖外部 pip 包。好处是版本可控、复现时不会因为第三方库更新导致指标对不上代价是你得确认这个目录被正确识别为 Python 包有__init__.py就行。2.2 为什么是「多尺度 GAN」而不是纯 CNN纯 CNN 做压缩感知重建本质是在学一个从测量值到图像的确定性映射损失函数通常是 MSE。问题在于 MSE 对纹理和边缘的惩罚是「平均化」的重建结果容易偏平滑高频细节丢失严重。GAN 的引入改变了这一点判别器不关心像素差多少它判断的是「这张图看起来像不像真实图像」这就逼着生成器去恢复那些 MSE 不敏感但人眼敏感的纹理结构。多尺度的价值在于感受野的层次化。单一尺度的卷积核只能捕捉固定范围的上下文而图像里既有大面积的平滑区域也有细密的纹理。多尺度结构让网络在不同分辨率上分别提取特征再融合回重建结果边缘和纹理的保留能力明显强于单尺度。常见做法是在生成器里用不同尺寸的卷积核并行处理或者用类似 U-Net 的编码器-解码器结构配合跳跃连接。提示如果你只是想快速验证重建效果可以先跳过训练直接用作者提供的预训练权重如果epochs目录下有.pth文件跑inferce_image.py。但要注意源码包里epochs/.gitkeep只是个占位文件实际权重需要你自己训练或向作者索取。2.3 采样率 SRF 的含义与数据组织源码里反复出现SRF_4、srf_4_test_results.csv这样的命名SRF 是 Sampling Rate Factor 的缩写SRF4 意味着采样率是 1/4即只保留 25% 的测量值。这是压缩感知里最核心的参数——采样率越低重建难度越大指标下降越明显。数据目录结构是这样的data/ ├── train/ │ └── 0564.jpg ├── valid/ │ └── 0622.jpg └── test/ └── SRF_4/训练集和验证集各只有一张图这在实际工程里几乎不可想象但论文复现场景下很常见——作者可能用的是标准测试图如 Set11、BSD68中的单张代表图做演示。你要做的是把自己的数据集按同样结构放进去训练集和验证集可以放多张但测试集的SRF_4子目录命名要保持一致否则inferce_benchmark.py里的路径拼接会直接报错。3. 把环境跑起来从依赖安装到第一次推理3.1 环境准备与依赖确认这套源码基于 PyTorch从__pycache__里的cpython-37.pyc可以推断作者用的是 Python 3.7。我一般不会死磕完全一致的版本但 PyTorch 的版本差异会直接影响模型加载和训练稳定性建议至少保证 Python 3.7 和 PyTorch 1.x。# 创建独立环境避免和系统里的其他 PyTorch 版本打架 conda create -n csgan python3.7 -y conda activate csgan # 安装核心依赖torch 版本根据你的 CUDA 情况调整 pip install torch1.7.1 torchvision0.8.2 pip install numpy scipy pillow pandas matplotlib # 验证 pytorch_ssim 子模块能被正确导入 python -c from pytorch_ssim import ssim; print(SSIM module OK)这里有个细节pytorch_ssim是本地目录不是 pip 包所以必须在项目根目录下执行 Python 命令否则import会失败。如果你在别的路径下跑需要把项目根目录加到sys.path里。3.2 数据加载与采样矩阵的生成逻辑data_utils.py是整个流程的入口它决定了测量值怎么来。压缩感知的核心操作是用一个测量矩阵 Φ 对图像 x 做投影y Φx其中 y 是测量值维度远小于 x。源码里大概率用的是随机高斯矩阵或部分傅里叶矩阵这两种是压缩感知领域最常用的。# data_utils.py 中数据加载的典型逻辑根据源码结构推断 import numpy as np from PIL import Image import torch from torch.utils.data import Dataset class CSDataset(Dataset): def __init__(self, img_path, srf4, block_size33): self.img Image.open(img_path).convert(L) # 转灰度压缩感知常用单通道 self.img np.array(self.img, dtypenp.float32) / 255.0 self.srf srf self.block_size block_size # 按块采样每块保留 1/srf 的测量值 self.measurement_matrix self._build_measurement_matrix() def _build_measurement_matrix(self): # 常见做法高斯随机矩阵行数 block_size // srf n self.block_size * self.block_size m n // self.srf phi np.random.randn(m, n) / np.sqrt(m) return torch.from_numpy(phi).float() def __len__(self): return 1 # 单图场景下返回 1多图需改为实际数量 def __getitem__(self, idx): img_tensor torch.from_numpy(self.img).unsqueeze(0) # 分块并展平再与测量矩阵相乘 blocks img_tensor.unfold(1, self.block_size, self.block_size).unfold(2, self.block_size, self.block_size) blocks blocks.contiguous().view(-1, self.block_size * self.block_size) measurements blocks self.measurement_matrix.t() return measurements, blocks这段代码的关键参数是block_size和srf。块大小决定了局部重建的粒度33 是压缩感知图像重建里的经典值对应 33×33 的图像块srf直接控制测量矩阵的行数SRF4 时每块保留约 272 个测量值。如果你改成 SRF1测量矩阵变成方阵重建退化成恒等映射指标会虚高但没有意义。3.3 训练脚本的启动与关键参数train.py是训练入口启动方式通常是直接python train.py但你需要先确认几个参数。源码里没有提供argparse的完整参数列表从文件结构推断所以大概率是硬编码在脚本开头的常量。# 启动训练注意观察控制台输出的 loss 变化 python train.py # 如果显存不够先把 batch_size 调小 # 在 train.py 开头找到类似 BATCH_SIZE 64 的行改成 16 或 8训练过程中会生成training_results目录下的日志文件以及statistics目录下的 CSV。srf_1_train_results.csv和srf_4_train_results.csv分别对应不同采样率的训练记录说明作者跑了多组实验。你第一次跑的时候建议先用 SRF4 验证流程能通再尝试其他采样率。注意如果训练 loss 在前几个 epoch 就变成 NaN八成是学习率太大或者测量矩阵没有做归一化。先把学习率降到 1e-4 试试同时检查data_utils.py里测量矩阵是否除了sqrt(m)。3.4 推理与基准测试拿到你的第一组指标训练完成后或者你拿到了预训练权重推理分两条路单图用inferce_image.py批量测试用inferce_benchmark.py。# 单图推理输出重建后的图像 python inferce_image.py # 批量基准测试结果写入 statistics/srf_4_test_results.csv python inferce_benchmark.pyinferce_benchmark.py会遍历data/test/SRF_4/下的所有图片对每张图计算 PSNR 和 SSIM然后汇总到 CSV。CSV 的列通常包括图片名、PSNR、SSIM、采样率。你可以直接用 pandas 读出来做对比import pandas as pd df pd.read_csv(statistics/srf_4_test_results.csv) print(df.describe()) # 快速看指标分布 print(df.sort_values(ssim, ascendingFalse).head()) # 找重建最好的图如果 CSV 是空的或者只有表头说明测试目录下没有图片或者路径拼接出了问题。检查data/test/SRF_4/里是否有.jpg文件以及inferce_benchmark.py里的路径变量是否指向了正确的位置。4. 避坑与排查复现这套源码时最容易翻车的五个地方4.1 现象ModuleNotFoundError: No module named pytorch_ssim原因pytorch_ssim是项目内的子目录不是 pip 安装的包。如果你在非项目根目录下执行脚本Python 找不到这个模块。解决确保cd到upload.zip解压后的根目录再运行。如果必须在其他目录运行在脚本开头加sys.path.insert(0, /path/to/project)。4.2 现象训练时 loss 震荡剧烈SSIM 不升反降原因GAN 训练本身就不稳定生成器和判别器的学习率如果不匹配容易出现一方压倒另一方的情况。源码里如果用的是同一个学习率判别器可能收敛太快。解决把判别器的学习率调低到生成器的 1/2 到 1/4或者给判别器加梯度惩罚。另外检查loss.py里对抗损失和重建损失的权重比常见做法是重建损失占主导权重 0.9 以上对抗损失只做微调。4.3 现象inferce_benchmark.py跑完 CSV 里只有一行或者报KeyError原因测试集路径不对或者 CSV 写入时的列名和读取时的列名不一致。源码里srf_4_test_results.csv已经有数据说明作者跑过但你的环境里可能因为路径分隔符Windows 用\Linux 用/导致文件没被遍历到。解决在inferce_benchmark.py里打印一下os.listdir(test_dir)确认能看到图片文件。如果是 Windows 环境把路径拼接改成os.path.join而不是字符串相加。4.4 现象重建图像整体偏暗或偏亮原因归一化方式不匹配。训练时如果对图像做了[0,1]归一化推理时没有做同样的处理或者反过来重建结果的像素值范围就会错位。解决检查data_utils.py里的归一化逻辑确保训练和推理走的是同一套预处理。常见做法是训练时归一化到[0,1]推理输出后再乘 255 转回uint8。4.5 现象显存溢出CUDA out of memory原因block_size或batch_size太大尤其是多尺度结构下特征图数量翻倍显存占用比普通 CNN 高不少。解决先把batch_size降到 8 或 4如果还不够把block_size从 33 降到 17。注意block_size改变后测量矩阵的维度也要同步调整否则矩阵乘法会报维度不匹配。5. 进阶玩法用自定义数据跑通完整链路并验证指标5.1 替换数据集从单图演示到批量训练源码自带的0564.jpg和0622.jpg只是演示用的单图真正要验证算法泛化能力得换成标准测试集。我一般会从 Set11 或 BSD68 里挑 1020 张图按下面的结构组织data/ ├── train/ │ ├── 001.jpg │ ├── 002.jpg │ └── ...至少 10 张 ├── valid/ │ ├── 101.jpg │ └── 102.jpg └── test/ └── SRF_4/ ├── 201.jpg └── 202.jpg然后改data_utils.py里的__len__返回值让它等于实际图片数量。如果源码里用的是ImageFolder之类的接口直接按目录结构放就行如果是硬编码的单图路径需要把路径改成os.listdir遍历。5.2 指标验证PSNR 和 SSIM 怎么算才靠谱pytorch_ssim算出来的 SSIM 和论文里的值对不上通常是因为两个细节一是数据范围SSIM 要求输入在[0,1]或[0,255]且data_range参数一致二是通道数灰度图和 RGB 图的 SSIM 计算方式不同。import torch from pytorch_ssim import ssim # 假设重建结果和原图都是 [0,1] 范围的灰度图 recon torch.rand(1, 1, 256, 256) # 模拟重建输出 target torch.rand(1, 1, 256, 256) # 模拟原图 # 关键data_range 要和输入范围匹配 ssim_val ssim(recon, target, data_range1.0) print(fSSIM: {ssim_val.item():.4f}) # PSNR 手动算避免依赖额外库 mse torch.mean((recon - target) ** 2) psnr 10 * torch.log10(1.0 / mse) print(fPSNR: {psnr.item():.2f} dB)如果算出来的 PSNR 超过 40 dB 而 SSIM 只有 0.7 左右大概率是 PSNR 算错了比如用了data_range255但输入是[0,1]。这两个指标要一起看PSNR 高但 SSIM 低说明像素误差小但结构信息丢失严重这在 GAN 重建里很常见。5.3 从 CSV 到论文图表结果分析的最小闭环statistics目录下的三个 CSV 是你写论文或做汇报时的原始素材。我习惯用 pandas 做一次聚合把不同采样率的结果拼到一张表里import pandas as pd srf1 pd.read_csv(statistics/srf_1_train_results.csv) srf4 pd.read_csv(statistics/srf_4_train_results.csv) # 假设 CSV 里有 epoch, loss, psnr, ssim 列 summary pd.DataFrame({ SRF: [1, 4], Best PSNR: [srf1[psnr].max(), srf4[psnr].max()], Best SSIM: [srf1[ssim].max(), srf4[ssim].max()], Final Loss: [srf1[loss].iloc[-1], srf4[loss].iloc[-1]] }) print(summary.to_markdown(indexFalse))这张表能直接看出采样率对重建质量的影响SRF1 时测量值最多指标应该明显好于 SRF4。如果 SRF4 的指标反而更高要么是训练不充分要么是测试集太小导致偶然性太大。5.4 一个我踩过的坑别在验证集上调参刚接触这套源码时我看到valid/0622.jpg只有一张图就顺手拿它当测试集调学习率和网络层数结果论文里的指标怎么都复现不出来。后来才反应过来验证集是用来监控过拟合的不是用来刷指标的。正确做法是训练集训模型验证集选超参测试集只在最后跑一次。测试集的图不要提前看更不要根据测试结果回头改模型——那是自欺欺人。从那以后我每次复现论文源码都强制把数据分成三份测试集单独锁在一个目录里训练过程中绝不碰。希望这套源码在你手里能跑出比论文更好的结果。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑