问题描述
我知道在卷积层中,内核大小需要乘以步幅,否则会在梯度计算中产生伪影,如棋盘问题。 现在它也像在池化层中那样工作吗?我在某处读到最大池化也会导致类似的问题。以鉴别器中的这一行为例:
self.downsample = nn.AvgPool2d(3,stride=2,padding=1,count_include_pad=False)
看起来像是棋盘问题,或者至少是梯度问题,但我检查了我的卷积层并没有发现上述错误。它们都是大小为 4 的步长为 2 的大小或不均匀的步长为 1 的大小。
解决方法
老实说,这看起来不像棋盘神器。另外我认为鉴别器不是问题,它通常是关于图像恢复(生成器或解码器)。
快速浏览一下 MUNIT,它们在 Decoder
中使用的是带有最近邻上采样的 torch.nn.Upsample
(确切的代码行 here)。
您可以尝试使用 torch.nn.Conv2d
后接 torch.nn.PixelShuffle
,如下所示:
import torch
in_channels = 32
upscale_factor = 2
out_channels = 16
upsampling = torch.nn.Sequential(
torch.nn.Conv2d(
in_channels,out_channels * upscale_factor * upscale_factor,kernel_size=3,padding=1,),torch.nn.PixelShuffle(upscale_factor),)
image = torch.randn(1,32,16,16)
upsampling(image).shape # [1,32]
这允许神经网络学习如何对图像进行上采样,而不仅仅是使用网络无法控制的 torch.nn.Upsample
(并且使用以下技巧也应该没有棋盘伪影)。
此外,Conv2d
的 ICNR 初始化也应该有帮助(可能的实现 here 或 here)。此初始化方案初始化权重以类似于开始时的最近邻上采样(研究论文 here)。