RuntimeError: Expected 3-dimensional input for 3-dimensional weight [3, 1, 3], but got 2-dimensional input of size [64, 200] instead

Hello,

I am trying to run a CNN that looks like this:

> class MyModel(nn.Module):
>     def __init__(self):
>         super(MyModel, self).__init__()
>         self.conv1 = nn.Conv1d(1, 3, kernel_size=3) 
>         self.conv2 = nn.Conv1d(3, 6, kernel_size=6) 
>         self.conv3 = nn.Conv1d(6, 12, kernel_size=12) 
>         self.conv4 = nn.Conv1d(12,24, kernel_size=24) 
>         self.conv5 = nn.Conv1d(24,48, kernel_size = 48)
>         self.conv_drop = nn.Dropout2d()
>         self.conv6_transpose = nn.ConvTranspose1d(48,24, kernel_size = 48)
>         self.conv7_transpose = nn.ConvTranspose1d(24,12, kernel_size = 24)
>         self.conv8_transpose = nn.ConvTranspose1d(12,6, kernel_size = 12)
>         self.conv9_transpose=nn.ConvTranspose1d(6,3, kernel_size = 6)
>         self.conv10_transpose = nn.ConvTranspose1d(3,1, kernel_size = 3)
>        
>     
>         self.bn1 = nn.BatchNorm1d(3)
>         self.bn2 = nn.BatchNorm1d(6)
>         self.bn3 = nn.BatchNorm1d(12)
>         self.bn4 = nn.BatchNorm1d(24)
>         self.bn5 = nn.BatchNorm1d(48)
>         self.bn6 = nn.BatchNorm1d(24)
>         self.bn7 = nn.BatchNorm1d(12)
>         self.bn8 = nn.BatchNorm1d(6)
>         self.bn9 = nn.BatchNorm1d(3)
>         self.bn10 = nn.BatchNorm1d(1)
>        
>     
>     def forward(self, x):
>    
>        #downsample
>         out = self.conv1(x)
>         out = F.relu(out)
>         out = self.bn1(out)
>         
>         out = self.conv2(out)
>         out = F.relu(out)
>         out = self.bn2(out)
>         
>         out = self.conv3(out)
>         out = F.relu(out)
>         out = self.bn3(out)
>         
>         out = self.conv4(out)
>         out = F.relu(out)
>         out = self.bn4(out)
>         
>         #bottleneck
>         out = self.conv5(out)
>         out = F.relu(out)
>         out = self.bn5(out)
>         out = self.conv_drop(out)
>         
>         #upsample
>         out = self.conv6_transpose(out)
>         out = self.conv6_drop(out)
>         out = F.relu(out)
>         out = out.unsqueeze(1)
>         out = self.bn6(out)
>         
>         out = self.conv7_transpose(out)
>         out = self.conv_drop(out)
>         out = F.relu(out)
>         out = out.unsqueeze(1)
>         out = self.bn7(out)
>         
>         out = self.conv8_transpose(out)
>         out = self.conv_drop(out)
>         out = F.relu(out)
>         out = out.unsqueeze(1)
>         out = self.bn8(out)
>         
>         out = self.conv9_transpose(out)
>         out = self.conv_drop(out)
>         out = F.relu(out)
>         out = out.unsqueeze(1)
>         out = self.bn9(out)
>         
>         out = self.conv10_transpose(out)
>         out = self.conv_drop(out)
>         out = F.relu(out)
>         out = out.unsqueeze(1)
>         out = self.bn10(out)
>         
>         return out
>         
>         
> model = MyModel()

However now I ge the error: Expected 3-dimensional input for 3-dimensional weight [3, 1, 3], but got 2-dimensional input of size [64, 200] instead. Does anybody know what can be done now? I am relatively new to pytorch so help would be welcome :slight_smile:

The input data is a tensor that needs to undergo several conv1d’s and transpose conv1d’s to downsample and upsample.

1 Like

Based on the error message, it seems that the first conv layer raises this issue.
Assuming your input of [64, 200] is using the dimensions [batch_size, seq_length], then you should add the channel dimension via:

input = input.unsqueeze(1)

Let me know, if that helps.

2 Likes

Thanks, it helped.

However, now I get a message ValueError: expected 4D input (got 3D input)
Does this have to do with the fact that I am downsampling and then upsampling, meaning i have to unsqueeze them again?

This error is most likely thrown by nn.Dropout2d(), which expects an input of [batch_size, channels, height, width] to zero out entire channels.
If you want to apply the same behavior to your use case, you could unsqueeze a fake spatial dimension, use the dropout layer, and squeeze the activation afterwards.

I am having a similar issue with some code I am working on. Where should [input = input.unsqueeze(1)] be inserted to add the channel dimension?

It depends on your use case and where an error is raised.
E.g. if the model’s forward pass raises an error about a missing channel dimension, you would need to unsqueeze the input before feeding it to the model:

output = model(input)
# error about a missing channel dimension

# fix
input = input.unsqueeze(0)
output = model(input)