Example #1
0
    def forward(self, x):
        flow = self.block(x)
        x = self.conv1(x)
        x = P.im2col(x, 5, 1, 0)
        flow = P.im2col(flow, 5, 1, 0)
        x = x * flow
        x = P.col2im(x, 5, 1, 0)

        return x
Example #2
0
 def test_im2col_batch(self):
     src = Variable(torch.randn(4, 8, 7, 7).cuda())
     k = 1
     pad = 0
     s = (1, 1)
     dst = P.im2col(src, k, s, pad)
     back = P.col2im(dst, k, s, pad)
     self.assertEqual((src - back).data.abs().max(), 0)
Example #3
0
def im2patch(x, patchsize, stride, padding=None, returnpadding=False):
    padtop, padbottom, padleft, padright = calc_padding(x, patchsize, stride, padding)
    xpad = F.pad(x, pad=(padleft, padright, padtop, padbottom))

    x2col = pyinn.im2col(xpad, [patchsize]*2, [stride]*2, [0,0])
    if returnpadding:
        return x2col, (padtop, padbottom, padleft, padright)
    else:
        return x2col
Example #4
0
def im2col_X(model, X, conv_index):
    # GPU implementation of im2col
    import pyinn as P
    this_X = P.im2col(X, model.features[conv_index].kernel_size[0],
                      model.features[conv_index].stride[0],
                      model.features[conv_index].padding[0]).detach()
    this_X_data = this_X.data
    this_X_data = this_X_data.permute(0, 4, 5, 1, 2, 3)
    this_X_data_flatten = this_X_data.contiguous().view(
        this_X_data.size(0) * this_X_data.size(1) * this_X_data.size(2), -1)
    del this_X, this_X_data
    return this_X_data_flatten
