PyTorch Conv 层的维度问题

Dimensionality problem with PyTorch Conv layers

我正在尝试使用一些输入信号在 PyTorch 中训练神经网络。这些层是 conv1d。我输入的形状是 [100, 10],意思是 100 个长度为 10 的信号。

但是当我执行训练时,我有这个错误: 给定 groups=1,权重大小 [100, 10, 1],预期输入 [1, 1, 10] 有 10 个通道,但得到 1 个通道

config = [10, 100, 100, 100, 100, 100, 100, 100] 
batch_size = 1
epochs = 10
learning_rate = 0.001
kernel_size = 1
    
class NeuralNet(nn.Module):
            
        def __init__(self, config, kernel_size=1):
             super().__init__()
                
             self.config = config
                
             self.layers = nn.ModuleList([nn.Sequential(
                    nn.Conv1d(self.config[i], self.config[i + 1], kernel_size = kernel_size),
                    nn.ReLU()) 
                    for i in range(len(self.config)-1)])
         
             self.last_layer = nn.Linear(self.config[-1], 3)
             self.layers.append(nn.Flatten())
             self.layers.append(self.last_layer)
        
        
        
      def forward(self, x):
           
            for i, l in enumerate(self.layers):
                x = l(x)
            return x
    
    
def loader(train_data, batch_size):
     
  inps = torch.tensor(train_data[0])
  tgts = torch.tensor(train_data[1])
        
  inps = torch.unsqueeze(inps, 1)
  dataset = TensorDataset(inps, tgts)
  train_dataloader = DataLoader(dataset, batch_size = batch_size)
        
  return train_dataloader

起初,我的代码没有 unsqueez(inps) 行,我遇到了完全相同的错误,但后来我添加了这一行,认为我必须输入大小 (num_examples, num_channels, lenght_of_signal) 但根本没有解决问题。

提前感谢您的回答

nn.Conv1d 期望输入的形状为 (batch_size, num_of_channels, seq_length)。它的参数允许直接设置输出通道数 (out_channels) 并使用例如 stride 更改输出长度。为了让 conv1d 层正常工作,它应该知道输入通道的数量 (in_channels),而第一个卷积不是这样:input.shape == (batch_size, 1, 10),因此 num_of_channels = 1,而 self.layers[0] 中的卷积] 期望此值等于 10(因为 in_channelsself.config[0]self.config[0] == 10 设置)。因此,要修复此问题,请在配置中再添加一个值:

config = [10, 100, 100, 100, 100, 100, 100, 100]  # as in snippet above
config = [1] + config

此时 convs 应该工作正常,但 self.layers 中还有另一个障碍 -- 最后的线性层。因此,如果使用 kernel_size of 1,则在最终卷积批次之后将具有形状 (batch_size, 100, 10),并且在展平 (batch_size, 100 * 10) 之后,而 last_layer 期望输入形状为 (batch_size, 100) .因此,如果知道最终转换层之后的序列长度(如果您使用默认步幅为 1 且默认填充为 0 的 kernel_size 1 肯定会出现这种情况——长度保持不变),last_layer 应定义为:

self.last_layer = nn.Linear(final_length * self.config[-1], 3)

并且在上面的代码片段中 final_length 可以设置为 10(因为满足前面括号中的条件)。要了解 conv1d 中的形状如何变换,请看下面 gif 中的简单示例(此处 batch_size 等于 1):