简体   繁体   中英

"RuntimeError: expected scalar type Long but found Float" in the forward process

I'm trying to create a model with PyTorch but during the forward, I encounter this issue "RuntimeError: expected scalar type Long but found Float".

Source code:

  • dataset_loader.py:
import h5py
import torch
import numpy as np

from PIL import Image
from os import listdir
from sklearn.utils import shuffle

WIDTH = 64
HEIGHT = 64
CREATE_DATASET = False


def load_set(path: str):
    dataset = []
    for f in listdir(path):
        dataset.append(np.asarray(Image.open(path + f).resize((WIDTH, HEIGHT)).convert('RGB'), dtype=np.int32).reshape(3, WIDTH, HEIGHT))

    return np.array(dataset, dtype=np.int32)


def create_batch(dataset, labels, batch_size):
    dataset_result = []
    labels_result = []
    data_batch = []
    label_batch = []

    for index in range(len(dataset)):
        if len(data_batch) == batch_size:
            # dataset_result.append(np.array(data_batch, dtype=np.int32))
            # labels_result.append(np.array(label_batch, dtype=np.int32))
            dataset_result.append(data_batch)
            labels_result.append(label_batch)
            data_batch = []
            label_batch = []
        else:
            # data_batch.append(torch.tensor(dataset[index]))
            # label_batch.append(torch.tensor(labels[index]))
            data_batch.append(np.array(dataset[index], dtype=np.int32))
            label_batch.append(np.array(labels[index], dtype=np.int32))

    dataset_result = np.array(dataset_result, dtype=np.int32)
    labels_result = np.array(labels_result, dtype=np.int32)
    return torch.from_numpy(dataset_result), torch.from_numpy(labels_result)
    # return dataset_result, labels_result


def create_dataset():
    dataset_file = h5py.File("dataset.hdf5", "w")

    train_normal = load_set("chest_xray/train/NORMAL/")
    dataset_file.create_dataset("train_normal", train_normal.shape, dtype=np.int32, data=train_normal)

    train_pneumonia = load_set("chest_xray/train/PNEUMONIA/")
    dataset_file.create_dataset("train_pneumonia", train_pneumonia.shape, dtype=np.int32, data=train_pneumonia)

    test_normal = load_set("chest_xray/test/NORMAL/")
    dataset_file.create_dataset("test_normal", test_normal.shape, dtype=np.int32, data=test_normal)

    test_pneumonia = load_set("chest_xray/test/PNEUMONIA/")
    dataset_file.create_dataset("test_pneumonia", test_pneumonia.shape, dtype=np.int32, data=test_pneumonia)

    val_normal = load_set("chest_xray/val/NORMAL/")
    dataset_file.create_dataset("val_normal", val_normal.shape, dtype=np.int32, data=val_normal)

    val_pneumonia = load_set("chest_xray/val/PNEUMONIA/")
    dataset_file.create_dataset("val_pneumonia", val_pneumonia.shape, dtype=np.int32, data=val_pneumonia)


def load_dataset():
    dataset = h5py.File('dataset.hdf5', 'r')

    train_set = np.array(list(dataset["train_normal"]) + list(dataset["train_pneumonia"]), dtype=np.int32)
    test_set = np.array(list(dataset["test_normal"]) + list(dataset["test_pneumonia"]), dtype=np.int32)
    val_set = np.array(list(dataset["val_normal"]) + list(dataset["val_pneumonia"]), dtype=np.int32)

    train_labels = [0] * len(dataset["train_normal"]) + [1] * len(dataset["train_pneumonia"])
    test_labels = [0] * len(dataset["test_normal"]) + [1] * len(dataset["test_pneumonia"])
    val_labels = [0] * len(dataset["val_normal"]) + [1] * len(dataset["val_pneumonia"])

    BATCH_SIZE = 32

    train_set, train_labels = shuffle(np.array(train_set, dtype=np.int32), np.array(train_labels, dtype=np.int32))
    train_set, train_labels = create_batch(train_set, train_labels, BATCH_SIZE)

    test_set, test_labels = shuffle(np.array(test_set, dtype=np.int32), np.array(test_labels, dtype=np.int32))
    test_set, test_labels = create_batch(test_set, test_labels, BATCH_SIZE)

    val_set, val_labels = shuffle(np.array(val_set, dtype=np.int32), np.array(val_labels, dtype=np.int32))
    val_set, val_labels = create_batch(val_set, val_labels, BATCH_SIZE)

    return train_set, train_labels, test_set, test_labels, val_set, val_labels, BATCH_SIZE
  • network.py:
import torch.nn as nn
import torch.nn.functional as F

class Network(nn.Module):
  def __init__(self):
    super().__init__()
    self.conv1 = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5)
    self.conv2 = nn.Conv2d(in_channels=6, out_channels=12, kernel_size=5)

    self.fc1 = nn.Linear(in_features=12*5*5, out_features=120)
    self.fc2 = nn.Linear(in_features=120, out_features=60)
    self.out = nn.Linear(in_features=60, out_features=2)

  def forward(self, t):
    t = self.conv1(t)
    t = F.relu()
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    t = F.relu(self.conv2(t))
    t = F.max_pool2d(t, kernel_size=2, stride=2)

    t = t.reshape(-1, 12 * 4 * 4)
    t = F.relu(self.fc1(t))
    t = F.relu(self.fc2(t))
    t = self.out(t)

    return t
  • main.py:
import numpy as np
import torch
import torch.optim as optim
import torch.nn.functional as F

import network
import dataset_loader

import matplotlib.pyplot as plt

device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

WIDTH = 64
HEIGHT = 64
NEED_TO_CREATE_DATASET = False

