【发布时间】: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