Ошибка выполнения при чтении данных из обучающего набора данных PyTorch - PullRequest
0 голосов
/ 28 февраля 2020

В моем наборе обучающих данных есть образец данных, который я могу просмотреть, если распечатываю данные, но при доступе к нему для обучения данных я продолжаю получать RuntimeError: Expected object of scalar type Double but got scalar type Float for argument #2 'weight' in call to _thnn_conv2d_forward. Я не могу понять, почему это происходит. В конце я также приложил изображение, чтобы лучше понять сообщение об ошибке.

Файл tags.txt выглядит следующим образом (имя изображения, связанного с другой папкой с соответствующими изображениями, центральные точки (x, у) и радиус)

0000,   0.67 ,   0.69 ,   0.26 
0001,   0.69 ,   0.33 ,   0.3  
0002,   0.16 ,   0.27 ,   0.15 
0003,   0.54 ,   0.33 ,   0.17 
0004,   0.32 ,   0.45 ,   0.3  
0005,   0.78 ,   0.26 ,   0.17 
0006,   0.44 ,   0.49 ,   0.19 

РЕДАКТИРОВАТЬ: Это функция потерь и оптимизатор, который я использую оптимизатор =

optim.Adam(model.parameters(), lr=0.001)
nn.CrossEntropyLoss()

Моя функция проверки модели выглядит следующим образом:

def validate_model(model, loader):
    model.eval() # eval mode (batchnorm uses moving mean/variance instead of mini-batch mean/variance)
                  # (dropout is set to zero)

    val_running_loss = 0.0
    val_running_correct = 0

    for int, data in enumerate(loader):
        data, target = data['image'].to(device), data['labels'].to(device)
        output = model(data)
        loss = my_loss(output, target)

        val_running_loss = val_running_loss + loss.item()
        _, preds = torch.max(output.data, 1)

        val_running_correct = val_running_correct+ (preds == target).sum().item()

    avg_loss = val_running_loss/len(loader.dataset)
    val_accuracy = 100. * val_running_correct/len(loader.dataset)

    #----------------------------------------------
    # implementation needed here 
    #----------------------------------------------
    return avg_loss, val_accuracy

У меня есть функция подгонки для определения тренировочных потерь:

def fit(model, train_dataloader):
    model.train()
    train_running_loss = 0.0
    train_running_correct = 0
    for i, data in enumerate(train_dataloader):
        print(data)
        #I believe this is causing the error, but not sure why.
        data, target = data['image'].to(device), data['labels'].to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = my_loss(output, target)
        train_running_loss = train_running_loss + loss.item()
        _, preds = torch.max(output.data, 1)
        train_running_correct =  train_running_correct + (preds == target).sum().item()
        loss.backward()
        optimizer.step()
    train_loss = train_running_loss/len(train_dataloader.dataset)
    train_accuracy = 100. * train_running_correct/len(train_dataloader.dataset)

    print(f'Train Loss: {train_loss:.4f}, Train Acc: {train_accuracy:.2f}')

    return train_loss, train_accuracy

и следующая функция train_model, которая сохраняет потери и точность в списке:

train_losses , train_accuracy = [], []
validation_losses , val_accuracy = [], []

def train_model(model,
                optimizer,
                train_loader,
                validation_loader,
                train_losses,
                validation_losses,
                epochs=1):

    """
    Trains a neural network. 
    Args:
        model               - model to be trained
        optimizer           - optimizer used for training
        train_loader        - loader from which data for training comes 
        validation_loader   - loader from which data for validation comes (maybe at the end, you use test_loader)
        train_losses        - adding train loss value to this list for future analysis
        validation_losses   - adding validation loss value to this list for future analysis
        epochs              - number of runs over the entire data set 
    """

    #----------------------------------------------
    # implementation needed here 
    #----------------------------------------------

    for epoch in range(epochs):
        train_epoch_loss, train_epoch_accuracy = fit(model, train_loader)
        val_epoch_loss, val_epoch_accuracy = validate_model(model, validation_loader)
        train_losses.append(train_epoch_loss)
        train_accuracy.append(train_epoch_accuracy)
        validation_losses.append(val_epoch_loss)
        val_accuracy.append(val_epoch_accuracy)

    return

