NAFNet (Simple Baselines for Image Restoration) 阅读笔记

旷视,2204

摘要

图像恢复SOTA方法的系统复杂性在增加,这可能会阻碍方法的便捷分析和比较 。本文提出了一种简单的基线,其性能超过了SOTA,并且在计算上效率高。为了进一步简化基线,我们揭示非线性激活函数不是必要的:它们可以被乘法替代或删除 。因此,我们从基线推导出了一个无非线性激活的网络,即NAFNet。在各类挑战基准测试中,我们实现了SOTA结果,例如在GoPro(用于图像去模糊)上获得33.69 dB的PSNR,超过了之前的SOTA 0.38 dB,仅以8.4%的计算成本;在SIDD(用于图像去噪)上获得40.30 dB的PSNR,超过了之前的SOTA 0.28 dB,计算成本不到其一半。

前言

本文将系统复杂性分为两种:块间和块内

块间:

块内:这篇文章举的例子是Restormer、SwinTransformer和Half Instance Norm Block(HINBlock)。这篇文章倒没有说它们不好,只是说逐一评估这些设计选择很难

本文想同时降低这两种复杂性,并仍取得SOTA 。为此,本文采用U-Net,并聚焦于降低块内设计。从最简单的组件出发:Conv、ReLU、shortcut,本文逐步加入/替换SOTA方法里的组件,验证它们带来的性能提升量。通过一大堆消融实验,本文提出了一个简单的基线,它超越了SOTA并且计算高效,如下图

图中的CA就是SE。基线还可以进一步简化:本文表明GELU可以被视作Gated Linear Unit(GLU)的特例,因此可以被替换;CA和GLU也很像,因此CA里的非线性激活函数也可以被移除。总之,这样简化完后,网络就没有非线性激活函数了!(但不是没有非线性了,只是转移到GLU上了)(你可能知道原始的GLU里是有非线性激活的,但本文把它删了!看下面的相关工作)本文将这个网络记作NAFNet(Nonlinera Activation Free)

相关工作(提一下GLU)

GLU【Language modeling with gated convolutional networks,2017】是两个线性层的逐元素乘积,其中一个线性层用非线性激活函数激活。GLU及其变体在NLP中被广泛应用,在CV中也有趋势。本文修改了GLU,把里面的非线性激活删除,这不会造成性能下降。(两个线性层的输出逐元素相乘是会产生非线性性的:Ax × Bx + Ay × By != A(x+y) × B(x+y),Akx × Bkx != k Ax × Bx,更简单点,标量ax × bx = ab x^2,就已经非线性了)

### 前情提要:下面的每一个层的添加/修改,都带来了性能提升,所以就不每次都说了

方法------Baseline

Architecture------UNet

层的排列------Transformer

本文模型的Block里的层排列设计参照了Transformer,先是一个"注意力"子块,然后是一个FFN。本文在构造简单基线,因此没有用self-attention

Normalization------LayerNorm

由于小batchsize会造成不稳定,BN被抛弃了。InstanceNorm避免了这个问题,但HIN Block又说IN的加入不一定总能提升性能,需要手动调优。LayerNorm在Transformer兴盛的大背景下被广泛使用,因此本文认为它很关键,实验表明LN使训练更丝滑,即使把学习率调大10倍。此外,大的学习率带来了显著的性能提升

Attention------Restormer与CA(SE)

自注意力属于一种空间注意力,计算上存在随图像尺寸平方增长的复杂度的问题。Restormer用Transposed的方法将这种空间注意力变为了通道注意力。通道注意力天然地聚合了全局信息(但精度上限应该比不上自注意力)。因此,本文加入了SE,将全局信息注入特征图

综上,baseline完成了。这个baseline能打败一众SOTA(图就不放了)

方法------NAFNet

还想继续简化,同时保持性能?看看一些SOTA方法的共性:GLU的使用。(这里列举了一些SOTA方法,基本上都是Transfomer变体,比如Restormer)

