Ignoring one/multiple channels in pytorch-model during training and evaluation

Viewed 25

For my ML-project I have 1d-data with multiple channels (n>2, variable). After data acquisition I noticed that the data in one channel was completely unusable, and therefore would decrease the accuracy of my trained model. Still, I did not want to remove the channel entirely from my model and re-write it into a model with (n-1)-channels, as it would receive future data with n channels during classification, which would break a modified model.

Instead, I wanted to have the option of telling my model to ignore data coming from one channel during both training and evaluation, such that it would look and behave like a model with n channels, but would internally only use n-1 channels. Is that possible for pytorch-based neural networks? And if yes, how would I approach that?

2 Answers

The quick-and-dirty solution would be to simply add a pre-processing stage where you multiply this un-wanted channel by zero.

The short answer is "YES" it is possible and in many ways, but you'll have to do some testing to see which method gives the performance you're looking for.

One approach might be to create 2 first conv layers, one expecting n channels and one expecting n-1 channels as input. Then in forward check the shape of the input and pass through the corresponding conv layer. In either case, the number of output channels should be fixed such that the resulting output shape is the same. You can then simply remove the nth channel from the desired inputs.

I'd naively expect this to work better than zeroing out the inputs of the nth channel approach given in another answer because the model won't learn any side-effect behavior for the last channel. For instance, one could imagine that if the first conv layer has bias terms, a different bias would be learned in the cases where one input channel is zeroed and in the cases where that channels' values are not zeroed, resulting in poor convergence. Of course you'd have to test each approach to find out for sure.

CODE EXAMPLE (details omitted for clarity)

class Model(nn.Module):
    def __init__(self,n,out_features):
        self.n = n
        self.conv1a = nn.Conv1D(n,out_features,3) # 3 is an arbitrary kernel size
        self.conv1b = nn.Conv1D(n,out_features,3)
        ... 
        # rest of model definition here

    def forward(self,inputs):
        if inputs.shape[0] == n:
            out = self.conv1a(inputs):
        else:
            out = self.conv1b(inputs):
        ...
        # forward pass through rest of model layers
Related