【问题标题】:ValueError: Expected target size (128, 44), got torch.Size([128, 100]), LSTM PytorchValueError: Expected target size (128, 44), gottorch.Size([128, 100]), LSTM Pytorch
【发布时间】:2021-04-04 18:54:49
【问题描述】:

我想建立一个模型,根据前面的字符预测下一个字符。 我已将文本拼接成长度 = 100 的整数序列(使用数据集和数据加载器)。

我的输入和目标变量的维度是:

inputs dimension: (batch_size,sequence length). In my case (128,100)
targets dimension: (batch_size,sequence length). In my case (128,100)

在前向传递之后,我得到了我的预测维度:(batch_size, sequence_length, words_size),在我的例子中是 (128,100,44)

但是当我使用nn.CrossEntropyLoss() 函数计算我的损失时:

batch_size = 128
sequence_length   = 100
number_of_classes = 44
# creates random tensor of your output shape
output = torch.rand(batch_size,sequence_length, number_of_classes)
# creates tensor with random targets
target = torch.randint(number_of_classes, (batch_size,sequence_length)).long()

# define loss function and calculate loss
criterion = nn.CrossEntropyLoss()
loss = criterion(output, target)
print(loss)

我收到一个错误:

ValueError: Expected target size (128, 44), got torch.Size([128, 100])

问题是:我应该如何处理多对多 LSTM 预测的损失函数的计算?特别是序列维度?根据nn.CrossEntropyLoss 维度必须是(N,C,d1,d2...dN),其中 N 是 batch_size,C - 类数。但是什么是D?和序列长度有关吗?

【问题讨论】:

  • 您的输入是(128, 100, 44),并且您尝试预测下一个字符(基本上是“第 101 个”字符)。为什么你的预测的seq_length100?就我个人而言,我会让它输出(128, 44)(因为我猜 dim=1 是长度为 44 的 OHE),并使用该字符预测计算 CrossEntropyLoss。编辑:也许我看错了,您是否希望在每个时间步(即在输入序列的每个字符预测之后)计算 CEL?
  • @Ivan:不,我的输入有维度 (128,100) - (batch_size, sequence_length)。基本上,我将文本(字符串)标记为整数,然后将输入定义为标记化_文本 [:-1],将目标定义为标记化_文本 [1:]。所以 Target 向右移动了一个标记。我想做的是:使用 Cross_entropy 将输出中的每个预测整数(一批中的 100 个整数)与目标中的整数(一批中的 100 个整数)进行比较。
  • @Ivan 我没有进行一次热编码,我认为这不是必需的。所以我想在每个时间步预测字符

标签: pytorch lstm recurrent-neural-network


【解决方案1】:

作为一般性评论,我只想说您提出了许多不同的问题,这让别人很难回答。我建议每个 StackOverflow 帖子只问一个问题,即使这意味着要发布多个帖子。我将只回答我认为您要问的主要问题:“为什么我的代码崩溃以及如何修复它?”希望这能解决您的其他问题。

根据您的代码,模型的输出尺寸为 (128, 100, 44) = (N, D, C)。这里 N 是小批量大小,C 是类数,D 是输入的维度。您使用的交叉熵损失期望输出具有维度 (N, C, D),目标具有维度 (N, D)。要清除说 (N, C, D1, D2, ..., Dk) 的文档,请记住您的输入可以是任意维度的任意张量。在您的情况下,输入的长度为 100,但没有什么可以阻止某人使用 100x100 图像作为输入来制作模型。 (在这种情况下,损失会期望输出具有维度 (N, C, 100, 100)。)但是在您的情况下,您的输入是一维的,因此您的输入长度只有一个 D=100。

现在我们看到了错误,输出应该是 (N, C, D),但你的输出是 (N, D, C)。您的目标具有 (N, D) 的正确尺寸。您有两条路径可以解决此问题。首先是更改网络的结构,使其输出为 (N, C, D),这可能很容易,也可能不太容易,或者您在模型的上下文中想要什么。第二种选择是在损失计算时使用 torch.transpose https://pytorch.org/docs/stable/generated/torch.transpose.html 转置轴

batch_size = 128
sequence_length   = 100
number_of_classes = 44
# creates random tensor of your output shape (N, D, C)
output = torch.rand(batch_size,sequence_length, number_of_classes)
# transposes dimensionality to (N, C, D)
tansposed_output = torch.transpose(output, 1, 2)
# creates tensor with random targets
target = torch.randint(number_of_classes, (batch_size,sequence_length)).long()

# define loss function and calculate loss
criterion = nn.CrossEntropyLoss()
loss = criterion(transposed_output, target)
print(loss)

【讨论】:

    猜你喜欢
    • 2021-02-14
    • 2020-02-14
    • 2021-03-11
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2021-07-05
    • 2011-04-13
    • 1970-01-01
    相关资源
    最近更新 更多