对于去雨任务,基于单个网络结构的训练而不考虑跨尺度关系,可能会导致信息丢失。具体来说,为了学习不同尺度的特征,论文提出了一个多子网(multi-sub-networks)络结构,其中这些子网通过门循环单元的跨尺度方式融合,以内部学习并充分利用这些子网络中不同尺度的信息。
首先,作者设计了一个内尺度(inner-scale)的连接块,通过建立每个尺度之间的相关性来融合不同尺度的特征,从而更好地学习雨的特征。
其次,为了最大限度地增加信息流,能够计算远程空间依赖性,并有效地利用后续层的特征激活,本文引入了具有密集连接结构的编码器和解码器,并通过跳跃连接来内部连接这些块。
最后,提出了一种跨尺度融合网络来学习不同尺度上的特征,其中提出的跨尺度方式通过门循环单元(GRU)将不同尺度上的特征连接起来,充分利用了不同尺度上的信息。
本文主要贡献:
- 通过建立每个尺度之间的相关性,建立了一个尺度内的连接块,从而更好地学习雨的特征。
- 引入了具有密集连接结构的编码器和解码器,并跳过连接到内部连接,以提高去雨的性能。
- 提出了一种跨尺度融合网络来学习不同尺度的特征,其中提出的跨尺度方式通过门循环单元连接不同尺度的特征,充分利用不同尺度的信息。
- 在合成和真实数据集上的实验结果证明了提出的方法的优越性,它优于最先进的方法。
网络整体结构:
该网络由三个不同规模的子网络组成。在每个尺度上,它们都有相同的结构,具有密集连接的编码器和解码器(如图2所示)。在每个编码器的最后,GRU通过跨尺度的方式融合不同尺度上的特征,以充分利用不同尺度上的信息。最后,将不同尺度上的所有特征融合,生成估计的雨,得到最终估计的无雨图像。
Inner-scale Connection Block 图2中的编码器由一系列内尺度的连接块组成(如图3所示)。 内尺度连接块,首先,利用全局最大池化来获得不同尺度的特征。其次,将不同尺度之间的多次卷积后的特征连接起来,以促进相关信息的探索。最后,通过融合不同尺度上的所有特征来学习主要特征。代码: Inner-scale Connection Block
论文及图中对应scale_num为3。1x 1/2 x 1/4 x
# Figure 3 Inner-scale Connection Block
class Inner_scale_connection_block(nn.Module):
def __init__(self):
super(Inner_scale_connection_block, self).__init__()
self.channel = settings.channel
self.scale_num = settings.scale_num
self.conv_num = settings.conv_num # 论文中为4
self.scale1 = nn.ModuleList()
self.scale2 = nn.ModuleList()
self.scale4 = nn.ModuleList()
self.scale8 = nn.ModuleList()
if settings.scale_num == 4:
for i in range(self.conv_num):
self.scale1.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
self.scale2.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
self.scale4.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
self.scale8.append(nn.Sequential(nn.Conv2d(self.channel, self.channel, 3, 1, 1), nn.LeakyReLU(0.2)))
self.fusion84 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
self.fusion42 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
self.fusion21 = nn.Sequential(nn.Conv2d(2 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
self.pooling8 = nn.MaxPool2d(8, 8)
self.pooling4 = nn.MaxPool2d(4, 4)
self.pooling2 = nn.MaxPool2d(2, 2)
self.fusion_all = nn.Sequential(nn.Conv2d(4 * self.channel, self.channel, 1, 1), nn.LeakyReLU(0.2))
# 论文中(K=3)scale_num为3
elif settings.scale_num == 3:
for i in range(self.conv_num):
#use