ValueError: Expected target size (128, 44), got torch.Size([128, 100]), LSTM Pytorch
ValueError: Expected target size (128, 44), got torch.Size([128, 100]), LSTM Pytorch
我想建立一个模型,根据前面的字符预测下一个字符。
我将文本拼接成长度为 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, vocabulary_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?与序列长度有关吗?
作为一般性评论,我只想说你问了很多不同的问题,这让人很难回答。我建议每个 Whosebug post 只问一个问题,即使这意味着提出多个 post。我将只回答我认为您要问的主要问题:“为什么我的代码会崩溃以及如何修复它?”希望这会解决您的其他问题。
根据您的代码,模型的输出维度为 (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)
我想建立一个模型,根据前面的字符预测下一个字符。 我将文本拼接成长度为 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, vocabulary_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?与序列长度有关吗?
作为一般性评论,我只想说你问了很多不同的问题,这让人很难回答。我建议每个 Whosebug post 只问一个问题,即使这意味着提出多个 post。我将只回答我认为您要问的主要问题:“为什么我的代码会崩溃以及如何修复它?”希望这会解决您的其他问题。
根据您的代码,模型的输出维度为 (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)