I have a huge dataset where I have a tensor with 535 channels but varying spatial dimension (but always a square) it can vary from 100X100 to 700X700. What I wish to predict is a sort of a binary map with the same spatial resolution, so some sort of segmentation task but not classically.

I feed the network with a batch size of 1 so that I would be able to train the model but I think that the way I pad the tensors to keep the dimension constant might be problematic because some times the "1" pixel are at the edges and when I pad the tensor I lost information (because I first decreased the size and then just pad randomly)

My network implementation is:

import torch.nn as nn
import torch.nn.functional as F

def pad_tensor(source, target):
    diff_y = target.size()[2] - source.size()[2]
    diff_x = target.size()[3] - source.size()[3]

    source = F.pad(input=source,
                   pad=[diff_x // 2, diff_x - diff_x // 2, diff_y // 2, diff_y - diff_y // 2],
    return source

class ResidualBlock(nn.Module):
    def __init__(self, in_c, mid_c, out_c, dropout_prob, dilation_val):
        self.act = nn.ELU(alpha=1.)

        block = [
            nn.Conv2d(in_channels=in_c, out_channels=mid_c,
                      kernel_size=3, padding_mode='circular', dilation=dilation_val),
            nn.Conv2d(in_channels=mid_c, out_channels=out_c,
                      kernel_size=3, padding_mode='circular', dilation=dilation_val),

        self.block = nn.Sequential(*block)

    def forward(self, x):
        res = self.block(x)
        res = pad_tensor(res, x)
        return self.act(res + x)

class Net(nn.Module):
    def __init__(self, in_c, out_c, num_blocks, dropout_p):
        num_f = 64

        head = [
            nn.Conv2d(in_channels=in_c, out_channels=num_f,
                      kernel_size=1, padding_mode='circular'),
        self.head = nn.Sequential(*head)

        main_block = []
        dilation = 1
        for _ in range(num_blocks):
            main_block.append(ResidualBlock(in_c=num_f, mid_c=num_f, out_c=num_f,
                                            dropout_prob=dropout_p, dilation_val=dilation))
            dilation *= 2
            if dilation > 16:
                dilation = 1
        self.main_block = nn.Sequential(*main_block)

        final = [
            nn.Conv2d(in_channels=num_f, out_channels=out_c,
                      kernel_size=1, padding_mode='circular'),
        self.final = nn.Sequential(*final)

    def forward(self, x):
        res = self.head(x)
        res = self.main_block(res)
        return self.final(res)

Is there a network that performs convolution and doesn't affect the spatial dimensions at all?

I was also thinking about an encoder-decoder network but I wasn't sure I be able to keep the spatial dimensions properly.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.