最后一层的张量输出在 PyTorch 中的形状错误

Posted

技术标签:

【中文标题】最后一层的张量输出在 PyTorch 中的形状错误【英文标题】:Tensor output from final layer is of the wrong shape in PyTorch 【发布时间】:2020-06-17 15:02:17 【问题描述】:

我正在构建一个序列到标签的分类器,其中输入数据是文本序列,输出标签是二进制的。该模型非常简单,具有 GRU 隐藏层和 Word Embeddings 输入层。我想要一个[n, 60] 输入来输出一个[n, 1] 标签,但是Torch 模型返回一个[n, 60] 输出。

我的模型,层数最少:

class Model(nn.Module):
    def __init__(self, weights_matrix, hidden_size, num_layers):
        super(Model, self).__init__()
        self.embedding, num_embeddings, embedding_dim = create_emb_layer(weights_matrix, True)
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.gru = nn.GRU(embedding_dim, hidden_size, num_layers, batch_first=True)
        self.out = nn.Linear(hidden_size, 1)
    def forward(self, inp, hidden):
        emb = self.embedding(inp);
        out, hidden = self.gru(emb, hidden)
        out = self.out(out);
        return out, hidden;

    def init_hidden(self, batch_size):
        return torch.zeros(self.num_layers, batch_size, self.hidden_size).to(device);

模型层:

Model(
  (embedding): Embedding(184901, 100)
  (gru): GRU(100, 60, num_layers=3, batch_first=True)
  (out): Linear(in_features=60, out_features=1, bias=True)
)

我的数据的输入形状是:Xtorch.Size([64, 60]),和Ytorch.Size([64, 1]),对于大小为 64 的单批。

当我通过模型运行 X 张量时,它应该输出一个标签,但是,分类器的输出是 torch.Size([64, 60, 1])。要运行模型,我执行以下操作:

for epoch in range(1):
    running_loss = 0.0;

    batch_size = 64;
    hidden = model.init_hidden(batch_size)
    for ite, data in enumerate(train_loader, 0):
        x, y = data[:,:-1], data[:,-1].reshape(-1,1)

        optimizer.zero_grad();

        outputs, hidden = model(x, hidden);

        hidden = Variable(hidden.data).to(device);
        loss = criterion(outputs, y);

        loss.backward();
        optimizer.step();

        running_loss = running_loss + loss.item();
        if ite % 2000 == 1999:
            print('[%d %5d] loss: %.3f'%(epoch+1, ite+1, running_loss / 2000))
        running_loss = 0.0;

当我打印outputsshape 时,它是64x60x1 而不是64x1。我也没有得到的是criterion 函数如何在输出和标签的形状不一致时计算损失。对于 Tensorflow,这总是会引发错误,但对于 Torch 则不会。

【问题讨论】:

【参考方案1】:

您的模型的输出形状为 torch.Size([64, 60, 1]),即 64 是批量大小,并且 (60, 1) 对应于预期的 [n, 1]

假设您使用的是nn.CrossEntropy(input, target),它预计输入为(N,C),目标为(N),其中C 是类数。

您的输出是一致的,因此会评估损失。

例如,

outputs = torch.randn(3, 2, 1)
target = torch.empty(3, 1, dtype=torch.long).random_(2)

criterion = nn.CrossEntropyLoss(reduction='mean')
print(outputs)
print(target)
loss = criterion(outputs, target)
print(loss)

# outputs
tensor([[[ 0.5187],
         [ 1.0320]],

        [[ 0.2169],
         [ 2.4480]],

        [[-0.4895],
         [-0.6096]]])
tensor([[0],
        [1],
        [0]])
tensor(0.5731)

阅读更多here。

【讨论】:

这有帮助,但不能回答我的问题。我认为我的问题是预测标签与实际标签的维度不同。我认为这是因为我没有通过任何类型的激活函数或池化运行最后一层输出。

以上是关于最后一层的张量输出在 PyTorch 中的形状错误的主要内容,如果未能解决你的问题,请参考以下文章

如何获得每一层的权重形状?

实践指南 | 检测 PyTorch 中的张量形状错误

pytorch 中LSTM模型获取最后一层的输出结果,单向或双向

张量(tensor)的阶、形状、数据类型

(pytorch / mse) 如何改变张量的形状?

nn.linear()