0
$\begingroup$

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],
                   mode='circular')
    return source


class ResidualBlock(nn.Module):
    def __init__(self, in_c, mid_c, out_c, dropout_prob, dilation_val):
        super().__init__()
        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.InstanceNorm2d(num_features=mid_c),
            nn.ELU(alpha=1.),
            nn.Dropout(p=dropout_prob),
            nn.Conv2d(in_channels=mid_c, out_channels=out_c,
                      kernel_size=3, padding_mode='circular', dilation=dilation_val),
            nn.InstanceNorm2d(num_features=out_c)
        ]

        self.block = nn.Sequential(*block)
        return

    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):
        super().__init__()
        num_f = 64

        head = [
            nn.Conv2d(in_channels=in_c, out_channels=num_f,
                      kernel_size=1, padding_mode='circular'),
            nn.InstanceNorm2d(num_features=num_f),
            nn.ELU(alpha=1.)
        ]
        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'),
            nn.Sigmoid()
        ]
        self.final = nn.Sequential(*final)
        return

    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.

$\endgroup$

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.