In the simple use case nn.Linear layers expect a 2D input in the shape [batch_size, nb_features] (you can add an additional dimension, which is described in more detail in the docs).
You are currently flattening the features into the batch dimension, which is usually wrong. I’m not familiar with your use case, so it might be exactly what you want to achieve, but you should be able to explain it, why this is needed. In your current use case you would not treat the input as e.g. batch_size=10 samples which each contain nb_features features, but would instead increase the number of samples by multiplying the batch size with the feature dimension.
The proposed way of flattening the activation (either via using the default arguments in nn.Flatten or via the view operation) will keep the batch dimension equal (i.e. the number of samples in a batch stay the same) and will flatten all other dimensions into dim1.
This line of code for example:
self.l0 = nn.Linear(numberOfFeatures*batchSize, 30)

changes the number of samples in a batch and will thus yield a shape mismatch in the loss calculation unless you also change the target.