Example #5
0
def nd2col(input_nd,
           kernel_size,
           stride=1,
           padding=0,
           output_padding=0,
           dilation=1,
           transposed=False,
           use_pyinn_if_possible=False):
    """
    Shape:
        - Input: :math:`(N, C, L_{in})`
        - Output: :math:`(N, C, *kernel_size, *L_{out})` where
          :math:`L_{out} = floor((L_{in} + 2 * padding - dilation * (kernel_size - 1) - 1) / stride + 1)` for non-transposed
          :math:`L_{out} = (L_{in} - 1) * stride - 2 * padding + dilation * (kernel_size - 1) + 1 + output_padding` for transposed
    """
    n_dims = len(input_nd.shape[2:])
    kernel_size = (kernel_size, ) * n_dims if isinstance(
        kernel_size, Number) else kernel_size
    stride = (stride, ) * n_dims if isinstance(stride, Number) else stride
    padding = (padding, ) * n_dims if isinstance(padding, Number) else padding
    output_padding = (output_padding, ) * n_dims if isinstance(
        output_padding, Number) else output_padding
    dilation = (dilation, ) * n_dims if isinstance(dilation,
                                                   Number) else dilation

    if transposed:
        assert n_dims == 2, 'Only 2D is supported for fractional strides.'
        w_one = input_nd.new_ones(1, 1, 1, 1)
        pad = [(k - 1) * d - p
               for (k, d, p) in zip(kernel_size, dilation, padding)]
        input_nd = F.conv_transpose2d(input_nd, w_one, stride=stride)
        input_nd = F.pad(input_nd, (pad[1], pad[1] + output_padding[1], pad[0],
                                    pad[0] + output_padding[0]))
        stride = _pair(1)
        padding = _pair(0)

    (bs, nch), in_sz = input_nd.shape[:2], input_nd.shape[2:]
    out_sz = tuple([
        ((i + 2 * p - d * (k - 1) - 1) // s + 1)
        for (i, k, d, p,
             s) in zip(in_sz, kernel_size, dilation, padding, stride)
    ])
    # Use PyINN if possible (about 15% faster) TODO confirm the speed-up
    if n_dims == 2 and dilation == 1 and has_pyinn and torch.cuda.is_available(
    ) and use_pyinn_if_possible:
        output = P.im2col(input_nd, kernel_size, stride, padding)
    else:
        output = F.unfold(input_nd, kernel_size, dilation, padding, stride)
        out_shape = (bs, nch) + tuple(kernel_size) + out_sz
        output = output.view(*out_shape).contiguous()
    return output
def main():
    window = np.array([150, 150])
    overlap = np.array([75, 75])
    lena = scipy.misc.face(True)
    print lena.shape
    # lena = torch.from_numpy(lena.transpose(2, 0, 1))
    lena = torch.from_numpy(lena).unsqueeze(0)
    lena = Variable(lena.float()).cuda()

    ##################################################
    # Unfold and convolution
    #-------------------------------------------------
    # lena = lena.unfold(0, window[0], window[0] - overlap[0]).unfold(1, window[1], window[0] - overlap[1])
    # s = lena.size()
    # lena = lena.contiguous().view(s[0]*s[1], 1, window[0],window[1])
    # mask = make_identifier_mask(s[0], s[1])
    # mask = torch.from_numpy(mask.transpose(2, 0, 1)).unsqueeze(1)
    # print mask.size()
    # print lena.size()
    # plt.ion()
    # for i in xrange(s[0]*s[1]):
    #     t = F.conv_transpose2d(Variable(mask[i].unsqueeze(0)).float(), Variable(lena[i].unsqueeze(0)).float())
    #     plt.imshow(t.data.squeeze().numpy())
    #     plt.draw()
    #     plt.pause(0.3)

    ##################################################
    # pyinn
    #-------------------------------------------------
    lena = P.im2col(lena, window, window - overlap,
                    [0, 0])  # (768 x 1024) -> (1 x 150 x 150 x 7 x 9)
    s = lena.data.size()
    plot = torchvision.utils.make_grid(lena.squeeze().transpose(
        0, 2).transpose(1, 3).contiguous().view(s[-1] * s[-2], 1, 150,
                                                150).data,
                                       nrow=5,
                                       padding=10,
                                       normalize=True)
    plt.imshow(plot.cpu().numpy().transpose(1, 2, 0))
    plt.show()

    lena = P.col2im(lena, window, window - overlap, [0, 0])  # (1 x 750 x 950)
    plt.imshow(lena.cpu().data.squeeze().numpy())
    plt.show()

    pass
Example #7
0
    def _compute_gaussian(self, input, gaussian, norm=None):

        if norm is not None:
            input = input * norm

        shape = input.shape
        num_channels = shape[1]
        bs = shape[0]

        if self.blur > 1:
            off_0 = (self.blur - self.npixels[0] % self.blur) % self.blur
            off_1 = (self.blur - self.npixels[1] % self.blur) % self.blur
            pad_0 = int(math.ceil(off_0 / 2))
            pad_1 = int(math.ceil(off_1 / 2))
            input = torch.nn.functional.avg_pool2d(input,
                                                   kernel_size=self.blur,
                                                   padding=(pad_0, pad_1),
                                                   count_include_pad=False)
            npixels = [
                math.ceil(self.npixels[0] / self.blur),
                math.ceil(self.npixels[1] / self.blur)
            ]
            assert (npixels[0] == input.shape[2])
            assert (npixels[1] == input.shape[3])
        else:
            npixels = self.npixels

        if self.verbose:
            show_memusage(name="Init")

        if self.pyinn:
            input_col = P.im2col(input, self.filter_size, 1, self.span)
        else:
            # An alternative implementation of num2col.
            #
            # This has implementation uses the torch 0.4 im2col operation.
            # This implementation was not avaible when we did the experiments
            # published in our paper. So less "testing" has been done.
            #
            # It is around ~20% slower then the pyinn implementation but
            # easier to use as it removes a dependency.
            input_unfold = F.unfold(input, self.filter_size, 1, self.span)
            input_unfold = input_unfold.view(bs, num_channels,
                                             self.filter_size,
                                             self.filter_size, npixels[0],
                                             npixels[1])
            input_col = input_unfold

        k_sqr = self.filter_size * self.filter_size

        if self.verbose:
            show_memusage(name="Im2Col")

        product = gaussian * input_col
        if self.verbose:
            show_memusage(name="Product")

        product = product.view(
            [bs, num_channels, k_sqr, npixels[0], npixels[1]])

        message = product.sum(2)

        if self.verbose:
            show_memusage(name="FinalNorm")

        if self.blur > 1:
            in_0 = self.npixels[0]
            in_1 = self.npixels[1]
            message = message.view(bs, num_channels, npixels[0], npixels[1])
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                # Suppress warning regarding corner alignment
                message = torch.nn.functional.upsample(message,
                                                       scale_factor=self.blur,
                                                       mode='bilinear')

            message = message[:, :, pad_0:pad_0 + in_0, pad_1:in_1 + pad_1]
            message = message.contiguous()

            message = message.view(shape)
            assert (message.shape == shape)

        if norm is not None:
            message = norm * message

        return message
Example #8
0
    def _compute_gaussian(self, input, gaussian, norm=None):

        if norm is not None:
            input = input * norm

        shape = input.shape
        num_channels = shape[1]
        bs = shape[0]

        if self.blur > 1:
            off_0 = (self.blur - self.npixels[0] % self.blur) % self.blur
            off_1 = (self.blur - self.npixels[1] % self.blur) % self.blur
            pad_0 = int(math.ceil(off_0 / 2))
            pad_1 = int(math.ceil(off_1 / 2))
            input = torch.nn.functional.avg_pool2d(input,
                                                   kernel_size=self.blur,
                                                   padding=(pad_0, pad_1),
                                                   count_include_pad=False)
            npixels = [math.ceil(self.npixels[0] / self.blur),
                       math.ceil(self.npixels[1] / self.blur)]
            assert(npixels[0] == input.shape[2])
            assert(npixels[1] == input.shape[3])
        else:
            npixels = self.npixels

        if self.verbose:
            show_memusage(name="Init")

        if self.pyinn:
            input_col = P.im2col(input, self.filter_size, 1, self.span)
        else:
            # An alternative implementation of num2col.
            #
            # This has implementation uses the torch 0.4 im2col operation.
            # This implementation was not avaible when we did the experiments
            # published in our paper. So less "testing" has been done.
            #
            # It is around ~20% slower then the pyinn implementation but
            # easier to use as it removes a dependency.
            input_unfold = F.unfold(input, self.filter_size, 1, self.span)
            input_unfold = input_unfold.view(
                bs, num_channels, self.filter_size, self.filter_size,
                npixels[0], npixels[1])
            input_col = input_unfold

        k_sqr = self.filter_size * self.filter_size

        if self.verbose:
            show_memusage(name="Im2Col")

        product = gaussian * input_col
        if self.verbose:
            show_memusage(name="Product")

        product = product.view([bs, num_channels,
                                k_sqr, npixels[0], npixels[1]])

        message = product.sum(2)

        if self.verbose:
            show_memusage(name="FinalNorm")

        if self.blur > 1:
            in_0 = self.npixels[0]
            in_1 = self.npixels[1]
            message = message.view(bs, num_channels, npixels[0], npixels[1])
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")
                # Suppress warning regarding corner alignment
                message = torch.nn.functional.upsample(message,
                                                       scale_factor=self.blur,
                                                       mode='bilinear')

            message = message[:, :, pad_0:pad_0 + in_0, pad_1:in_1 + pad_1]
            message = message.contiguous()

            message = message.view(shape)
            assert(message.shape == shape)

        if norm is not None:
            message = norm * message

        return message