插值上采样+卷积的代码实现:
class Upsample(nn.Module): # 只改变大小不改变通道数
def __init__(self, channels, use_conv):
super().__init__()
self.use_conv = use_conv
if use_conv:
self.conv = nn.Conv2d(channels, channels, kernel_size=3, padding=1)
def forward(self, x):
x = F.interpolate(x, scale_factor=2, mode="nearest") # 只改变大小,不改变通道数
if self.use_conv:
x = self.conv(x)
return x
上采样通常有两种方式:一种是插值;一种是转置卷积,即利用深度学习让神经网络学习参数。
Deconvolution & Overlap
转置卷积有一个弊端:生成的图像有棋盘效应。
什么是棋盘效应?输出的feature map出现了明显的网格状,图像中某个部位的颜色比其他部位更深。
为什么有棋盘效应?因为不均匀重叠。转置卷积容易产生不均匀重叠(uneven overlap),就好像在某些地方多涂了些颜料。尤其是卷积核大小(kernel size)无法被步长(stride)整除的时候,会产生不均匀重叠。但神经网络在学习中努力去避免这种不均匀重叠。在对2维图像卷积的时候,卷积核在两个维度上移动,2个维度同时有不均匀重叠,从而产生棋盘效应。
![](https://img-blog.csdnimg.cn/9a8a95df769b4dff982f69b9cd623282.png)
现在,经常使用多层转置卷积希望消除棋盘效应,但它们往往会产生复合效果。步长为1的转置卷积对棋盘效应有一定抑制效果。
当输出unusual colors的图像,棋盘效应很明显:因为神经网络一般会学习bias(比如卷积:学习kernel weight,bias),所以神经网络容易输出average color,因此颜色越偏离average color,转置卷积的副作用越大。
Overlap & Learning
避免棋盘效应会对kernel大大限制。
Better Upsampling
考虑别的上采样方式来抵制棋盘效应。尽量避免不均匀重叠:
- 方式1:转置卷积时,kernel % stride == 0
- 方式2:双线性插值/最近邻插值调整大小+卷积层
Image Generation Results
Our experience has been that nearest-neighbor resize followed by a convolution works very well, in a wide variety of contexts.