图像超分辨-2:CVPR2020: Dual Regression Networks for SISR

之前学习图像超分辨一直盯着GAN网络,感觉生成对抗才是超分辨王道。最近偶然看到这篇CVPR的会议论文,文章中做了一些半监督的处理,让图像超分辨减少了对成对数据集的依赖,感觉打开了一些新思路,记录下来方便以后学习创新。

代码:https://github.com/guoyongcs/DRN

论文:https://arxiv.org/pdf/2003.07018.pdf


本文针对了两个问题做了创新:

1.损失函数:目前主流的图像超分辨损失函数几乎都是对网络生成的SR和给定高分辨率HR做损失,不管是传统判别器还是相对判别器都是对这一损失求backward。作者给出了一个判定思想:理想情况下,如果网络映射LR-SR是最优的,那么超分辨图像SR可以向下采样得到相同的输入LR图像。基于此,可形成了一个闭环的LR - SR - LR的网络设计,损失函数loss分为 pramary_loss(LR-SR上采样loss)和dual_regression_loss(SR-LR下采样loss),提高loss函数的准确性。

2.非成对数据集学习:在图像超分辨训练中数据集通常采用DIV2K或者Flick2K,泛化能力较差,而真实场景中往往无法获得成对的图像,所以需要无监督的训练模型。基于此,作者提出在训练中加入半监督训练,即在成对训练集的基础上加入无配对的图像集,通过dual_regression_loss损失进行判断学习,以达到不依赖pair-data(准确来讲是不光依赖配对pair-data,其实还是需要的)。


老规矩,整个网络模型我还是分为三个部分:数据读取、模型搭建、损失函数。

1.数据读取:

文中数据读取采用传统DataLoader()

self.loader_train = DataLoader(
                trainset,
                batch_size=args.batch_size,
                num_workers=args.n_threads,
                shuffle=True,
                pin_memory=not args.cpu)

其中trainset需要说明一下,trainset在程序的返回值为lr_tensor, hr_tensor, filename,其中hr_tensor, filename很好理解,即高分辨Hr和图像的名称。lr图像则不止包含了最低分辨率的lr,还包含有其期望超分辨尺度scale的log2(scale),例如期望4倍提升,那个lr不仅包括X4,还包含X2图像,这个在后面的损失函数会用到。

    def _scan(self):
        names_hr = sorted(
            glob.glob(os.path.join(self.dir_hr, '*' + self.ext[0]))
        )
        names_lr = [[] for _ in self.scale]
        for f in names_hr:
             #os.path.basename:获得最小文件名,os.path.splitext文件名和后缀分离    
            filename, _ = os.path.splitext(os.path.basename(f)) 
            for si, s in enumerate(self.scale):  #self.scale = 2,4
                names_lr[si].append(os.path.join(
                    self.dir_lr, 'X{}/{}x{}{}'.format(
                        s, filename, s, self.ext[1]  #获得Hr对应的lr文件名
                    )
                ))

上式中self.scale表示期望放大尺度及其log2(),可看到name_lr包含有多个尺度的图像。

2.网络模型

 整个网络模型很像U-Net网络,即前半程提取特征,后半程上采样,使用拼接cat来形成新的网络层,这种结构也可叫编码器-解码器。

上图中的黑色箭头部分为Primary网络,主要进行图像变码和解码,得到生成的多尺度SR图像,上图中在经过Conv2后生成1x,2x,4x三个尺度图像。并分别与数据集中的lrx1,lrx2,及高清Hr做loss,得到损失函数。

上图红色箭头部分为Dual Regression对偶网络,通过对生成图像下采样得到对偶网络的输出图像,进一步优化损失函数。

在定义model时,通过传递参数“--model = DRN-S | DRN-L”来定义卷积层的特征图数量n-feats和RCAB 模块在每一层级的数量L,DRN-S的parameter较少,效果比DRN-L稍差,但是可节省硬件资源。

Primary网络左边为下采样提取特征,右边通过RCAB后经Pixelshuffle()进行上采样以减小总层数并增大每层的和hw。经上采样中间层后与前面的特征层进行拼接,之后进行Conv2得到三通道可视图像。RCAB网络即残差网络,各层网络由多个RCBA组成。

class RCAB(nn.Module):
    def __init__(self, conv, n_feat, kernel_size, reduction=16, bias=True, bn=False, act=nn.ReLU(True), res_scale=1):
        super(RCAB, self).__init__()
        modules_body = []
        for i in range(2):
            modules_body.append(conv(n_feat, n_feat, kernel_size, bias=bias))
            if bn: modules_body.append(nn.BatchNorm2d(n_feat))
            if i == 0: modules_body.append(act)
        modules_body.append(CALayer(n_feat, reduction))
        self.body = nn.Sequential(*modules_body)
        self.res_scale = res_scale

    def forward(self, x):
        res = self.body(x) 
        res += x  #残差
        return res

 3.损失函数

pair data loss(双损失函数):

 

 在成对数据集中,损失函数分为primary_loss、dual_loss,两种损失函数都采用L1 loss,通过设置权重得到总损失loss_total。

unpaired data:

 在非成对数据集中,通常是大部分成对数据集加少部分非成对数据集,从上图可看当成对数据时才加上Lp损失,若非成对数据则只有后面的LD损失。

 


训练结果

1.定量比较

作者给出的训练结果图如下图,可看出DRN-L和DRN-S的整体表现还是很不错的,parameters不多但是PSNR都很高,可以说碾压了EDSR(但是不知道为什么没有和SRGAN进行比较)

 2.定性比较

作者在图像的直观比较加入了SRGAN,可以看到此方法的效果还是最好的。

下面是我自己模型的实测结果,通过实测模型可看出Dual Regression确实效果比srgan还稍好。

Dual Regression
SRGAN
lr

 


Dual Regression Network就先介绍这么多,之后有什么想起来的继续补充,一起奥利给超分辨!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值