RuntimeError: el tipo de entrada (torch.FloatTensor) y el tipo de peso (torch.cuda.FloatTensor) deben ser los mismos

9

Estoy tratando de entrenar la siguiente CNN de la siguiente manera, pero sigo recibiendo el mismo error con respecto a .cuda () y no estoy seguro de cómo solucionarlo. Aquí hay una porción de mi código hasta ahora.

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

Sin embargo, sigo recibiendo este error en la consola:

RuntimeError: el tipo de entrada (torch.FloatTensor) y el tipo de peso (torch.cuda.FloatTensor) deben ser los mismos`

¿Alguna idea sobre cómo solucionarlo? Leí que tal vez el modelo no haya sido introducido en mi GPU, pero no estoy seguro de cómo solucionarlo. ¡Gracias!

Liz
fuente

Respuestas:

11

Obtiene este error porque su modelo está en la GPU pero sus datos están en la CPU. Por lo tanto, debe enviar sus tensores de entrada a CUDA.

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

O así, para mantenerse consistente con el resto de su código:

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

El mismo error de mensaje aparecerá si sus datos están en CUDA, pero su modelo no lo es. En este caso, debe enviar su modelo a CUDA.

model = MyModel()

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