You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch图像训练报错:RuntimeError: expected scalar type Long but found Float

PyTorch CrossEntropyLoss 类型错误及UNet训练问题

问题描述

我是PyTorch新手,正在用它做图像处理任务,遇到了CrossEntropyLoss计算时的错误,同时在训练UNet处理[5, 3, 544, 688]尺寸图像时也存在疑问。

错误代码及报错信息

测试代码:

model.to(device)

# Specify the loss function and optimizer
#criterion = torch.nn.CrossEntropyLoss()

criterion = nn.CrossEntropyLoss()

output = Variable(torch.randn(10, 120).float())
labels = Variable(torch.FloatTensor(10).uniform_(0, 120).long())

loss = criterion(output, labels.float())

optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.1)

报错信息:

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[37], line 11
      8 output = Variable(torch.randn(10, 120).float())
      9 labels = Variable(torch.FloatTensor(10).uniform_(0, 120).long())
---> 11 loss = criterion(output, labels.float())
     13 optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.1)

File ~\anaconda3\envs\withGPU\lib\site-packages\torch\nn\modules\module.py:1518, in Module._wrapped_call_impl(self, *args, **kwargs)
   1516     return self._compiled_call_impl(*args, **kwargs)  # type: ignore[misc]
   1517 else:
-> 1518     return self._call_impl(*args, **kwargs)

File ~\anaconda3\envs\withGPU\lib\site-packages\torch\nn\modules\module.py:1527, in Module._call_impl(self, *args, **kwargs)
   1522 # If we don't have any hooks, we want to skip the rest of the logic in
   1523 # this function, and just call forward.
   1524 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks
   1525         or _global_backward_pre_hooks or _global_backward_hooks
   1526         or _global_forward_hooks or _global_forward_pre_hooks):
-> 1527     return forward_call(*args, **kwargs)
   1529 try:
   1530     result = None

File ~\anaconda3\envs\withGPU\lib\site-packages\torch\nn\modules\loss.py:1179, in CrossEntropyLoss.forward(self, input, target)
   1178 def forward(self, input: Tensor, target: Tensor) -> Tensor:
-> 1179     return F.cross_entropy(input, target, weight=self.weight,
   1180                            ignore_index=self.ignore_index, reduction=self.reduction,
   1181                            label_smoothing=self.label_smoothing)

File ~\anaconda3\envs\withGPU\lib\site-packages\torch\nn\functional.py:3053, in cross_entropy(input, target, weight, size_average, ignore_index, reduce, reduction, label_smoothing)
   3051 if size_average is not None or reduce is not None:
   3052     reduction = _Reduction.legacy_get_string(size_average, reduce)
-> 3053 return torch._C._nn.cross_entropy_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index, label_smoothing)

RuntimeError: expected scalar type Long but found Float

我的UNet训练代码

模型初始化

model.to(device)

# Specify the loss function and optimizer
#criterion = torch.nn.CrossEntropyLoss()

criterion = nn.CrossEntropyLoss()

output = Variable(torch.randn(10, 120).float())
labels = Variable(torch.FloatTensor(10).uniform_(0, 120).long())

loss = criterion(output, labels.float())

optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.1)

训练与验证函数

