PyTorch 损失函数中目标和预测张量的形状
Shape of target and predictions tensors in PyTorch loss functions
我对 nn.CrossEntropyLoss
中张量的输入形状感到困惑。
我正在尝试为文本序列实现一个简单的自动编码器。我的问题的核心可以用下面的代码来说明
predictions = torch.rand(2, 3, 4)
target = torch.rand(2, 3)
print(predictions.shape)
print(target.shape)
nn.CrossEntropyLoss(predictions.transpose(1, 2), target)
在我的例子中,预测的形状为 (time_step, batch_size, vocabulary_size)
,而目标的形状为 (time_step, batch_size)
。接下来,我根据 description 转置预测,在我的例子中,预测的第二个维度应该是 类 - vocabulary_size 的数量。代码 returns 错误 RuntimeError: bool value of Tensor with more than one value is ambiguous
。有人可以告诉我如何使用该死的东西吗?提前致谢!
您不是在调用损失函数,而是在构建它。 nn.CrossEntropyLoss
构造函数的签名是:
nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')
您将预测设置为 weight
,将目标设置为 size_average
,
其中 weight
是 classes 的可选重新缩放,size_average
已弃用,但需要一个布尔值。目标是大小为 [2, 3] 的张量,无法转换为布尔值。
您需要先创建损失函数,因为您没有使用构造函数的任何可选参数,所以您没有指定任何参数。
# Create the loss function
cross_entropy = nn.CrossEntropyLoss()
# Call it to calculate the loss for your data
loss = cross_entropy(predictions.transpose(1, 2), target)
或者直接使用功能版nn.functional.cross_entropy
:
import torch.nn.functional as F
loss = F.cross_entropy(predictions.transpose(1, 2), target)
class版本的优势,与功能版本相比,您只需指定一次额外的参数(例如weight
),而不必手动提供它们每次。
关于张量的维度,批量大小必须是第一维度,因为损失是批量中每个元素的平均,所以你有大小为 [[=47= 的损失张量]]。如果你使用 reduction="none"
,你会得到批处理中每个元素的这些损失,但默认情况下 (reduction="mean"
) 返回这些损失的平均值。如果跨时间步而不是批次取平均值,结果会有所不同。
最后,目标必须是 class 索引,这意味着它们需要具有类型 torch.long
而不是 torch.float
。在这个随机选择的示例中,您可以使用 torch.randint
.
创建随机 classes
predictions = torch.rand(2, 3, 4)
target = torch.randint(4, (2, 3))
# Reorder the dimensions
# From: [time_step, batch_size, vocabulary_size]
# To: [batch_size, vocabulary_size, time_step]
predictions = predictions.permute(1, 2, 0)
# From: [time_step, batch_size]
# To: [batch_size, time_step]
target = target.transpose(0, 1)
F.cross_entropy(predictions, target)
我对 nn.CrossEntropyLoss
中张量的输入形状感到困惑。
我正在尝试为文本序列实现一个简单的自动编码器。我的问题的核心可以用下面的代码来说明
predictions = torch.rand(2, 3, 4)
target = torch.rand(2, 3)
print(predictions.shape)
print(target.shape)
nn.CrossEntropyLoss(predictions.transpose(1, 2), target)
在我的例子中,预测的形状为 (time_step, batch_size, vocabulary_size)
,而目标的形状为 (time_step, batch_size)
。接下来,我根据 description 转置预测,在我的例子中,预测的第二个维度应该是 类 - vocabulary_size 的数量。代码 returns 错误 RuntimeError: bool value of Tensor with more than one value is ambiguous
。有人可以告诉我如何使用该死的东西吗?提前致谢!
您不是在调用损失函数,而是在构建它。 nn.CrossEntropyLoss
构造函数的签名是:
nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')
您将预测设置为 weight
,将目标设置为 size_average
,
其中 weight
是 classes 的可选重新缩放,size_average
已弃用,但需要一个布尔值。目标是大小为 [2, 3] 的张量,无法转换为布尔值。
您需要先创建损失函数,因为您没有使用构造函数的任何可选参数,所以您没有指定任何参数。
# Create the loss function
cross_entropy = nn.CrossEntropyLoss()
# Call it to calculate the loss for your data
loss = cross_entropy(predictions.transpose(1, 2), target)
或者直接使用功能版nn.functional.cross_entropy
:
import torch.nn.functional as F
loss = F.cross_entropy(predictions.transpose(1, 2), target)
class版本的优势,与功能版本相比,您只需指定一次额外的参数(例如weight
),而不必手动提供它们每次。
关于张量的维度,批量大小必须是第一维度,因为损失是批量中每个元素的平均,所以你有大小为 [[=47= 的损失张量]]。如果你使用 reduction="none"
,你会得到批处理中每个元素的这些损失,但默认情况下 (reduction="mean"
) 返回这些损失的平均值。如果跨时间步而不是批次取平均值,结果会有所不同。
最后,目标必须是 class 索引,这意味着它们需要具有类型 torch.long
而不是 torch.float
。在这个随机选择的示例中,您可以使用 torch.randint
.
predictions = torch.rand(2, 3, 4)
target = torch.randint(4, (2, 3))
# Reorder the dimensions
# From: [time_step, batch_size, vocabulary_size]
# To: [batch_size, vocabulary_size, time_step]
predictions = predictions.permute(1, 2, 0)
# From: [time_step, batch_size]
# To: [batch_size, time_step]
target = target.transpose(0, 1)
F.cross_entropy(predictions, target)