5分钟搞懂ADMM-CSNet:用PyTorch实现图像压缩感知重建(附代码)
5分钟实战ADMM-CSNetPyTorch图像重建从零实现指南当你在医院做核磁共振检查时是否想过为什么扫描时间那么长图像压缩感知技术正是为了解决这个痛点而生。传统方法需要采集大量数据才能重建清晰图像而ADMM-CSNet通过深度学习与优化算法的完美结合仅需少量采样数据就能还原高质量图像。本文将带你用PyTorch快速实现这一前沿技术。1. 环境配置与数据准备首先确保你的Python环境已安装PyTorch 1.8和OpenCV。推荐使用Anaconda创建独立环境conda create -n csnet python3.8 conda activate csnet pip install torch torchvision opencv-python matplotlib我们将使用MRI图像作为示例数据集。创建一个简单的数据加载器import torch from torch.utils.data import Dataset import cv2 import os class CSDataset(Dataset): def __init__(self, img_dir, transformNone): self.img_dir img_dir self.transform transform self.img_names os.listdir(img_dir) def __len__(self): return len(self.img_names) def __getitem__(self, idx): img_path os.path.join(self.img_dir, self.img_names[idx]) image cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) if self.transform: image self.transform(image) return torch.FloatTensor(image) / 255.0提示实际应用中建议使用专业医学影像数据集如fastMRI但本文为演示目的使用普通灰度图像即可2. 核心网络架构实现ADMM-CSNet的精妙之处在于将传统ADMM算法的迭代步骤展开为神经网络层。让我们分模块构建2.1 重建层实现import torch.nn as nn import torch.nn.functional as F class ReconstructionLayer(nn.Module): def __init__(self, sampling_rate0.3): super().__init__() self.sampling_rate sampling_rate def forward(self, y, phi, psi): y: 测量信号 (batch_size, m) phi: 采样矩阵 (m, n) psi: 稀疏基 (n, n) # 生成随机采样矩阵实际应用应固定 if phi is None: m int(psi.size(0) * self.sampling_rate) phi torch.randn(m, psi.size(0)) phi phi / torch.norm(phi, dim1, keepdimTrue) # 计算伪逆 A torch.matmul(phi, psi) pinv_A torch.pinverse(A) # 初始重建 x_hat torch.matmul(pinv_A, y) return x_hat, phi2.2 辅助变量更新块class AuxiliaryUpdateBlock(nn.Module): def __init__(self, channels32): super().__init__() self.conv1 nn.Conv2d(1, channels, 3, padding1) self.conv2 nn.Conv2d(channels, 1, 3, padding1) self.activation nn.ReLU() def forward(self, z, beta): residual z z self.conv1(z) z self.activation(z) z self.conv2(z) return z beta * residual3. 完整ADMM-CSNet组装现在我们将各个组件整合为完整网络class ADMMCSNet(nn.Module): def __init__(self, num_stages5, channels32): super().__init__() self.num_stages num_stages self.recon_layer ReconstructionLayer() self.aux_blocks nn.ModuleList( [AuxiliaryUpdateBlock(channels) for _ in range(num_stages)] ) self.rho nn.Parameter(torch.ones(num_stages) * 0.1) def forward(self, y, phiNone, psiNone): if psi is None: # 使用DCT作为默认稀疏基 n int(y.size(-1)**0.5) psi torch.tensor(np.eye(n)).float() # 初始重建 x, phi self.recon_layer(y, phi, psi) # ADMM展开迭代 z torch.zeros_like(x) beta torch.zeros_like(x) for stage in range(self.num_stages): # x更新 x self._update_x(x, z, beta, stage) # z更新 z self.aux_blocks[stage](z, beta) # 乘子更新 beta beta self.rho[stage] * (x - z) return x def _update_x(self, x, z, beta, stage): # 简化版x更新实际应包含采样矩阵运算 return (z - beta) * 0.5 x * 0.54. 训练技巧与参数调优要让ADMM-CSNet发挥最佳性能需要注意以下关键点学习率策略采用余弦退火学习率损失函数结合L1损失和SSIM指标正则化添加谱归一化提升稳定性def train_model(model, dataloader, epochs50): optimizer torch.optim.Adam(model.parameters(), lr1e-3) scheduler torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, epochs) criterion nn.L1Loss() for epoch in range(epochs): for batch in dataloader: # 模拟压缩感知测量 phi None # 使用随机采样 y torch.matmul(phi, batch.flatten(1)) # 重建 recon model(y, phi) # 计算损失 loss criterion(recon, batch) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() scheduler.step() print(fEpoch {epoch1}, Loss: {loss.item():.4f})注意实际训练时应将采样矩阵phi固定而不是每批随机生成5. 效果评估与可视化训练完成后我们可以通过以下方式评估模型性能def evaluate(model, test_loader): model.eval() total_psnr 0 with torch.no_grad(): for batch in test_loader: # 模拟30%采样 phi generate_sampling_matrix(0.3, batch.size(-1)) y torch.matmul(phi, batch.flatten(1)) recon model(y, phi) # 计算PSNR mse torch.mean((recon - batch)**2) psnr 20 * torch.log10(1.0 / torch.sqrt(mse)) total_psnr psnr return total_psnr / len(test_loader) def generate_sampling_matrix(sampling_rate, img_size): 生成随机但固定的采样矩阵 m int(img_size * sampling_rate) phi torch.randn(m, img_size) return phi / torch.norm(phi, dim1, keepdimTrue)可视化对比原始图像与重建结果import matplotlib.pyplot as plt def plot_results(original, reconstructed): plt.figure(figsize(10, 5)) plt.subplot(1, 2, 1) plt.imshow(original, cmapgray) plt.title(Original Image) plt.subplot(1, 2, 2) plt.imshow(reconstructed, cmapgray) plt.title(Reconstructed (30% samples)) plt.show()在实际项目中ADMM-CSNet相比传统压缩感知方法可以将重建速度提升10倍以上同时保持相近的图像质量。一个常见的应用场景是加速MRI扫描患者只需保持静止原来1/3的时间就能获得诊断级图像。