RCAN是引用较高的超分模型。paper code
作者观察到两个问题:
- 深层网络有训练难度。
- LR中有低频成分,和相对高频且更重要的成分。但二者被平等对待。
针对这两点的解决思路:
- 采用嵌套的残差结构加深网络,RIR residual in residua。
- 在通道(不同成分)上增加注意力(权重)。
RCAN网络结构:
RCAB结构:
RCAB代码:
## Residual Channel Attention Block (RCAB)
class RCAB(nn.Module):
def __init__(
self, conv, n_feat, kernel_size, reduction,
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 = self.body(x).mul(self.res_scale)
res += x
return res
channel attention:
CA代码:
class CALayer(nn.Module):
def __init__(self, channel, reduction=16):
super(CALayer, self).__init__()
# global average pooling: feature --> point
self.avg_pool = nn.AdaptiveAvgPool2d(1)
# feature channel downscale and upscale --> channel weight
self.conv_du = nn.Sequential(
nn.Conv2d(channel, channel // reduction, 1, padding=0, bias=True),
nn.ReLU(inplace=True),
nn.Conv2d(channel // reduction, channel, 1, padding=0, bias=True),
nn.Sigmoid()
)
def forward(self, x):
y = self.avg_pool(x)
y = self.conv_du(y)
return x * y
思考:
- 在训练初期,每个kernal还没有区分度,CA本身的学习和初始化参数是否会对网络参数学习产生影响?
参考文献:
- https://blog.cython.top/paper-notes-1.html#architecture
- https://www.kesci.com/home/project/5db292f875df5c002b23cda0
- http://www.jeepxie.net/article/611013.html
- https://perper.site/2019/09/05/Image-Super-Resolution-Using-Very-Deep-Residual-Channel-Attention-Networks-RCAN/
- https://www.jianshu.com/p/07334544b4b0