RuntimeError: le type d'entrée (torch.FloatTensor) et le type de poids (torch.cuda.FloatTensor) doivent être identiques

9

J'essaie de former le CNN suivant comme suit, mais je reçois toujours la même erreur concernant .cuda () et je ne sais pas comment le corriger. Voici un morceau de mon code jusqu'à présent.

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

Cependant, je continue à obtenir cette erreur dans la console:

RuntimeError: le type d'entrée (torch.FloatTensor) et le type de poids (torch.cuda.FloatTensor) doivent être identiques. »

Des réflexions sur la façon de le réparer? J'ai lu que le modèle n'avait peut-être pas été inséré dans mon GPU, mais je ne sais pas comment le corriger. Merci!

Liz
la source

Réponses:

11

Vous obtenez cette erreur car votre modèle est sur le GPU mais vos données sont sur le CPU. Vous devez donc envoyer vos tenseurs d'entrée à CUDA.

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

Ou comme ça, pour rester cohérent avec le reste de votre code:

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

Le même message d' erreur apparaîtra si vos données sont sur CUDA, mais pas votre modèle. Dans ce cas, vous devez envoyer votre modèle à CUDA.

model = MyModel()

if torch.cuda.is_available():
    model.cuda()
Nicolas Gervais
la source