【图像去噪】第六期论文复现赛——MIRNet


本文复现MIRNet系列论文,含V1和V2版本。V1先提取低级特征,经递归残差组处理,再得残差图像,最终恢复图像;V2类似但优化模块提升速度。复现精度达标,提供数据集、预训练模型、文件结构及训练、评估等操作方法,方便使用。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

MIRNet 系列论文复现 兼 飞桨特色模型挑战赛

复现了两篇论文:

MIRNetV1: Learning Enriched Features for Real Image Restoration and Enhancement

MIRNetV2: Learning Enriched Features for Fast Image Restoration and Enhancement

官方源码:https://github.com/swz30/MIRNet 和 https://github.com/swz30/MIRNetV2

复现地址:https://github.com/sldyns/MIRNetV2_paddle

1. 简介

MIRNet V1:

       

给定一个图像 IRH×H×3I∈RH×H×3,MIRNet 首先应用一个卷积层来提取低级特征 X0RH×W×CX0∈RH×W×C. 接下来,特征映射 X0X0 通过 NN 个递归残差组(RRGs),产生深度特征 XdRH×W×CXd∈RH×W×C. 我们注意到每个 RRG 包含多个多尺度残差块(MRB),MRB 由多个(本文中有三个)并行连接的全卷积流组成,每个连接上先由 DAU 抑制了不太有用的特性,并且只允许信息更丰富的特性进一步传递给 SKFF,SKFF 模块通过 Fuse 和 select 两种操作对接受域进行动态调整. 接下来, 应用卷积层,得到残差图像 RRH×H×3R∈RH×H×3。最后,恢复的图像为 I^=I+RI^=I+R.

MIRNet V2:

       

MIRNetV2 过程同 MIRNet V1 类似,主要在 MRB 内减少了卷积流间的链接,同时将DAU替换为残差上下文块,显著降低了模型大小并提升了推理速度.

2. 复现精度

MIRNet V1:

验收标准:SIDD PSNR: 39.678

复现结果:SIDD PSNR: 39.687

飞桨特色模型挑战赛:

验收标准:SIDD PSNR: 37,SSIM: 0.94

MIRNet V2,训练92个epoch精度:SIDD PSNR: 39.5286,SSIM: 0.9578

3. 数据集、预训练模型、文件结构

3.1 数据集

训练和测试数据为 SIDD-Medium,需要下载并分 patch.

已将分好 patch 的数据放在了 Ai Studio 里.

可直接运行下面的脚本解压:

In [ ]
!cd data && tar -xf data140841/SIDD_patches.tar.gz
   

3.2 预训练模型

MIRNet V1:

  1. 官方预训练模型,已转为 paddle 的,名为 MIRNetV1_torch.pdparams.
  2. 复现的模型,名为 MIRNetV1_paddle.pdparams.
  3. pytorch 的初始化参数,名为 torch_init.pdparams

MIRNet V2:

复现的模型,名为 MIRNetV2_paddle.pdparams,导出的静态图模型参数包括 model.pdmodel 和 model.pdiparams.

运行以下脚本解压:

In [ ]
!unzip data/data150163/pretrained_models.zip -d work/pretrained_models
   

3.3 文件结构

MIRNet_Paddle    |-- configs                       # 单机单卡/四卡训练配置文件
    |-- dataloaders                # 数据集相关文件
    |-- SIDD_patches
         |-- train                      # SIDD-Medium 训练数据
         |-- val                         # SIDD 测试数据
    |-- networks
         |-- MIRNet_model.py          # MIRNetV1模型代码
         |-- MIRNet_V2_model.py    # MIRNetV2模型代码
    |-- pretrained_models              # 预训练模型
    |-- utils                                     # 一些工具代码
    |-- config.py                             # 配置文件
    |-- losses.py                             # 损失函数
    |-- test_denoising_sidd.py       # 测试SIDD数据上的指标
    |-- train_denoising.py              # 训练代码
   

4. 环境依赖

PaddlePaddle >= 2.2.0

scikit-image == 0.19.2

In [ ]
!pip install scikit-image natsort yacs
   

5. 核心代码

MIRNet 的核心为 MRB 模块,核心代码为:

