一层卷积能做啥?BOE告诉你:一层卷积可以做超分!
前言 本文是京东方团队关于端侧超分的深度思考,以端侧设备超分为切入点,对经典上采样与深度学习超分之间的“空白”地带进行思考,提出了一类“一层”超分架构,并对所提方案与其他轻量型超分方案以及bicubic从不同角度进行了对比,同时也为未来端侧超分算法的设计提供了一个极具价值的参考点。
本文转载自AIWalker
作者 | Happy
欢迎关注公众号 CV技术指南 ,专注于计算机视觉的技术总结、最新技术跟踪、经典论文解读、CV招聘信息。
arXiv: https:// arxiv.org/pdf/2108.1033 5.pdf
Abstract
经典的图像缩放(比如bicubic)可以视作一个卷积层+一个上采样滤波器,它在所有显示设备与图像处理软件中是普遍存在的。
在过去的十年里,深度学习技术已被成功应用到图像超分任务上,它们往往由多个卷积与大量滤波器构成。深度学习方法已成功占据了图像上采样任务的质量基准。 深度学习方法能否在端侧设备(比如显示屏、平板电脑以及笔记本电脑)上取代经典上采样技术吗 ?一方面,随着能高效运行深度学习任务的硬件的迅速发展,AI芯片发展趋势呈现出了非常好的前景;另一方面,只有少数SR架构能够在端侧设备上实时处理非常小尺寸图像。
我们对该问题的可能方案进行了探索以期弥补经典上采样与轻量深度学习超分之间的空白。作为从经典到深度学习上采样之间的过渡,我们提出了edge-SR(eSR):一层架构,它采用可解释机制进行图像上采样。当然,一层架构无法达到与深度学习方法的性能,但是,对于高速度需求来说,eSR具有更好的图像质量-推理速度均衡。弥补经典与深度学习上采样之间的空白对于大量采用该技术非常重要。
本文贡献包含以下几点:
- 提出了几种一层架构以弥补经典与深度学习上采样之间的空白;
- 在1185中深度学习架构中进行了穷举搜索,可参考上图,不同的架构具有不同的性能-速度均衡。
- 对一层自注意力架构进行了可解释分析,对自注意力机制提供了一种新的解释。
上述结果可能会带来以下影响:
- 图像超分系统有可能大量应用到端侧设备;
- 对小网络的内部学习机制有更好的理解;
- 对未来应用于研究了一个更好的性能-耗时均衡参考。
Super-Resolution for Edge Devices
Classical 图像上采样与下采样指的是LR与HR之间的转换。最简单的下采样有pooling、downsample。downsample一半是在水平和垂直方向进行均匀的像素丢弃,这种处理会导致高频信息丢失,导致Alisaing问题。为解决该问题,经典的线性下采样首先采用anti-aliasing低通滤波器移除高频,然后再下采样。现有深度学习框架中采用stride convolution实现。线性上采样则与之相反,下图给出了实现可视化图,即 先上采样后滤波 。
由于引入过多零,造成大量的资源浪费,上图中的定义实现非常低效。本文提出了一种高效实现,见上图下部分,即先滤波再pixelshuffle。注:作者采用标准bicubi插值滤波器系数进行验证,两者具有完全相同的结果。
Maxout 本文提出的首个一层网络为edge-SR Maximum(eSR-MAX),见下图。
class edgeSR_MAX(nn.Module):
def __init__(self, C, k, s):
super().__init__()
self.pixel_shuffle = nn.PixelShuffle(s)
self.filter = nn.Conv2d(1,s*s*C,k,1,(k-1)//2,bias=False)
def forward(self, x):
return self.pixel_shuffle(self.filter(x)).max(dim=1, keepdim=True)[0]
Self-Attention 本文提出的第二个一层网络为edge-SR Template Matching(eSR-TM)。下图给出了该方案的解释示意图,它利用了模板匹配的思想。
class edgeSR_TM(nn.Module):
def __init__(self, C, k, s):
super().__init__()
self.pixel_shuffle = nn.PixelShuffle(s)
self.softmax = nn.Softmax(dim=1)
self.filter = nn.Conv2d(1,2*s*s*C,k,1,(k-1)//2,bias=False)
def forward(self, x):
filtered = self.pixel_shuffle(self.filter(x)
B,C,H,W = filtered.shape
filtered = filtered.view(B,2,C,H,W)
upscaling= filtered[:,0]
matching = filtered[:,1]
return torch.sum(upscaling * self.softmax(matching), dim=1, keepdim=True)
Transformer 本文提出的第三种方案是edge-SR TRansformer(eSR-TR),见下图,它采用了Transformer的自注意力机制,某种程度上时eSR-TM的简化。
class edgeSR_TR(nn.Module):
def __init__(self, C, k, s):
self.pixel_shuffle = nn.PixelShuffle(s)
self.softmax = nn.Softmax(dim=1)
self.filter = nn.Conv2d(1,3*s*s*C,k,1,(k-1)//2,bias=False)
def forward(self, x):
filtered = self.pixel_shuffle(self.filter(x))
B,C,H,W = filtered.shape
filtered = filtered.view(B,3,C,H,W)
value = filtered[:,0]
query = filtered[:,1]
key = filtered[:,2]
return torch.sum(value*self.softmax(query*key),dim=1,keepdim=True)
edge-SR CNN 此外本文还提出了edge-SR CNN(eSR-CNN),见上图c。下图给出了所提几种方案的算法实现。
class edgeSR_CNN(nn.Module):
def __init__(self, C, D, S, s):
super().__init__()
self.softmax = nn.Softmax(dim=1)
if D == 0:
self.filter = nn.Sequential(
nn.Conv2d(D, S, 3, 1, 1),
nn.Tanh(),
nn.Conv2d(S,2*s*s*C,3,1,1,bias=False),
nn.PixelShuffle(s))
else:
self.filter = nn.Sequential(
nn.Conv2d(1, D, 5, 1, 2),
nn.Tanh(),
nn.Conv2d(D, S, 3, 1, 1),
nn.Tanh(),
nn.Conv2d(S,2*s*s*C,3,1,1,bias=False),
nn.PixelShuffle(s))
def forward(self, input):
filtered = self.filter(input)