首页 > 解决方案 > 这个火炬项目不断告诉我“预期 2 个或更多维度(得到 1 个)”

问题描述

我试图使用 PyTorch 制作自己的神经网络。我不明白为什么我的代码不能正常工作。

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)

该程序不断给我这个错误:

预期 2 个或更多维度(得到 1 个)

谁能解释我的代码有什么问题?

标签: pythonpytorch

解决方案


您用作数据集的张量的Xs形状为(n, 2)。因此,当循环遍历它时,每个元素x最终都会变成一维张量形状(2,)。但是,您的模块需要一个批处理张量作为输入,这里是一个 2D 张量形状(n, 2),就像Xs. 您有两种可能的选择,或者使用数据加载器并将您的数据集划分为批次,或者解压缩您的输入x以使其成为二维形状(1, 2)

  • 使用 aTensorDataset并用 a 包装它DataLoader

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

    然后迭代dataloader将返回成批的四个(输入和相应的标签):

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

    TensorDataset并且Dataloader都是从torch.utils.data.

  • 或者使用torch.Tensor.unsqueezeonx添加一个额外的维度:

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

    或者,您可以执行x[None]具有相同效果的操作。


推荐阅读