class MSRB(nn.Layer):
    def __init__(self, n_feat, height, width, stride, bias):
        super(MSRB, self).__init__()

        self.n_feat, self.height, self.width = n_feat, height, width
        self.blocks = nn.LayerList([nn.LayerList([DAU(int(n_feat*stride**i))]*width) for i in range(height)])

        INDEX = np.arange(0,width, 2)
        FEATS = [int((stride**i)*n_feat) for i in range(height)]
        SCALE = [2**i for i in range(1,height)]

        self.last_up   = nn.LayerDict()        for i in range(1,height):
            self.last_up.update({f'{i}': UpSample(int(n_feat*stride**i),2**i,stride)})

        self.down = nn.LayerDict()
        self.up   = nn.LayerDict()

        i=0
        SCALE.reverse()        for feat in FEATS:            for scale in SCALE[i:]:
                self.down.update({f'{feat}_{scale}': DownSample(feat,scale,stride)})
            i+=1

        i=0
        FEATS.reverse()        for feat in FEATS:            for scale in SCALE[i:]:                
                self.up.update({f'{feat}_{scale}': UpSample(feat,scale,stride)})
            i+=1

        self.conv_out = nn.Conv2D(n_feat, n_feat, kernel_size=3, padding=1, bias_attr=bias)

        self.selective_kernel = nn.LayerList([SKFF(n_feat*stride**i, height) for i in range(height)])    def forward(self, x):
        inp = x.clone()        #col 1 only
        blocks_out = []        for j in range(self.height):            if j==0:
                inp = self.blocks[j][0](inp)            else:
                inp = self.blocks[j][0](self.down[f'{inp.shape[1]}_{2}'](inp))
            blocks_out.append(inp)        #rest of grid
        for i in range(1,self.width):            #Mesh
            # Replace condition(i%2!=0) with True(Mesh) or False(Plain)
            # if i%2!=0:
            tmp=[]            for j in range(self.height):
                TENSOR = []
                nfeats = (2**j)*self.n_feat                for k in range(self.height):
                    TENSOR.append(self.select_up_down(blocks_out[k], j, k))

                selective_kernel_fusion = self.selective_kernel[j](TENSOR)
                tmp.append(selective_kernel_fusion)            #Forward through either mesh or plain
            for j in range(self.height):
                blocks_out[j] = self.blocks[j][i](tmp[j])        #Sum after grid
        out=[]        for k in range(self.height):
            out.append(self.select_last_up(blocks_out[k], k))  

        out = self.selective_kernel[0](out)

        out = self.conv_out(out)
        out = out + x        return out    def select_up_down(self, tensor, j, k):
        if j==k:            return tensor        else:
            diff = 2 ** np.abs(j-k)            if j
        

损失函数采用 Charbonnier Loss,实现较为简单,代码如下:

class CharbonnierLoss(nn.Layer):
    """Charbonnier Loss (L1)"""

    def __init__(self, eps=1e-3):
        super(CharbonnierLoss, self).__init__()
        self.eps = eps    def forward(self, x, y):
        diff = x - y        # loss = paddle.sum(paddle.sqrt(diff * diff + self.eps))
        loss = paddle.mean(paddle.sqrt((diff * diff) + (self.eps*self.eps)))        return loss
   

6. 快速开始

配置文件在work/configs下,可修改学习率、batch_size等参数

对于MIRNet V1(论文复现赛93题),单卡运行的配置文件为MIRNet_1cards.yml:

优化相关的设置:batch_size设置为4,epoch设为60,初始学习率设为2e-4.

OPTIM:
  BATCH_SIZE: [4]  NUM_EPOCHS: [60]  LR_INITIAL: 2e-4
       

对于MIRNet V2(特色模型挑战赛5),单卡运行的配置文件为MIRNetV2_1cards.yml:

采用Progressive Learning,即逐渐增大输入的patch_size,并减小batch_size,此处patch_size从128增加到256,batch_size从8减小到2,各个patch_size对应epoch数为30、15、10、5.

OPTIM:
  BATCH_SIZE: [8,6,4,2]  NUM_EPOCHS: [30,15,10,5]  LR_INITIAL: 2e-4
  TRAINING:
  PATCH_SIZE: [128,160,192,256]  NUM_WORKERS: [4,4,4,4]
       

注:学习策略采用Warm up + Cosine Anneal LR,其中Warm up的epoch数为3.

6.1 模型训练

MIRNet V1单卡运行的代码如下:

In [ ]
!cd work && python train_denoising.py --model MIRNet --gpus 1
   

同时给出 MIRNet 单机四卡和 MIRNet V2 的训练脚本,为更好的体验 MIRNet 的训练并得到复现结果,请使用脚本任务.

## MIRnet V1# 单机四卡!cd work && python -m paddle.distributed.launch train_denoising.py --model MIRNet --gpus 4## MIRNet V2# 单机单卡!cd work && python train_denoising.py --model MIRNetV2 --gpus 1# 单机四卡!cd work && python -m paddle.distributed.launch train_denoising.py --model MIRNetV2 --gpus 4
       

训练过程会将模型参数保存在 ./ckpt/Denoising/model/ 文件夹下.

6.2 日志读取

训练过程会将日志记录保存在 ./ckpt/Denoising/logs/ 文件夹下,例如 MIRNet V2 的日志目录为 ./ckpt/Denoising/logs/MIRNet_V2/

日志是用 VisualDL 工具记录的,可在 CodeLab 左侧的数据模型可视化中,设置 logdir 查看.

6.3 模型评估

在 SIDD 测试数据上作测试,以 MIRNet V1 为例,若想测试 MIRNet V2,只需将 --model MIRNet 改为 MIRNetV2,同时修改权重weights路径.

In [ ]
# MIRNet V1!cd work && python test_denoising_sidd.py --input_dir ../data/SIDD_patches/val --weights ./pretrained_models/MIRNetV1_paddle.pdparams --model MIRNet
   

输出如下:

# MIRNet V1PSNR: 39.6872 
SSIM: 0.9586# MIRNet V2PSNR: 39.5286
SSIM: 0.9578
       

达到了验收精度.

6.4 模型预测

在 SIDD 小验证集上作预测,结果存放在 work/results/ 文件夹下,下以 MIRNet V1 为例,对于 MIRNet V2,同上修改weight和model.

In [ ]
# MIRNet V1!cd work && python predict.py --data_path ./SIDD_patches/val_mini/ --save_path results/ --save_images --model_ckpt ./pretrained_models/MIRNetV1_paddle.pdparams --model MIRNet
   

6.5 单张图像去噪测试

导入单张图像,测试去噪效果,首先需要在work/test_images里上传一张图片.

In [41]
# 先上传一张图片,import os.path as ospfrom IPython.display import displayfrom PIL import Image
img_path = 'bird.png' # 改成自己上传的图片名称full_img_path = osp.join(osp.abspath('work/test_images/'), img_path)
img = Image.open(full_img_path).convert('RGB')print('以下为上传的图片:')
display(img)
       
以下为上传的图片:
       
               

以 MIRNet V1 为例,对于 MIRNet V2,同上修改model_ckpt和model.

需要指定干净图像和噪声图像,可以只给一张噪声图片,也可以只给一张干净图片,也可以都给.

  1. 给定一张噪声图片:指定参数noisy_img,直接输出去噪图片.

  2. 给定一张干净图片:指定参数clean_img和noisyL,后者为噪声水平,默认为15,输出加噪图片和去噪图片.

  3. 给定噪声图片和干净图片:直接输出去噪图片.

In [ ]
# MIRNet V1 仅给定干净图片,噪声水平为15!cd work && python predict_single.py --clean_img $full_img_path --save_images --model_ckpt ./pretrained_models/MIRNetV1_paddle.pdparams --model MIRNet
    In [45]
# 去噪效果查看import globfrom IPython.display import displayfrom PIL import Image

imgs = glob.glob('work/test_images/*')for path in imgs:    print(path)
    img = Image.open(path)
    display(img)
       
work/test_images/bird_noised.png
       
               
work/test_images/bird_denoised.png
       
               
work/test_images/bird.png
       


