Neural network pytorch线性方法中的多维输入?

Neural network pytorch线性方法中的多维输入?,neural-network,deep-learning,pytorch,perceptron,Neural Network,Deep Learning,Pytorch,Perceptron,在构建一个简单的感知器神经网络时,我们通常都会将格式为(批次大小、特征)的2D输入矩阵传递给2D权重矩阵,类似于中的这个简单神经网络。我总是假设神经网络的感知器/密集/线性层只接受2D格式的输入并输出另一个2D输出。但最近我遇到了这个pytorch模型,其中一个线性层接受一个3D输入张量并输出另一个3D张量(o1=self.a1(x)) 这就是我的问题 上述神经网络是否有效?这就是模型是否能正确训练 即使通过3D输入x=torch.randn(10,3,4),为什么pytorchnn.Linea

在构建一个简单的感知器神经网络时,我们通常都会将格式为
(批次大小、特征)
的2D输入矩阵传递给2D权重矩阵,类似于中的这个简单神经网络。我总是假设神经网络的感知器/密集/线性层只接受2D格式的输入并输出另一个2D输出。但最近我遇到了这个pytorch模型,其中一个线性层接受一个3D输入张量并输出另一个3D张量(
o1=self.a1(x)

这就是我的问题

  • 上述神经网络是否有效?这就是模型是否能正确训练
  • 即使通过3D输入
    x=torch.randn(10,3,4)
    ,为什么pytorch
    nn.Linear
    不会显示任何错误并给出3D输出

  • PyTorch的较新版本允许接受N-D输入张量,唯一的限制是输入张量的最后一个维度将等于线性层的
    in_特征。然后在张量的最后一个维度上应用线性变换。
    例如,如果
    in_features=5
    out_features=10
    并且输入张量
    x
    的维数为2-3-5,那么输出张量的维数将为2-3-10。

    如果您查看,您会发现
    线性
    层确实接受任意形状的张量,其中,只有最后一个维度必须与构造函数中指定的
    in_features
    参数匹配

    输出将具有与输入完全相同的形状,只有最后一个维度将更改为构造函数中指定的
    out\u features

    它的工作方式是将相同的层(具有相同的权重)应用于每个(可能的)多个输入。在您的示例中,您有一个输入形状
    (10,3,4)
    ,它基本上是一组
    10*3==30
    4维向量。因此,您的层
    a1
    a2
    应用于所有这30个向量,以生成另一个
    10*3==30
    4D向量作为输出(因为您在构造函数中指定了
    out\u features=4

    因此,要回答您的问题:

    上述神经网络是否有效?这就是模型是否能正确训练

    是的,它是有效的,并且将从技术pov“正确”培训。但是,与任何其他网络一样,这是否能正确解决您的问题是另一个问题

    即使经过3D输入x=torch.randn(10,3,4),为什么pytorch nn.Linear不显示任何错误并给出3D输出

    嗯,因为它被定义为这样工作

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.optim as optim
    
    class Net(nn.Module):
        def __init__(self):
            super().__init__()
            self.a1 = nn.Linear(4,4)
            self.a2 = nn.Linear(4,4)
            self.a3 = nn.Linear(9,1)
        def forward(self,x):
            o1 = self.a1(x)
            o2 = self.a2(x).transpose(1,2)
            output = torch.bmm(o1,o2)
            output = output.view(len(x),9)
            output = self.a3(output)
            return output
    
    x = torch.randn(10,3,4)
    y = torch.ones(10,1)
    
    net = Net()
    
    criterion = nn.MSELoss()
    optimizer = optim.Adam(net.parameters())
    
    for i in range(10):
        net.zero_grad()
        output = net(x)
        loss = criterion(output,y)
        loss.backward()
        optimizer.step()
        print(loss.item())