因此,我通常对PyTorch和神经网络都不熟悉,因此在创建按性别对姓名进行分类的神经网络时遇到了一些问题。
我基于PyTorch的RNN教程,该教程按国籍对姓名进行分类,但我决定不采用重复性的方法...如果这是错误的主意,请在这里停下来!
但是,每当我尝试通过网络运行输入时,都会告诉我:

RuntimeError: matrices expected, got 3D, 2D tensors at /py/conda-bld/pytorch_1493681908901/work/torch/lib/TH/generic/THTensorMath.c:1232

我知道这与PyTorch总是希望有一个批处理大小之类的东西有关,并且我以这种方式设置了张量,但是到现在为止,您可能可以告诉我我不知道我在说什么。
这是我的代码:
from future import unicode_literals, print_function, division
from io import open
import glob
import unicodedata
import string
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import random
from torch.autograd import Variable
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

"""------GLOBAL VARIABLES------"""

all_letters = string.ascii_letters + " .,;'"
num_letters = len(all_letters)
all_names = {}
genders = ["Female", "Male"]

"""-------DATA EXTRACTION------"""

def findFiles(path):
    return glob.glob(path)

def unicodeToAscii(s):
    return ''.join(
        c for c in unicodedata.normalize('NFD', s)
        if unicodedata.category(c) != 'Mn'
        and c in all_letters
    )

# Read a file and split into lines
def readLines(filename):
    lines = open(filename, encoding='utf-8').read().strip().split('\n')
    return [unicodeToAscii(line) for line in lines]

for file in findFiles("/home/andrew/PyCharm/PycharmProjects/CantStop/data/names/*.txt"):
    gender = file.split("/")[-1].split(".")[0]
    names = readLines(file)
    all_names[gender] = names

"""-----DATA INTERPRETATION-----"""

def nameToTensor(name):
    tensor = torch.zeros(len(name), 1, num_letters)
    for index, letter in enumerate(name):
        tensor[index][0][all_letters.find(letter)] = 1
    return tensor

def outputToGender(output):
    gender, gender_index = output.data.topk(1)
    if gender_index[0][0] == 0:
        return "Female"
    return "Male"

"""------NETWORK SETUP------"""

class Net(nn.Module):
    def __init__(self, input_size, output_size):
        super(Net, self).__init__()
        #Layer 1
        self.Lin1 = nn.Linear(input_size, int(input_size/2))
        self.ReLu1 = nn.ReLU()
        self.Batch1 = nn.BatchNorm1d(int(input_size/2))
        #Layer 2
        self.Lin2 = nn.Linear(int(input_size/2), output_size)
        self.ReLu2 = nn.ReLU()
        self.Batch2 = nn.BatchNorm1d(output_size)
        self.softMax = nn.LogSoftmax()

    def forward(self, input):
        output1 = self.Batch1(self.ReLu1(self.Lin1(input)))
        output2 = self.softMax(self.Batch2(self.ReLu2(self.Lin2(output1))))
        return output2

NN = Net(num_letters, 2)

"""------TRAINING------"""

def getRandomTrainingEx():
    gender = genders[random.randint(0, 1)]
    name = all_names[gender][random.randint(0, len(all_names[gender])-1)]
    gender_tensor = Variable(torch.LongTensor([genders.index(gender)]))
    name_tensor = Variable(nameToTensor(name))
    return gender_tensor, name_tensor, gender

def train(input, target):
    loss_func = nn.NLLLoss()

    optimizer = optim.SGD(NN.parameters(), lr=0.0001, momentum=0.9)

    optimizer.zero_grad()

    output = NN(input)

    loss = loss_func(output, target)
    loss.backward()
    optimizer.step()

    return output, loss

all_losses = []
current_loss = 0

for i in range(100000):
    gender_tensor, name_tensor, gender = getRandomTrainingEx()
    output, loss = train(name_tensor, gender_tensor)
    current_loss += loss

    if i%1000 == 0:
        print("Guess: %s, Correct: %s, Loss: %s" % (outputToGender(output), gender, loss.data[0]))

    if i%100 == 0:
        all_losses.append(current_loss/10)
        current_loss = 0

# plt.figure()
# plt.plot(all_losses)
# plt.show()

请帮助新手!

最佳答案

  • 调试您的错误:

  • Pycharm是一个有用的python调试器,可让您设置张量的断点和 View 尺寸。
    为了简化调试,请勿像这样堆叠内容
    output1 = self.Batch1(self.ReLu1(self.Lin1(input)))
    

    反而,
    h1 = self.ReLu1(self.Lin1(input))
    h2 = self.Batch1(h1)
    

    对于堆栈跟踪,Pytorch还提供Pythonic错误堆栈跟踪。我相信以前
    RuntimeError: matrices expected, got 3D, 2D tensors at /py/conda-bld/pytorch_1493681908901/work/torch/lib/TH/generic/THTensorMath.c:1232
    

    有一些python错误stacktrace指向您的代码。如前所述,为了简化调试,请不要向前堆叠。

    您可以使用Pycharm在崩溃点之前创建断点。在调试器监视程序中,然后使用Variable(torch.rand(dim1, dim2))测试正向输入,输出尺寸以及尺寸是否不正确。与输入维度进行比较。在调试器监视程序中调用input.size()

    例如,self.ReLu1(self.Lin1(Variable(torch.rand(10, 20)))).size()。如果显示读取的文本(错误),则输入尺寸不正确。否则,它显示输出的大小。

    python - 关于Pytorch中的张量尺寸和批量大小感到困惑-LMLPHP
  • 阅读文档

  • Pytorch Docs中,它指定输入/输出尺寸。它还有一个示例代码片段
    >>> rnn = nn.RNN(10, 20, 2)
    >>> input = Variable(torch.randn(5, 3, 10))
    >>> h0 = Variable(torch.randn(2, 3, 20))
    >>> output, hn = rnn(input, h0)
    

    您可以使用PyCharm Debugger中的代码片段来浏览您感兴趣的特定层(RNN,Linear,BatchNorm1d)的输入,输出维度。

    关于python - 关于Pytorch中的张量尺寸和批量大小感到困惑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45020108/

    10-12 23:59