def train_one_epoch(model, optimizer, data_loader, device):

    model.train()

    # Zero the performance stats for each epoch (set initial condition - clear)
    running_loss = 0.0
    start_time = time.time()
    total = 0
    correct = 0
    

    
    for i, (inputs, labels) in enumerate(dataloaders['train']):
        inputs = inputs.to(device)
        print(inputs.shape)
        labels = labels.to(device).float()
        #labels = labels.reshape(-1).to(device)
        print(labels) # output: tensor([number of outputs depends on batch size], device='cuda:0')
        
        optimizer.zero_grad()
        #outputs = model(inputs.float())
        
        outputs = F.softmax(model(inputs.float()), dim=1)

        
        # Assuming labels are originally loaded as torch.Tensor
        # Convert labels to long type
        #labels = labels.long()

        
        # Flatten the labels if needed
        #labels = labels.reshape(-1)
        
        # Print shapes
        print("Inputs shape:", inputs.shape)
        print("Outputs shape:", outputs.shape)
        print("Labels shape:", labels.shape)
        
        
        loss = criterion(labels, torch.argmax(outputs, dim=1))
        loss.backward()
        optimizer.step()
        
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
        accuracy = 100 * correct / total
    
        # Print performance statistics
        running_loss += loss.item()
        if i % 10 == 0:    # print every 10 batches
            batch_time = time.time()
            speed = (i+1)/(batch_time-start_time)
            print('[%5d] loss: %.3f, speed: %.2f, accuracy: %.2f %%' %
                  (i, running_loss, speed, accuracy))

            running_loss = 0.0
            total = 0
            correct = 0

    
def val_model(model, data_loader):

    model.val()

    start_time = time.time()
    total = 0
    correct = 0
      
    with torch.no_grad():
        for i, (inputs, labels) in enumerate(dataloaders['val']):
            inputs = inputs.to(device)
            labels = labels.to(device).long()
            inputs = inputs.to(device)
            labels = labels.to(device).long()

            # zero the parameter gradients
            #optimizer.zero_grad()

            # forward + backward + optimize
            outputs = model(inputs.float())

            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum(dim=1).item()
        accuracy = 100 * correct / total
            
        print('Finished Testing')
        print('Testing accuracy: %.1f %%' %(accuracy))

训练循环

num_epochs = 3
for epoch in range(num_epochs): 
    print("------------------ Training Epoch {} ------------------".format(epoch+1))
    
    train_one_epoch(model, optimizer,'train' , device)

    val_model(model, 'val')

print('Finished Training')      

问题解答

错误原因解释

RuntimeError: expected scalar type Long but found Float 是因为PyTorch的CrossEntropyLoss要求目标标签必须是LongTensor类型(整数张量,代表类别索引,比如0、1、2...)。你在测试代码里把已经转成long的labels又用.float()转成了浮点型,违反了Loss的输入要求,直接触发报错。

训练代码核心修正点

  1. 标签类型修正
    训练函数中不要把标签转成float,必须转为long类型:

    labels = labels.to(device).long()  # 替换原labels.to(device).float()
    
  2. Loss输入逻辑修正

    • CrossEntropyLoss内部会自动计算softmax,不需要提前对模型输出做F.softmax,否则会导致数值不稳定:
      outputs = model(inputs.float())  # 直接使用模型输出的logits
      
    • Loss的调用顺序必须是criterion(模型输出, 标签),你之前写反了输入顺序,而且用torch.argmax处理输出的操作完全错误:
      loss = criterion(outputs, labels)  # 正确输入顺序
      
  3. 验证函数错误修正

    • model.val()是错误写法,应该用model.eval()切换到评估模式;
    • 统计正确样本数时,(predicted == labels).sum(dim=1).item()会导致维度错误,直接用.sum().item()即可:
      correct += (predicted == labels).sum().item()
      

修正后的关键代码片段

训练函数Loss计算部分

optimizer.zero_grad()
outputs = model(inputs.float())  # 直接用模型输出的logits
labels = labels.to(device).long()

loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total

验证函数修正版

def val_model(model, data_loader):
    model.eval()  # 修正为eval()模式

    start_time = time.time()
    total = 0
    correct = 0
      
    with torch.no_grad():
        for i, (inputs, labels) in enumerate(dataloaders['val']):
            inputs = inputs.to(device)
            labels = labels.to(device).long()

            outputs = model(inputs.float())

            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
        accuracy = 100 * correct / total
            
        print('Finished Validation')
        print('Validation accuracy: %.1f %%' %(accuracy))

内容的提问来源于stack exchange,提问作者Waltty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:30:54