web-dev-qa-db-fra.com

Pytorch: comment convertir des données en tenseur

Je suis débutant pour Pytorch. J'essayais d'écrire du code CNN faisant référence au tutoriel Pytorch. Ci-dessous est une partie du code, mais il affiche l'erreur "RuntimeError: les données variables doivent être un tenseur, mais la liste est". J'ai essayé de lancer des données d'entrée sur le tenseur, mais cela n'a pas bien fonctionné. Si quelqu'un connaît la solution, aidez-moi s'il vous plaît ...

    def read_labels(file):
      dic = {}
      with open(file) as f:
        reader = f
        for row in reader:
            dic[row.split(",")[0]]  = row.split(",")[1].rstrip() #rstrip(): eliminate "\n"
      return dic

    image_names= os.listdir("./train_mini")
    label_dic = read_labels("labels.csv")


    names =[]
    labels = []
    images =[]

    for name in image_names[1:]:
        images.append(cv2.imread("./train_mini/"+name))
        labels.append(label_dic[os.path.splitext(name)[0]])

    """
    Data distribution
    """
    N = len(images)
    N_train = int(N * 0.7)
    N_test = int(N*0.2)

    X_train, X_tmp, Y_train, Y_tmp = train_test_split(images, labels, train_size=N_train)
    X_validation, X_test, Y_validation, Y_test = train_test_split(X_tmp, Y_tmp, test_size=N_test)

    """
    Model Definition
    """

    class CNN(nn.Module):
        def __init__(self):
            super(CNN, self).__init__()
            self.head = nn.Sequential(
                nn.Conv2d(in_channels=1, out_channels=10,
                          kernel_size=5, stride=1),
                nn.MaxPool2d(kernel_size=2),
                nn.ReLU(),
                nn.Conv2d(10, 20, kernel_size=5),
                nn.MaxPool2d(kernel_size=2),
                nn.ReLU())
            self.tail = nn.Sequential(
                nn.Linear(320, 50),
                nn.ReLU(),
                nn.Linear(50, 10))

        def forward(self, x):
            x = self.head(x)
            x = x.view(-1, 320)
            x = self.tail(x)
            return F.log_softmax(x)

    CNN = CNN()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(CNN.parameters(), lr=0.001, momentum=0.9)


    """
    Training
    """
    batch_size = 50
    for Epoch in range(2):  # loop over the dataset multiple times
        running_loss = 0.0
        for i in range(N / batch_size):
        #for i, data in enumerate(trainloader, 0):
            batch = batch_size * i

            # get the inputs
            images_batch = X_train[batch:batch + batch_size]
            labels_batch = Y_train[batch:batch + batch_size]

            # wrap them in Variable
            images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)

            # zero the parameter gradients
            optimizer.zero_grad()

            # forward + backward + optimize
            outputs = CNN(images_batch)
            loss = criterion(outputs, labels_batch)
            loss.backward()
            optimizer.step()

            # print statistics
            running_loss += loss.data[0]
            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')

Et l'erreur se produit ici

# wrap them in Variable
images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)
4
soshi shimada

Si ma supposition est correcte, vous obtenez probablement une erreur dans la ligne suivante.

# wrap them in Variable
images_batch, labels_batch = Variable(images_batch), Variable(labels_batch)

Ça veut dire, images_batch et/ou labels_batch sont des listes. Vous pouvez simplement les convertir en tableau numpy, puis les convertir en tenseur comme suit.

# wrap them in Variable
images_batch = torch.from_numpy(numpy.array(images_batch))
labels_batch = torch.from_numpy(numpy.array(labels_batch))

Cela devrait résoudre votre problème.


Modifier : si vous obtenez l'erreur suivante lors de l'exécution de l'extrait de code ci-dessus:

"RuntimeError: impossible de convertir un np.ndarray donné en un tenseur - il a un type non valide. Les seuls types pris en charge sont: double, float, int64, int32 et uint8."

Vous pouvez créer le tableau numpy en donnant un type de données. Par exemple,

images_batch = torch.from_numpy(numpy.array(images_batch, dtype='int32'))

Je suppose images_batch contient des informations sur les pixels des images, j'ai donc utilisé int32. Pour plus d'informations, consultez documentation officielle .

5
Wasi Ahmad