【问题标题】:Failing to train SkipGram word embedding in Pytorch未能在 Pytorch 中训练 SkipGram 词嵌入
【发布时间】:2017-10-14 18:17:02
【问题描述】:

我正在使用https://arxiv.org/abs/1310.4546 中描述的著名模型训练skipgram 词嵌入。我想在 PyTorch 中训练它,但我遇到了错误,我不知道它们来自哪里。下面我提供了我的模型类、训练循环和批处理方法。有没有人知道发生了什么?

output = loss(data, target) 行出现错误。 <class 'torch.LongTensor'> 有问题,这很奇怪,因为 CrossEntropyLoss 需要很长的张量。输出形状可能是错误的,即:前馈后的torch.Size([1000, 100, 1000])

我的模型定义为:

import torch
import torch.nn as nn

torch.manual_seed(1)

class SkipGram(nn.Module):

    def __init__(self, vocab_size, embedding_dim):
        super(SkipGram, self).__init__()
        self.embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.hidden_layer = nn.Linear(embedding_dim, vocab_size)

        # Loss needs to be input: (minibatch (N), C) target: (minibatch, 1), each label is a class
        # Calculate loss in training            

    def forward(self, x):
        embeds = self.embeddings(x)
        x = self.hidden_layer(embeds)
        return x

我的训练定义为:

import torch.optim as optim
from torch.autograd import Variable

net = SkipGram(1000, 300)
optimizer = optim.SGD(net.parameters(), lr=0.01)

batch_size = 100
size = len(train_ints)

batches = batch_index_gen(batch_size, size)
inputs, targets = build_tensor_from_batch_index(batches[0], train_ints)


for i in range(100):
    running_loss = 0.0

    for batch_idx, batch in enumerate(batches):
        data, target = build_tensor_from_batch_index(batch, train_ints)
#         if (torch.cuda.is_available()):
#             data, target = data.cuda(), target.cuda()
#             net = net.cuda()
        data, target = Variable(data), Variable(target)
        optimizer.zero_grad()
        output = net.forward(data)
        loss = nn.CrossEntropyLoss()    
        output = loss(data, target)
        output.backward()
        optimizer.step()                        
        running_loss += loss.data[0]
        optimizer.step()

        print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                i, batch_idx * len(batch_size), len(size),
                100. * (batch_idx * len(batch_size)) / len(size), loss.data[0]))

如果有用的话,我的批处理是:

def build_tensor_from_batch_index(index, train_ints):
    minibatch = []
    for i in range(index[0], index[1]):
        input_arr = np.zeros( (1000,1), dtype=np.int )
        target_arr = np.zeros( (1000,1), dtype=np.int )
        input_index, target_index = train_ints[i]
        input_arr[input_index] = 1
        target_arr[input_index] = 1

        input_tensor = torch.from_numpy(input_arr)
        target_tensor = torch.from_numpy(target_arr)

        minibatch.append( (input_tensor, target_tensor) )

    # Concatenate all tensors into a minibatch
    #x = [tensor[0] for tensor in minibatch]
    #print(x)
    input_minibatch = torch.cat([tensor[0] for tensor in minibatch], 1)
    target_minibatch = torch.cat([tensor[1] for tensor in minibatch], 1)

    #target_minibatch = minibatch[0][1]
    return input_minibatch, target_minibatch

【问题讨论】:

  • 只是几个提示:不要调用 optimizer.step() 两次。您不需要每次都定义损失函数,只需在训练循环之外进行。您将loss 定义为一个函数,所以这个running_loss += loss.data[0] 会抛出一个错误。另外我认为您不想总结每个时期的损失。默认情况下,CrossEntropyLoss 函数将计算批次的平均值。看看 PyTorch 的 DataLoader。它为并行加载和批处理数据提供了一个简单的包装器。

标签: python-3.x deep-learning pytorch


【解决方案1】:

我不确定这一点,因为我没有阅读论文,但您使用原始数据和目标计算损失似乎很奇怪:

output = loss(data, target)

考虑到网络的输出是output = net.forward(data),我认为您应该将损失计算为:

error = loss(output, target)

如果这没有帮助,请简要指出论文中关于损失函数的内容。

【讨论】:

    猜你喜欢
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2019-07-11
    • 2021-03-29
    • 2018-03-12
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多