反卷积(Deconvolution)、上采样(UNSampling)与上池化(UnPooling)加入自己的思考(pytorch函数)(三)

ps:最近在做分割在github上找代码看模型时老发现尺度从小到大那部分,有的是采用上采样(双线性插值)+卷积,有的用反卷积。为什么不相同能,我查阅相关资料发现这位知乎大神根据外网大佬文章总结原因。知乎地址:https://www.zhihu.com/question/328891283。先放下我之前一二中都会放的图:

这次我们重点关注下反卷积和上采样+卷积的结果对比。借用上面知乎大神的示例代码:

import mxnet as mx

batch_size = 1
in_channel = 1
height = 2
width = 2

data_shape = (batch_size, in_channel, height, width)
data = mx.nd.ones(data_shape)
print(data)
out_channel = 1
kernel_size = 2
deconv_weight_shape = (in_channel, out_channel, kernel_size, kernel_size)
deconv_weight = mx.nd.ones(deconv_weight_shape)

stride = 2
up_scale = 2
data_deconv = mx.nd.Deconvolution(data=data, weight=deconv_weight,

				      kernel=(kernel_size, kernel_size),
				      stride=(stride, stride),
				      num_filter=out_channel)
print(data_deconv)

data_upsample = mx.nd.contrib.BilinearResize2D(data=data, scale_height=up_scale, scale_width=up_scale)
print(data_upsample)
conv_weight_shape = (out_channel, in_channel, kernel_size, kernel_size)
conv_weight = mx.nd.ones(conv_weight_shape)
pad = (kernel_size - 1) / 2
data_conv = mx.nd.Convolution(data=data_upsample, weight=conv_weight,
			            kernel=(kernel_size, kernel_size),
			            pad=(pad, pad), num_filter=out_channel, no_bias=True)
print(data_conv)

这里卷积核尺寸为2*2,里面的权值都是1。输入原始数据是值全为1的1*1*2*2的矩阵。反卷积的步长为2。下面分别是原始数据,原始数据+反卷积,原始数据+2倍的双线性插值,原始数据+2倍的双线性插值+卷积。


[[[[1. 1.]
   [1. 1.]]]]
<NDArray 1x1x2x2 @cpu(0)>

[[[[1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]]]]
<NDArray 1x1x4x4 @cpu(0)>

[[[[1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]]]]
<NDArray 1x1x4x4 @cpu(0)>

[[[[4. 4. 4.]
   [4. 4. 4.]
   [4. 4. 4.]]]]
<NDArray 1x1x3x3 @cpu(0)>

好像没看出什么,将卷积核尺寸改为3*3,原始数据改大写1*1*4*4。

[[[[1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]]]]
<NDArray 1x1x4x4 @cpu(0)>

[[[[1. 1. 2. 1. 2. 1. 2. 1. 1.]
   [1. 1. 2. 1. 2. 1. 2. 1. 1.]
   [2. 2. 4. 2. 4. 2. 4. 2. 2.]
   [1. 1. 2. 1. 2. 1. 2. 1. 1.]
   [2. 2. 4. 2. 4. 2. 4. 2. 2.]
   [1. 1. 2. 1. 2. 1. 2. 1. 1.]
   [2. 2. 4. 2. 4. 2. 4. 2. 2.]
   [1. 1. 2. 1. 2. 1. 2. 1. 1.]
   [1. 1. 2. 1. 2. 1. 2. 1. 1.]]]]
<NDArray 1x1x9x9 @cpu(0)>

[[[[1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]]]]
<NDArray 1x1x8x8 @cpu(0)>

[[[[4. 6. 6. 6. 6. 6. 6. 4.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [6. 9. 9. 9. 9. 9. 9. 6.]
   [4. 6. 6. 6. 6. 6. 6. 4.]]]]
<NDArray 1x1x8x8 @cpu(0)>

在对比下卷积核尺寸改为4*4。


[[[[1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]
   [1. 1. 1. 1.]]]]
<NDArray 1x1x4x4 @cpu(0)>

[[[[1. 1. 2. 2. 2. 2. 2. 2. 1. 1.]
   [1. 1. 2. 2. 2. 2. 2. 2. 1. 1.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [2. 2. 4. 4. 4. 4. 4. 4. 2. 2.]
   [1. 1. 2. 2. 2. 2. 2. 2. 1. 1.]
   [1. 1. 2. 2. 2. 2. 2. 2. 1. 1.]]]]
<NDArray 1x1x10x10 @cpu(0)>

[[[[1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]
   [1. 1. 1. 1. 1. 1. 1. 1.]]]]
<NDArray 1x1x8x8 @cpu(0)>

[[[[ 9. 12. 12. 12. 12. 12.  9.]
   [12. 16. 16. 16. 16. 16. 12.]
   [12. 16. 16. 16. 16. 16. 12.]
   [12. 16. 16. 16. 16. 16. 12.]
   [12. 16. 16. 16. 16. 16. 12.]
   [12. 16. 16. 16. 16. 16. 12.]
   [ 9. 12. 12. 12. 12. 12.  9.]]]]
<NDArray 1x1x7x7 @cpu(0)>

这样一对比2和3就发现如果在步长为2的情况下,卷积核为3是的反卷积产生棋盘状的4(特征),这是原始数据里所有值为1中没有的特征(这样就成为噪声了),而卷积核为4时反卷积后就没有这种不该有的特征(噪声)。而上采样+卷积就没这种问题。所以直接都用上采样+卷积就比较省心,而直接反卷积就需要注意要设计时规避这种问题。

至于我为什么要放第1这种情况就是为解开我之前的困惑其实步长为2,所说的不是在反卷积时卷积核移动的步长(反卷积时卷积核移动的步长始终为1),而是代表插值后原始数据元素之间的距离。比如下图,左为卷积,右为反卷积。左图的输出先以步长为2插值(一般都插0值),那么元素间距离为步长2.在计算卷积是其实还是为移动步长为1进行。

最后再放下大佬的博文:https://distill.pub/2016/deconv-checkerboard/

人家16年已经搞的明明白白,我到现在才搞清楚啊!!!

猜你喜欢

转载自blog.csdn.net/qq_36401512/article/details/103294062