我使用这个代码:
import torch.nn as nn
loss_fn=nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.00001)
loss = loss_fn(preds,labels) # Error
错误:
in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction, label_smoothing)
2844 if size_average is not None or reduce is not None:
2845 reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 2846 return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index, label_smoothing)
2847
2848
RuntimeError: Expected floating point type for target with class probabilities, got Long
运行时错误:具有类的目标的预期浮点类型 概率,长了
错误非常明显。您需要将目标张量的 dtype 转换为 float。这与您使用的损失函数有关。既然你选择了 CE 损失,你最终会得到概率。而这些概率自然都是浮点数。这意味着您的目标也应该是浮动的。例如,您可能有一个目标张量 a= [1, 0, 0, 1] 您需要将其转换为 [1.0 , 0.0 , 0.0 , 1.0]
您可以使用下表检查所有类型。
╔══════════════════════════╦═══════════════════════════════╦════════════════════╦═════════════════════════╗
║ Data type ║ dtype ║ CPU tensor ║ GPU tensor ║
╠══════════════════════════╬═══════════════════════════════╬════════════════════╬═════════════════════════╣
║ 32-bit floating point ║ torch.float32 or torch.float ║ torch.FloatTensor ║ torch.cuda.FloatTensor ║
║ 64-bit floating point ║ torch.float64 or torch.double ║ torch.DoubleTensor ║ torch.cuda.DoubleTensor ║
║ 16-bit floating point ║ torch.float16 or torch.half ║ torch.HalfTensor ║ torch.cuda.HalfTensor ║
║ 8-bit integer (unsigned) ║ torch.uint8 ║ torch.ByteTensor ║ torch.cuda.ByteTensor ║
║ 8-bit integer (signed) ║ torch.int8 ║ torch.CharTensor ║ torch.cuda.CharTensor ║
║ 16-bit integer (signed) ║ torch.int16 or torch.short ║ torch.ShortTensor ║ torch.cuda.ShortTensor ║
║ 32-bit integer (signed) ║ torch.int32 or torch.int ║ torch.IntTensor ║ torch.cuda.IntTensor ║
║ 64-bit integer (signed) ║ torch.int64 or torch.long ║ torch.LongTensor ║ torch.cuda.LongTensor ║
║ Boolean ║ torch.bool ║ torch.BoolTensor ║ torch.cuda.BoolTensor ║
╚══════════════════════════╩═══════════════════════════════╩════════════════════╩═════════════════════════╝
为了将张量转换为另一种数据类型,您可以使用类似的东西
sample_tensor=sample_tensor.type(torch.FloatTensor)
或
sample_tensor=sample_tensor.to(torch.float )
(我不确定是否需要重新分配张量)
问题在于您将错误的
preds
(张量)值传递给 loss_fn
函数。仔细观察,您会发现您正在传递 preds = torch.argmax(preds, dim=1)
的输出,而您应该传递 preds = model(sent_id, mask)
的输出。这样做会将两个 dtype int64 张量传递给损失函数。但是,损失函数 (CrossEntropyLoss) 需要一个 dtype float32 的张量作为其第一个参数(即输入参数)——请参阅 https://pytorch.org/docs/stable/ generated/torch.nn 的“示例” .CrossEntropyLoss.html。然后你会得到一个错误:“预期的浮点类型...”
要解决这个问题,您可以在更改
preds
的值之前(即在 preds = torch.argmax(preds, dim=1)
之前)计算损失,如下所示。或者,您可以为 model()
的输出指定另一个名称,例如 outp
,并将其传递给损失函数,例如:loss_fn(outp, labels)
。
# get model predictions for the current batch
preds = model(sent_id, mask)
# compute the loss between actual and predicted values
loss = loss_fn(preds, labels)
preds =torch.argmax(preds, dim=1)
我在下面遇到了同样的错误:
运行时错误:具有类概率的目标的预期浮点类型,得到了 Long
当我将
int
类型的张量设置为 CrossEntropyLoss()的
target
参数时,如下所示:
import torch
tensor1 = torch.tensor([0., 1., 2.])
tensor2 = torch.tensor([3, 4, 5]) # Here
cel = nn.CrossEntropyLoss()
cel(input=tensor1, target=tensor2) # Error
# ↑↑↑↑ Here ↑↑↑↑
所以,我将
float
类型的张量设置为target
的CrossEntropyLoss()
参数,然后我可以得到如下所示的结果:
*备注:
target
张量相同的input
张量被视为类别概率,其类型必须是float
类型。target
张量不同的 input
张量被视为类型必须为 int
类型的类索引。import torch
tensor1 = torch.tensor([0., 1., 2.])
tensor2 = torch.tensor([3., 4., 5.]) # Here
cel = nn.CrossEntropyLoss()
cel(input=tensor1, target=tensor2) # tensor(14.8913)
# ↑↑↑↑ Here ↑↑↑↑