RuntimeError: Jenis input (torch.FloatTensor) dan jenis berat (torch.cuda.FloatTensor) harus sama

9

Saya mencoba untuk melatih CNN berikut sebagai berikut, tetapi saya terus mendapatkan kesalahan yang sama mengenai .cuda () dan saya tidak yakin bagaimana cara memperbaikinya. Berikut adalah sebagian dari kode saya sejauh ini.

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')

Namun, saya terus mendapatkan kesalahan ini di konsol:

RuntimeError: Jenis input (torch.FloatTensor) dan jenis berat (torch.cuda.FloatTensor) harus sama`

Adakah pemikiran tentang cara memperbaikinya? Saya membaca bahwa mungkin modelnya belum dimasukkan ke GPU saya, tetapi tidak yakin bagaimana cara memperbaikinya. Terima kasih!

Liz
sumber

Jawaban:

11

Anda mendapatkan kesalahan ini karena model Anda ada di GPU tetapi data Anda ada di CPU. Jadi, Anda perlu mengirim tensor input Anda ke CUDA.

inputs, labels = data
inputs, labels = inputs.cuda(), labels.cuda() # add this line

Atau seperti ini, untuk tetap konsisten dengan kode Anda yang lain:

inputs, labels = inputs.to(device), labels.to(device)

The kesalahan yang sama pesan akan muncul jika data Anda pada CUDA, tapi model Anda tidak. Dalam hal ini, Anda perlu mengirim model Anda ke CUDA.

model = MyModel()

if torch.cuda.is_available():
    model.cuda()
Nicolas Gervais
sumber