[构建简单的感知器神经网络时,我们通常将(batch_size,features)
格式的2D输入矩阵传递给2D权重矩阵,类似于numpy中的简单神经网络。我一直假设神经网络的Perceptron / Dense / Linear层仅接受2D格式的输入并输出另一个2D输出。但是最近我遇到了这个pytorch模型,其中线性层接受3D输入张量并输出另一个3D张量(o1 = self.a1(x)
)。
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())
这些是我的问题,
x = torch.randn(10,3,4)
,为什么pytorch nn.Linear
都没有显示任何错误并给出了3D输出?较新版本的PyTorch允许nn.Linear
接受N-D输入张量,唯一的限制是输入张量的最后一个尺寸将等于线性层的nn.Linear
。然后将线性变换应用于张量的最后一个维度。例如,如果in_features
和in_features=5
且输入张量out_features=10
的尺寸为2-3-5,则输出张量的尺寸为2-3-10。
如果您查看x
,您会发现documentation层确实接受任意形状的张量,其中只有最后一个维度必须与您在构造函数中指定的Linear
参数匹配。
输出将具有与输入完全相同的形状,只有最后一个尺寸将更改为在构造函数中指定为in_features
的任何尺寸。
它的工作方式是将相同的图层(具有相同的权重)应用于(可能)多个输入中的每个输入。在您的示例中,输入形状为out_features
,基本上是一组(10, 3, 4)
4维向量。因此,将图层10 * 3 == 30
和a1
应用于所有这30个向量,以生成另一个a2
4D向量作为输出(因为在构造函数中指定了10 * 3 == 30
)。
所以,回答您的问题:
以上神经网络有效吗?那就是模型是否可以正确训练?
是的,它是有效的,并且将从技术角度对它进行“正确”的培训。但是,与其他任何网络一样,这是否能够真正解决您的问题是另一个问题。
即使在传递3D输入x = torch.randn(10,3,4)之后,为什么pytorch nn.Linear没有显示任何错误并给出了3D输出?
嗯,因为它被定义为以这种方式工作。