Skip to content
Advertisement

This torch project keep telling me “Expected 2 or more dimensions (got 1)”

I was trying to make my own neural network using PyTorch. I do not understand why my code is not working properly.

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optimizers
import numpy as np
from tqdm import tqdm
import os
import hashlib

# Only for the first time
MAKE_DATA = False


class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(2, 100)
        self.fc2 = nn.Linear(100, 200)
        self.fc3 = nn.Linear(200, 200)
        self.fc4 = nn.Linear(200, 1)

    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = self.fc4(x)
        return F.relu(x)


def make_numirical(data):
    data = str(data)
    data = data.encode()
    data = hashlib.md5(data).hexdigest()
    str1 = ''
    for c in data:
        if not (c >= '0' and c <= '9'):
            c = ord(c)
            if c > 10:
                c /= 10
        str1 += str(int(c))
    return int(str1[:20])


def make_train_data():
    HITS = 'Songs_DB/Hits'
    NOHITS = 'Songs_DB/NoHits'
    hits_count = 0
    no_hits_count = 0
    LABELS = {HITS: 0, NOHITS: 0}
    training_data = []
    i = 0
    for label in LABELS:
        for f in tqdm(os.listdir(label)):
            try:
                path = os.path.join(label, f)
                with open(path, 'rb') as file:
                    data = file.read()
                    file.close()
                data = make_numirical(data)
                data = int(data)
                training_data.append([np.array([data]), np.eye(2)[i]])

                if label == HITS:
                    hits_count += 1
                else:
                    no_hits_count += 1
            except:
                pass
        i += 1

        np.random.shuffle(training_data)
        np.save('training_data.npy', training_data)
        print(hits_count)
        print(no_hits_count)


if MAKE_DATA:
    make_train_data()

model = Model()

# 1 = brown, 0 = not brown, 1 = cat, 0 = dog.

Xs = torch.Tensor([[0, 1], [1, 1], [1, 0], [1, 1], [1, 1], [0, 1], [1, 1], [0, 0], [1, 0]])
ys = torch.Tensor([[1], [0], [0], [1], [0], [1], [0], [1], [1]])

i = 0
for x in Xs:
    output = model(x)
    print(output)
    loss = F.nll_loss(output, ys[i])

print(loss)

The program keeps giving me this error:

Expected 2 or more dimensions (got 1)

Can anyone explain what is wrong with my code?

Advertisement

Answer

The tensor you use as the dataset, Xs is shaped (n, 2). So when looping over it each element x ends up as a 1D tensor shaped (2,). However, your module expects a batched tensor as input, i.e. here a 2D tensor shaped (n, 2), just like Xs. You have two possible options, either use a data loader and divide your dataset into batches, or unsqueeze your input x to make it two dimensional shaped (1, 2).

  • Using a TensorDataset and wrapping it with a DataLoader:

    >>> dataset = TensorDataset(Xs, ys)
    >>> dataloader = Dataloader(dataset, batch_size=4)
    

    Then iterating over dataloader will return batches of fours (inputs and corresponding labels):

    >>> for x, y in dataloader:
    ...     output = model(x)
    ...     loss = F.nll_loss(output, y)
    

    TensorDataset and Dataloader are both imported from torch.utils.data.

  • Or use torch.Tensor.unsqueeze on x to add one extra dimension:

    >>> for x, y in zip(Xs, ys):
    ...     output = model(x.unsqueeze())
    ...     loss = F.nll_loss(output, y)
    

    Alternatively, you can do x[None] which has the same effect.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement