RuntimeError: Typ danych wejściowych (torch.FloatTensor) i typ masy (torch.cuda.FloatTensor) powinny być takie same

9

Próbuję wyszkolić następujący CNN w następujący sposób, ale wciąż pojawia się ten sam błąd dotyczący .cuda () i nie jestem pewien, jak to naprawić. Oto fragment mojego kodu do tej pory.

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

Jednak ciągle pojawia się ten błąd w konsoli:

RuntimeError: Typ wejścia (torch.FloatTensor) i typ wagi (torch.cuda.FloatTensor) powinny być takie same`

Wszelkie przemyślenia, jak to naprawić? Przeczytałem, że może model nie został wepchnięty do mojego GPU, ale nie jestem pewien, jak to naprawić. Dzięki!

Liz
źródło

Odpowiedzi:

11

Ten błąd pojawia się, ponieważ Twój model jest oparty na procesorze graficznym, ale dane są na procesorze. Musisz więc wysłać tensory wejściowe do CUDA.

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

Lub w ten sposób, aby zachować zgodność z resztą kodu:

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

Ten sam komunikat o błędzie pojawi się, jeśli Twoje dane znajdują się w CUDA, ale Twój model nie. W takim przypadku musisz wysłać swój model do CUDA.

model = MyModel()

if torch.cuda.is_available():
    model.cuda()
Nicolas Gervais
źródło