What defines legitimate input dimensions of a pytorch nn?
From the tutorial / example github, the network to be trained on the MNIST dataset is defined as:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5, 1)
        self.conv2 = nn.Conv2d(20, 50, 5, 1)
        self.fc1 = nn.Linear(4*4*50, 500)
        self.fc2 = nn.Linear(500, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 4*4*50)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)


The image sizes this network is trained with are 28x28 pixels.

Testing images of different sizes creates errors. To be precise: I tested images of size 27x27 and 32x32 for whom it does break with an error; an input size of 29x29 does create none.

Where is the size of 28x28 actually defined? What formula can I use to discern parameters for different input sizes for different tasks? Can one use images of different sizes as input? How?

You can backtrack the size of the input image from the first fully connected layer i.e. fc1 = Linear(4*4*50, 500). The input to the fc1 is 50x4x4 (CxHxW) (here 50 is the channel dimension as evident from the previous conv2 layer). Thus, the output of conv2 (before max-pooling operation) is 50x8x8 as you're performing pooling using 2x2 - max_pool2d(x, 2, 2).

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, ...)


Now, you can get the input size of image before the convolution operation using the formula (W-F+2P)/S + 1 = output size. Here, W is input size, F is filter/kernel size, and P is padding used, and S is the stride. Thus, (W-5+2*0)/1+1=8 => W=12. 

Hence, the input to conv2 is 20x12x12.

In the same way, we can continue the process as follows:

Output of conv1 (i.e. before max-pooling): 20x24x24
Input to conv1: 1x28x28. ((W-5+2*0)/1+1=24 => W=28)

Hence, the input image size is 1x28x28.



The error is because the fully connected layers expect input of fixed size and that defines your network. In order to pass variable sized input, you may use need to transform the input to size that your network (fc layers) expects using transformations such as cropping.

Also, there are networks that can take variable size input e.g. Fully Convolutional Networks (FCN), which doesn't contain fc layers, but only conv layers. You may also read about Spatial Pyramid Pooling (used in a network called DeepLab for semantic segmentation). Read more here.
