Handling varying in_channels in Conv1D layer

I am training a convolutional neural network in pytorch. I’m training it on data in the form of [n, 3] where ‘n’ can be any number. The first layer in my network is a Conv1d layer that operates over the ‘n’ portion of the input tensor. How can I define my model’s architecture so that it accepts varying number of in_channels in the first conv layer, because during testing ‘n’ might change, the reason for that is because I’m working with 3D data, and my model is classifying 3D Models based upon their vertices (having the shape [n, 3]), and during testing the shape of the vertices might change.

In Keras I don’t have to worry about the in_channels of a convolutional layer, how can I implement a similar logic in PyTorch.

Following is my architecture, it’s learning brilliantly, but during testing on different 3d models, the shape [n, 3] changes, how do I fix this? Note padding is not an option, because it can distort the shape of the vertices. Also, FYI my input tensor during training is a packed tensor, meaning that I pack all the vertices of each 3D model in my batch into one [n, 3] tensor (and that is a requirement).

class ClassificationModel(nn.Module):
    # Currently I'm passing 'n' of the training samples as the in_channels
    def __init__(self, in_channels):
        super().__init__()

        self._in_channels = in_channels
        
        self._conv_sequential = nn.Sequential(
            nn.Conv1d(in_channels=self._in_channels, out_channels=4096, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=4096, out_channels=2048, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=2048, out_channels=1024, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=1024, out_channels=512, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=512, out_channels=256, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=256, out_channels=64, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=64, out_channels=16, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
            nn.Conv1d(in_channels=16, out_channels=2, kernel_size=3, stride=1, padding="same"),
            nn.Tanh(),
        )
        
        self._linear_sequential = nn.Sequential(
            nn.Linear(in_features=3, out_features=1),
        )

    def forward(self, mesh: pytorch3d.structures.Meshes):
        vertices = mesh.verts_packed()

        output: torch.Tensor = self._conv_sequential(vertices)
        output: torch.Tensor = self._linear_sequential(output)

        
        return F.sigmoid(output)

Perhaps I’m unclear, but why aren’t you just flattening it?

From what you’ve described, here is what I would suggest doing:

  1. Reshape the (B, n, 3) into (B, 1, n*3);
  2. Change the stride to 3(unless there’s some significance to the order of vertices).
  3. The out_channels of the first layer can be whatever you want.
  4. After all convolutions are applied and before the feedforward network, use nn.AdaptiveAvgPool1d.

Greetings;
Thankyou very much, I’ll try your solution and then inform here.

Thankyou J_Johnson, you’re solution worked for me but with a little changing, rather than using nn.AdaptiveAvgPool1d at the end of the convolutions, to solve my problem I used it in before the first convolution to fix the changing in_channels problem in the first layer.

1 Like