# pytorch  # 数为  # 会将  # 测试数据  # 设为  # 多个  # 放在  # 为例  # 上传  # 配置文件  # https  # paddlepaddle  # python  # github  # 递归  # select  # for  # igs  # red  # cos  # ai  # 工具  # git 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化91478 】 【 技术知识72672 】 【 云计算0 】 【 GEO优化84317 】 【 优选文章0 】 【 营销推广36048 】 【 网络运营41350 】 【 案例网站102563 】 【 AI智能45237


相关推荐: Dr.Job AI:职场简历优化终极指南,提升求职成功率  智谱AI创意设计怎么用_智谱AI创意设计使用方法详细指南【教程】  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  通义千问怎样优化提示词更口语化_通义千问口语化技巧【教程】  豆包AI怎么用提示词生成短视频脚本_豆包AI脚本提示词编写【教程】  《高龄母亲》:从日本民间故事中汲取的人生智慧与家庭真谛  怎么用AI帮你设计一套个性化的手机App图标?  3步教你用AI帮你把菜谱转换成详细的烹饪步骤视频脚本  百度AI助手聊天入口 文心一言对话窗口入口  AI赋能营销:角色、策略与工具选择全指南  利用MECLABS AI解决业务难题:实用指南  AI 编码助手:提升效率的 5 大工具及应用详解  ChatGPT 处理超长 PDF 文件的核心步骤  百度ai助手工具栏怎么关 百度ai助手状态栏隐藏  如何用AI生成正则表达式?再也不怕复杂的文本匹配  Google AI Studio文本转语音教程:零成本创作高质量音频  CanvaAI抠图如何换背景_CanvaAI背景替换与设计模板结合【攻略】  艺龙旅行AI怎样筛选最优车次_艺龙AI车次筛选与耗时最短推荐【攻略】  微信AI数字人如何设置工作时间_微信AI数字人时段开关与值班安排【实操】  Jetson SegNet: 语义分割深度探索与实践  冷邮件营销新策略:工作坊模式助力B2B销售增长  智行ai抢票怎么选优先车次_智行ai抢票车次优先级设置技巧【指南】  QuickBooks Desktop 到 Online 迁移指南:轻松转移您的公司数据  kimi生成ppt怎么编辑文字_kimi编辑文字后怎么保存  DeepSeek写合同怎么用_DeepSeek写合同使用方法详细指南【教程】  唐库AI拆书工具如何提取核心观点_唐库AI拆书工具观点提取与标注方法【攻略】  百度输入法蓝色图标怎么关 百度输入法ai图标消除  通义千问怎样写文案_通义千问文案写作教程【指南】  tofai怎么调整层级顺序 tofai图层上下移动方法【步骤】  GitHub Copilot与Azure AI Foundry模型:加速AI编程实践  如何用AI一键给视频自动加字幕  百度AI搜索怎么用AI总结网页_百度AI搜索网页总结功能与调用【技巧】  Weavernote:AI驱动的知识管理与高效笔记应用  豆包AI怎么生成员工成长总结_豆包AI成长指标提取与案例编写【方法】  MemeGIF Studio:AI驱动的GIF生成器全面评测与使用指南  ChatGPT背后的AI革命:OpenAI的崛起与Google的危机  ChatGPT怎么用一键生成活动策划案_ChatGPT策划案生成教程【攻略】  AI女友:时尚穿搭与美丽瞬间的完美融合  如何在 Google Sheets 中利用 Gemini 自动填充数据  Feelin聊天网页版地址 Feelin AI官方网站首页  TechInternPath.ai:AI驱动的实习之路,助你梦想成真  零基础玩转千问AI,轻松实现月入万元的最新方法!  BEILA:用AI驱动的低代码开发平台详解  AI赋能保险销售:提升邮件营销效果的终极指南  AI音频增强和视频背景替换终极指南  免费高效获客!ChatGPT助你快速生成潜在客户名单  百度输入法ai面板怎么关 百度输入法ai面板隐藏技巧  AI怎么修复模糊视频 视频画质增强AI软件Topaz Video使用【教程】  Canva AI 辅助 KDP 封面设计:轻松创建畅销书笔记本  AISIA O1皮肤检测仪操作指南:安装、使用、疑难解答 

 2025-07-23

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

南京市珐之弘网络技术有限公司


南京市珐之弘网络技术有限公司

南京市珐之弘网络技术有限公司专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 87067657

 13565296790

 87067657@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.