gluon怎么没有UpSampling

Gluon Neural Network Layers里怎么没有UpSampling Layers?

可以用Decovolution

nn.Conv2DTranspose(channels, kernel_size=4, padding=1, strides=2) 可以放大兩倍

1赞

反卷积会产生棋盘状artifacts

所以要用上采样卷积层

    class UpsampleConvLayer(Block):
    """UpsampleConvLayer
    Upsamples the input and then does a convolution. This method gives better results
    compared to ConvTranspose2d.
    ref: http://distill.pub/2016/deconv-checkerboard/
    """

    def __init__(self, in_channels, out_channels, kernel_size, 
            stride, upsample=None):
        super(UpsampleConvLayer, self).__init__()
        self.upsample = upsample
        self.reflection_padding = int(np.floor(kernel_size / 2))
        self.conv2d = nn.Conv2D(in_channels=in_channels, 
                                channels=out_channels, 
                                kernel_size=kernel_size, strides=(stride,stride),
                                padding=self.reflection_padding)

    def forward(self, x):
        if self.upsample:
            x = mxnet.ndarray.UpSampling(x, scale=self.upsample, sample_type='bilinear')
        out = self.conv2d(x)
        return out

例:

UpsampleConvLayer(in_channels=128, out_channels=128,
                                   kernel_size=1, stride=1, upsample=2)

ref:
MXNet-Gluon-Style-Transfer/net.py at master · zhanghang1989/MXNet-Gluon-Style-Transfer · GitHub

3赞
import numpy as np
import mxnet as mxnet

class UpsampleConvLayer(nn.Block):
    """UpsampleConvLayer
    Upsamples the input and then does a convolution. This method gives better results
    compared to ConvTranspose2d.
    ref: http://distill.pub/2016/deconv-checkerboard/
    """

    def __init__(self, in_channels, out_channels, kernel_size, 
            stride, upsample=None):
        super(UpsampleConvLayer, self).__init__()
        self.upsample = upsample
        self.reflection_padding = int(np.floor(kernel_size / 2))
        self.conv2d = nn.Conv2D(in_channels=in_channels, 
                                channels=out_channels, 
                                kernel_size=kernel_size, strides=(stride,stride),
                                padding=self.reflection_padding)

    def forward(self, x):
        if self.upsample:
            x = mxnet.ndarray.UpSampling(x, scale=self.upsample, sample_type='bilinear')
        out = self.conv2d(x)
        return out
    
x1 = mxnet.nd.ones(shape=(16,128,4,4))   
upconv = UpsampleConvLayer(in_channels=128, out_channels=128, kernel_size=1, stride=1, upsample=2)
y1 = upconv(x1)
y1.shape

还是不行,
MXNetError: [12:08:06] d:\program files (x86)\jenkins\workspace\mxnet\mxnet\src\c_api…/imperative/imperative_utils.h:313: Check failed: num_inputs == infered_num_inputs (1 vs. 2) Operator UpSampling expects 2 inputs, but got 1 instead.
请问这个block还能正常使用吗?我看到很多人都反映不会设置这个UpSampling的参数,都是这个问题,没见过一个人搞定……最后他们都用反卷积了
@zhouhang95

import mxnet as mx
import mxnet.ndarray as nd
xx = nd.random_normal(shape=[1,1,256,256],ctx=mx.cpu())
xx1 = nd.random_normal(shape=[1,1,4,4],ctx=mx.cpu()) 
temp = nd.UpSampling(xx,xx1, num_filter=1, scale=2, sample_type='bilinear', num_args=2)

···发现这样可以运行,xx1是weight,不过双线性插值为什么还有权重?

1赞


现在可以用这个……不过不知道如果输入大小变化时怎么办,因为我一般用的symbolize化的hybridblock,没法取输入的shape

这个xx1需要设置为不可学习吗?

UpSampling我到现在也不会用,现在用BilinearResize2D
额,什么叫不可学习?我一直觉得这个就是无法学习的层吧

为什么一定要xx1? Bilinear确实本来就是不可学习的层, 真是很奇怪.

是啊,同样不理解怎么设置Bilinear的参数,而且这里为啥需要把xx1的尺寸设置为[1, 1, 4, , 4]呀

nd.UpSampling有个参数num_args,当其为1时,不需要weight, 为2时,需要weight,估计是在小窗里做插值预测吧,


    xx = nd.ones(shape=[1, 1, 3, 3])
    xx1 = nd.random_normal(shape=[1, 1, 2, 2])
    temp1 = nd.UpSampling(xx,  scale=2, sample_type='nearest', num_args=1)
    temp2 = nd.UpSampling(xx, xx1, scale=2, sample_type='nearest', num_args=2)
    print("tmp1 nearest: \n", temp1.asnumpy())
    print("tmp2 nearest: \n", temp2.asnumpy())

结果如下:


tmp1 nearest: 
 [[[[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.]]]]
tmp2 nearest: 
 [[[[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.       ]]

  [[2.2122064 2.2122064 2.2122064 0.7740038 0.7740038 0.7740038]
   [2.2122064 2.2122064 2.2122064 0.7740038 0.7740038 0.7740038]
   [2.2122064 2.2122064 2.2122064 0.7740038 0.7740038 0.7740038]
   [1.0434405 1.0434405 1.0434405 1.1839255 1.1839255 1.1839255]
   [1.0434405 1.0434405 1.0434405 1.1839255 1.1839255 1.1839255]
   [1.0434405 1.0434405 1.0434405 1.1839255 1.1839255 1.1839255]]]]
1赞

Upsampling的内部实现就是Deconvolution,能用Deconvolution就用Deconvolution吧,比较灵活且可学习,而且感受野也没问题

1赞

TMD 哪能找到源码 我看看

截至目前,mxnet已有Upsampling