GLU的通用形式:,其中f和g是线性层,σ是非线性激活函数,⊙是逐元素乘积

直接用通用GLU实际上还是增加了复杂度,咋办?看一下GELU:,Φ(x)是标准正态分布的累积分布函数(CDF)。显然,GELU是GLU的特例。因此,本文认为GLU是一种通用型非线性激活函数,可以替代GELU。但这还不够,GLU里的σ就是非线性激活函数,能删掉吗?可以的!这样的GLU还是非线性的。但这还不够,线性变换要不少计算量,也删了!直接X ⊙ X。诶,这样的GLU还有足够的非线性性吗?(另一方面,这样的GLU还有Gate的作用吗?)本文换了一种设计:沿着通道维度把输入特征图对半分,然后把这两半逐点相乘(这样两半就互相作为对方的Gate)。本文将这种GLU叫做SimpleGate

看着GLU,有没有觉得和SE很像?对的,回顾一下SE:,把后面那一大块抽象一下,形式上就是GLU的一个特例了。好,让我们简化一下:删去ReLU和sigmoid,以及合并两个线性层,得到:【这里不能直接替换为SimpleGate,因为CA的两个关键特性是:全局信息聚合(通过pool)、通道信息交互(通过W)】

实验

在未特意提及的情况下,遵循HIN-Net的设置,包括gradient clip等。Adam with β=(0.9, 0.9) and weight_decay=0,200K迭代,lr=1e-3 -> 1e-6,cosineAnnealing,256 x 256。测试时采用TLC【Improving image restoration by revisiting global information aggregation,2112,也是旷视的文章】策略,弥补"当图像修复网络中存在全局信息操作时,用patch训练,用全图测试"导致的性能损失。此外,采用skip-init【由Batch normalization biases residual blocks towards the identity function in deep networks提出,但这篇文章说following ConvNeXt】来稳定训练

从PlainNet到Baseline

用lr=1e-3开始练出现了不稳定,遂调低至1e-4。加入LN后,可以用1e-3,并且训练更稳,性能更强【从表里看,LN和大学习率带来的提升比其它的改动要大得多

从Baseline到NAFNet

没什么可说的,性能和计算效率提升就完事了

块数

主要考虑720 x 1280的图像,因为这是GoPro数据集的全图分辨率。从9 -> 36,性能增长明显,速度下降较少(本文是用latency衡量的,只增加了约14.5%),再往上就不值得了

GLU里的非线性激活函数

没必要,在GoPro上PSNR和SSIM甚至还降了

附录

其它细节
  • 特征融合:对于U-Net中的跳跃连接,本文简单地将两个特征进行逐元素求和
  • 下采样与上采样:下采样用k=2、s=2的卷积【受arxiv.org/pdf/2010.02178启发】,上采样用1x1卷积将通道数翻倍 + PixelShuffle
相关推荐
没头脑的男大3 小时前
信号处理与系统设计,第二节课笔记
笔记·信号处理
凉、介4 小时前
ARM Synchronization Primitives
arm开发·笔记·学习
Godspeed Zhao4 小时前
自动驾驶中的传感器技术53——Radar(14)
人工智能·机器学习·自动驾驶
iconball4 小时前
个人用云计算学习笔记 --14( Linux 逻辑卷管理、Linux 交换空间管理)
linux·运维·笔记·学习·云计算
峰顶听歌的鲸鱼4 小时前
32.Linux NFS 服务
linux·运维·服务器·笔记·学习方法
Python极客之家4 小时前
基于机器学习的心血管疾病智能预测系统
人工智能·python·机器学习·数据挖掘·数据分析·毕业设计·课程设计
geilip4 小时前
知识体系_分布式内存计算框架_spark
笔记
41号学员5 小时前
构建神经网络的两大核心工具
人工智能·pytorch·深度学习
无风听海5 小时前
神经网络之仿射变换
人工智能·深度学习·神经网络