【问题标题】:RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the sameRuntimeError:输入类型(torch.FloatTensor)和权重类型(torch.cuda.FloatTensor)应该相同
【发布时间】:2023-03-27 18:52:01
【问题描述】:

我正在尝试按如下方式训练以下 CNN,但我不断收到关于 .cuda() 的相同错误,我不知道如何修复它。到目前为止,这是我的一部分代码。

import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn
from torch import optim
import torch.nn.functional as F
import torchvision
from torchvision import datasets, transforms, models
from torch.utils.data.sampler import SubsetRandomSampler


data_dir = "/home/ubuntu/ML2/ExamII/train2/"
valid_size = .2

# Normalize the test and train sets with torchvision
train_transforms = transforms.Compose([transforms.Resize(224),
                                           transforms.ToTensor(),
                                           ])

test_transforms = transforms.Compose([transforms.Resize(224),
                                          transforms.ToTensor(),
                                          ])

# ImageFolder class to load the train and test images
train_data = datasets.ImageFolder(data_dir, transform=train_transforms)
test_data = datasets.ImageFolder(data_dir, transform=test_transforms)


# Number of train images
num_train = len(train_data)
indices = list(range(num_train))
# Split = 20% of train images
split = int(np.floor(valid_size * num_train))
# Shuffle indices of train images
np.random.shuffle(indices)
# Subset indices for test and train
train_idx, test_idx = indices[split:], indices[:split]
# Samples elements randomly from a given list of indices
train_sampler = SubsetRandomSampler(train_idx)
test_sampler = SubsetRandomSampler(test_idx)
# Batch and load the images
trainloader = torch.utils.data.DataLoader(train_data, sampler=train_sampler, batch_size=1)
testloader = torch.utils.data.DataLoader(test_data, sampler=test_sampler, batch_size=1)


#print(trainloader.dataset.classes)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = models.resnet50(pretrained=True)

model.fc = nn.Sequential(nn.Linear(2048, 512),
                                 nn.ReLU(),
                                 nn.Dropout(0.2),
                                 nn.Linear(512, 10),
                                 nn.LogSigmoid())
                                 # nn.LogSoftmax(dim=1))
# criterion = nn.NLLLoss()
criterion = nn.BCELoss()
optimizer = optim.Adam(model.fc.parameters(), lr=0.003)
model.to(device)

#Train the network
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

但是,我在控制台中不断收到此错误:

RuntimeError:输入类型(torch.FloatTensor)和权重类型(torch.cuda.FloatTensor)应该相同`

关于如何解决它的任何想法?我读到该模型可能尚未推送到我的 GPU 中,但不知道如何修复它。谢谢!

【问题讨论】:

    标签: python python-3.x machine-learning deep-learning pytorch


    【解决方案1】:

    您收到此错误是因为您的模型在 GPU 上,但您的数据在 CPU 上。因此,您需要将输入张量发送到 GPU。

    inputs, labels = data                         # this is what you had
    inputs, labels = inputs.cuda(), labels.cuda() # add this line
    

    或者像这样,与你的其余代码保持一致:

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    
    inputs, labels = inputs.to(device), labels.to(device)
    

    如果您的输入张量在 GPU 上但您的模型权重不在,则会引发相同的错误。在这种情况下,您需要将模型权重发送到 GPU。

    model = MyModel()
    
    if torch.cuda.is_available():
        model.cuda()
    

    这是cuda()cpu() 的文档,正好相反。

    【讨论】:

      【解决方案2】:

      新的API是使用.to()方法。

      优势很明显也很重要。 您的设备明天可能不是“cuda”:

      • CPU
      • cuda
      • mkldnn
      • opengl
      • opencl
      • 很深
      • 臀部
      • msnpu
      • xla

      所以尽量避免model.cuda() 检查设备没有错

      dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
      

      或者硬编码:

      dev=torch.device("cuda") 
      

      同:

      dev="cuda"
      

      一般你可以使用这个代码:

      model.to(dev)
      data = data.to(dev)
      

      【讨论】:

      • 即使在使用 to(device) 将模型和数据移动到 gpu 之后,我也会收到错误 RuntimeError: Input, output and indices must be on the current device
      【解决方案3】:

      正如前面的答案中已经提到的,问题可能是您的模型是在 GPU 上训练的,但它是在 CPU 上测试的。如果是这种情况,那么您需要将模型的权重和数据从 GPU 移植到 CPU,如下所示:

      device = args.device # "cuda" / "cpu"
      if "cuda" in device and not torch.cuda.is_available():
          device = "cpu"
      data = data.to(device)
      model.to(device)
      

      注意:这里我们仍然检查配置参数是否设置为 GPU 或 CPU,以便这段代码可用于训练(在 GPU 上)和测试(在 CPU 上)。

      【讨论】:

        【解决方案4】:
           * when you get this error::RuntimeError: Input type 
           (torch.FloatTensor) and weight type (torch.cuda.FloatTensor should 
           be the same
           # Move tensors to GPU is CUDA is available
           # Check if CUDA is available
        
          train_on_gpu = torch.cuda.is_available()
        
          If train_on_gpu:
              print("CUDA is available! Training on GPU...")
          else:
              print("CUDA is not available. Training on CPU...")
        
         -------------------
         # Move tensors to GPU is CUDA is available
        if train_on_gpu:
        
        model.cuda()
        

        【讨论】:

          【解决方案5】:

          首先检查cuda是否可用:

            if torch.cuda.is_available():
                device = 'cuda'
            else:
                device = 'cpu'
          

          如果您想加载某些模型,请执行以下操作:

            checkpoint = torch.load('./generator_release.pth', map_location=device)
            G = Generator().to(device)
          

          现在你可能会得到这个错误:

          RuntimeError:输入类型(torch.FloatTensor)和权重类型(torch.cuda.FloatTensor)应该相同

          需要通过以下方式将输入数据的类型从torch.tensor转换为torch.cuda.tensor:

          if torch.cuda.is_available():
            data = data.cuda()
          result = G(data)
          

          然后将结果从 torch.cuda.tensor 转换为 torch.tensor:

          if torch.cuda.is_available():
              result = result.cpu()
          

          【讨论】:

            猜你喜欢
            • 2021-07-19
            • 1970-01-01
            • 2020-09-29
            • 2021-01-03
            • 2022-11-11
            • 2021-12-30
            • 2021-12-06
            • 2021-07-18
            • 2023-04-10
            相关资源
            最近更新 更多