И когда Я запускаю следующий код, я получаю сообщение об ошибке выполнения:

train_model(model, 
            optimizer,
            train_loader, 
            validation_loader, 
            train_losses, 
            validation_losses,
            epochs=2)

ОШИБКА: RuntimeError: Ожидаемый объект скалярного типа Double, но получил скалярный тип Float для аргумента # 2 'weight' при вызове _thnn_conv2d_forward

Вот снимок экрана с сообщением об ошибке: ОШИБКА

РЕДАКТИРОВАТЬ: так выглядит моя модель, я должен обнаруживать круги в емк e с указанными центрами и радиусом в файле label.txt и закрасьте их - была дана функция рисования, я должен был создать модель, пройти обучение и проверку. моя пользовательская функция потерь:

criterion = nn.CrossEntropyLoss()

def my_loss(outputs, labels):

    """
    Args:
        outputs - output of network ([batch size, 3]) 
        labels  - desired labels  ([batch size, 3])
    """

    loss = torch.zeros(1, dtype=torch.float, requires_grad=True)
    loss = loss.to(device)

    loss = criterion(outputs, labels)

    #----------------------------------------------
    # implementation needed here 
    #----------------------------------------------

    # Observe: If you need to iterate and add certain values to loss defined above
    # you cannot write: loss +=... because this will raise the error: 
    # "Leaf variable was used in an inplace operation"
    # Instead, to avoid this error write: loss = loss + ...       

    return loss

Train Loader (данный мне):

train_dir      = "./train/"
validation_dir = "./validation/"
test_dir       = "./test/"


train_dataset = ShapesDataset(train_dir)

train_loader = DataLoader(train_dataset, 
                          batch_size=32,
                          shuffle=True)



validation_dataset = ShapesDataset(validation_dir)

validation_loader = DataLoader(validation_dataset, 
                               batch_size=1,
                               shuffle=False)



test_dataset = ShapesDataset(test_dir)

test_loader = DataLoader(test_dataset, 
                          batch_size=1,
                          shuffle=False)


print("train loader examples     :", len(train_dataset)) 
print("validation loader examples:", len(validation_dataset))
print("test loader examples      :", len(test_dataset))

EDIT: Это изображение вида, метки целевого круга и сетевой вывод также были заданы:

"""
View first image of a given number of batches assuming that model has been created. 
Currently, lines assuming model has been creatd, are commented out. Without a model, 
you can view target labels and the corresponding images.
This is given to you so that you may see how loaders and model can be used. 
"""

loader = train_loader # choose from which loader to show images
bacthes_to_show = 2
with torch.no_grad():
    for i, data in enumerate(loader, 0): #0 means that counting starts at zero
        inputs = (data['image']).to(device)   # has shape (batch_size, 3, 128, 128)
        labels = (data['labels']).to(device)  # has shape (batch_size, 3)
        img_fnames = data['fname']            # list of length batch_size

        #outputs = model(inputs.float())
        img = Image.open(img_fnames[0])

        print ("showing image: ", img_fnames[0])

        labels_str = [ float(("{0:.2f}".format(x))) for x in labels[0]]#labels_np_arr]

        #outputs_np_arr = outputs[0] # using ".numpy()" to convert tensor to numpy array
        #outputs_str = [ float(("{0:.2f}".format(x))) for x in outputs_np_arr]
        print("Target labels :", labels_str )
        #print("network coeffs:", outputs_str)
        print()
        #img.show()

        if (i+1) == bacthes_to_show:
            break

Вот вывод, который я получаю, он должен охватывать полный круг: Вывод, который я получаю Любая идея будет полезна.

1 Ответ

0 голосов
/ 28 февраля 2020

Я в основном добавил (в функции validate_model и fit) это:

 _, target= torch.max(target.data, 1)

ниже строки кода _, preds = torch.max(output.data, 1), чтобы получить данные и цель одинаковой длины. Также изменена функция потерь с CrossEntropyLoss на MSELoss

Затем в тех же функциях: я изменил следующую строку output = model(data) на output = model(data.float())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...