if NEED_TO_CREATE_DATASET:
    dataset_loader.create_dataset()

train_set, train_labels, test_set, test_labels, val_set, val_labels, BATCH_SIZE = dataset_loader.load_dataset()

TRAINING_SIZE = len(train_set) * BATCH_SIZE
TESTING_SIZE = len(test_set) * BATCH_SIZE

EPOCHS = 5
LEARNING_RATE = 0.01

network = network.Network().to(device)
optimizer = optim.Adam(network.parameters(), lr=LEARNING_RATE)

training_losses = []
training_accuracies = []

testing_losses = []
testing_accuracies = []

def get_num_correct(preds, labels):
    return preds.argmax(dim=1).eq(labels).sum().item()

def train():
    network.train()
    correct_in_episode = 0
    episode_loss = 0

    for index, images in enumerate(train_set):
        labels = train_labels[index]

        print(images.shape)
        # exit()
        predictions = network(images.type(torch.LongTensor)) # TODO: fix crash "RuntimeError: expected scalar type Long but found Float"
        # predictions = network(images)
        loss = F.cross_entropy(predictions, labels)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        episode_loss += loss.item()
        correct_in_episode += get_num_correct(predictions, labels)

    training_losses.append(episode_loss)
    training_accuracies.append(correct_in_episode * 100 / TRAINING_SIZE)
    print(f"Epoch: {epoch + 1} accuracy: {correct_in_episode * 100 / TRAINING_SIZE:.2f} loss: {episode_loss:.3f}", end="\t")


def test():
    network.eval()
    episode_loss = 0
    correct_in_episode = 0

    with torch.no_grad():
        for index, images in enumerate(test_set):
            labels = test_labels[index]

            predictions = network(images)
            loss = F.cross_entropy(predictions, labels)

            episode_loss = loss.item()
            correct_in_episode += get_num_correct(predictions, labels)

    testing_losses.append(episode_loss)
    testing_accuracies.append(correct_in_episode * 100 / TESTING_SIZE)
    print(f'Validation: Accuracy: {correct_in_episode * 100 / TESTING_SIZE:.2f} loss: {episode_loss:.3f}')

for epoch in range(EPOCHS):
    train()
    test()

fig = plt.figure()

plt.plot(list(range(1, len(training_losses)+1)), training_losses, color='blue')
plt.plot(list(range(1, len(testing_losses)+1)), testing_losses, color='red')

plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('Loss')

fig = plt.figure()

plt.plot(list(range(1, len(training_accuracies)+1)), training_accuracies, color='blue')
plt.plot(list(range(1, len(testing_accuracies)+1)), testing_accuracies, color='red')

plt.legend(['Train Accuracy', 'Test Accuracy'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('Accuracy')

Error:

torch.Size([32, 3, 64, 64])
Traceback (most recent call last):
  File "Soluce.py", line 86, in <module>
    train()
  File "Soluce.py", line 50, in train
    predictions = network(images.type(torch.LongTensor)) # TODO: fix crash "RuntimeError: expected scalar type Long but found Float"
  File "/home/thytu/.local/lib/python3.8/site-packages/torch/nn/modules/module.py", line 727, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/home/thytu/Prog/PoC/pool_2021/Day3/Admin-XRAI/Admin/network.py", line 15, in forward
    t = self.conv1(t)
  File "/home/thytu/.local/lib/python3.8/site-packages/torch/nn/modules/module.py", line 727, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/home/thytu/.local/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 423, in forward
    return self._conv_forward(input, self.weight)
  File "/home/thytu/.local/lib/python3.8/site-packages/torch/nn/modules/conv.py", line 419, in _conv_forward
    return F.conv2d(input, weight, self.bias, self.stride,
RuntimeError: expected scalar type Long but found Float

Do you have any ideas chat the issue is?
Thanks for your time and your help.

(PS: It's not about Cross-Entropy, it happens before)

I also encountered the same problem. My code is as follows:

  • my code:

     import torch from torchvision.models import alexnet model = alexnet(pretrained=True) input_data = torch.randint(255, size=(1, 3, 224, 224), dtype=torch.long) outputs = model(input_data) print(outputs)

very simple operation, but it's error:

Traceback (most recent call last):
  File "D:\Program Files\JetBrains\PyCharm 2021.1.3\plugins\python\helpers\pydev\pydevd.py", line 1483, in _exec
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "D:\Program Files\JetBrains\PyCharm 2021.1.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "F:/Python/TF2/main.py", line 9, in <module>
    outputs = model(input_data)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torchvision\models\alexnet.py", line 46, in forward
    x = self.features(x)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\container.py", line 139, in forward
    input = module(input)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\module.py", line 1051, in _call_impl
    return forward_call(*input, **kwargs)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\conv.py", line 443, in forward
    return self._conv_forward(input, self.weight, self.bias)
  File "D:\Anaconda\envs\tf2x\lib\site-packages\torch\nn\modules\conv.py", line 440, in _conv_forward
    self.padding, self.dilation, self.groups)
RuntimeError: expected scalar type Long but found Float

and but I think it's the weight problem, but I immediately changed this idea. Because it's only an official model, the problem is located in input data. So I changed the code again:

  • Changed code:

     input_data = torch.rand(size=(1, 3, 224, 224)) outputs = model(input_data) print(outputs)

and then, it's ok:

tensor([[-1.5024e+00, -1.1394e+00, -3.7661e-01,  1.1497e+00,  1.1878e-01,
     -6.6696e-01,  3.8399e-01, -1.0095e+00, -1.3813e+00, -1.4772e+00,
     ...
Process finished with exit code 0

Therefore, my suggestion is that you can try to change the type of input data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM