[Исходное сообщение, см. отредактированное ниже]
Я новичок в PyTorch и пытаюсь выполнить в нем задачу классификации предложений.
Я усреднил вложения слов в каждом предложении (вложения перчаток), чтобы сформировать вложение предложения. Следовательно, размерность вложения каждого предложения одинакова. Насколько я понимаю, поскольку у меня уже есть вложения, мне не нужен слой встраивания перед использованием LSTM. Моя модель выглядит следующим образом:
import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
class LSTM1(nn.Module):
def __init__(self,args):
super(LSTM1,self).__init__()
self.args = args
self.hidden_dim = args.hidden_dim
self.lstm = nn.LSTM(args.embed_dim, args.hidden_dim)
self.hidden2tag = nn.Linear(args.hidden_dim, 2)
self.hidden = self.init_hidden()
def init_hidden(self):
return (autograd.Variable(torch.zeros(1,1, self.hidden_dim).cuda()),
autograd.Variable(torch.zeros(1,1, self.hidden_dim).cuda()))
def forward(self,embeds):
embeds = autograd.Variable(torch.from_numpy(embeds[0]).float().cuda())
lstm_output, self.hidden = self.lstm(embeds.view(1, 1, -1), self.hidden)
tag_space = self.hidden2tag(lstm_output.view(1, -1))
scores = F.log_softmax(tag_space)
return scores
И я передаю предложения в виде вложений следующим образом:
model = model.LSTM1(args).cuda()
criterion = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=1e-5, momentum=0.9, weight_decay=1e-5)
optimizer.zero_grad()
for epoch in range(20):
for i in range(len(sentences)):
optimizer.zero_grad()
model.hidden = model.init_hidden()
target = prepare_targets(tag_phrase[i],tag_to_ix,1) #Gets a Variable(long tensor) for the target, single value (either 0 or 1)
score = model(sentences[i]) #sentences[i] is the embedding of sentence i
loss = criterion(score,target)
loss.backward()
optimizer.step()
Мои сомнения:
- Таким образом, встраивание переходит в модель, где в прямой функции оно преобразуется в Variablle (тензор с плавающей запятой) и, следовательно, является подходящим входом для LSTM. Это мое понимание вещей. Это верно?
- Я возвращаюсь назад после каждого предложения, значит, это делает каждое предложение отдельной партией? Как мне разбить предложения на партии и какие изменения мне тогда нужно внести в модель?
- Каков наиболее подходящий способ использования предварительно обученных встраиваний предложений в PyTorch?
- Если этот код кажется правильным, то проблема, с которой я столкнулся, заключается в том, что все классифицируется в один класс из двух. Есть предложения по устранению этой ошибки?
Спасибо.
[EDIT] Улучшенный код
embeddings = torch.from_numpy(embeddings).float().cuda()
args.embed_num=embeddings.size(0)
args.embed_dim=embeddings.size(1)
seq = [i for i in range(13000)]
seq_tensor = torch.LongTensor(seq).cuda() #Index tensor corresponding to the embedding.
target = prepare_targets(tag_phrase[:13000],tag_to_ix,1)
train_data = torch.utils.data.TensorDataset(seq_tensor.cuda(),target.data.cuda())
trainloader = torch.utils.data.DataLoader(train_data, batch_size=100, shuffle=True)
model = model2.LSTM1(args,embeddings, 3).cuda()
criterion = nn.NLLLoss()
optimizer = optim.SGD(model.parameters(), lr=1e-4, momentum=0.9, weight_decay=1e-5)
for epoch in range(1000):
avg_loss=0.
for i, data in enumerate(trainloader,0):
seq, target = data
seq_var, target = autograd.Variable(seq.cuda()), autograd.Variable(target.cuda())
correct=0
optimizer.zero_grad()
model.hidden=model.init_hidden()
score=model(seq_var)
loss = criterion(score,target)
loss.backward()
optimizer.step()
epoch_lis.append(epoch)
losses.append(loss.data[0])
_,predicted = torch.max(score.data,1)
correct += (predicted == target.data).sum()
print i, correct
модель:
class LSTM1(nn.Module):
def __init__(self,args,embeddings, layers):
super(LSTM1,self).__init__()
self.num_layers=layers
self.args = args
self.hidden_dim = args.hidden_dim
self.embed = nn.Embedding(args.embed_num, args.embed_dim)
self.embed.weight = nn.Parameter(embeddings)
self.lstm = nn.LSTM(args.embed_dim, args.hidden_dim, num_layers=self.num_layers)
self.hidden2tag = nn.Linear(args.hidden_dim, 2)
self.hidden = self.init_hidden()
def init_hidden(self):
return (autograd.Variable(torch.zeros(self.num_layers,1, self.hidden_dim).cuda()),
autograd.Variable(torch.zeros(self.num_layers,1, self.hidden_dim).cuda()))
def forward(self,sentence):
embeds = self.embed(sentence)
lstm_output, self.hidden = self.lstm(embeds.view(len(sentence), 1, -1), self.hidden)
tag_space = self.hidden2tag(lstm_output.view(len(sentence), -1))
scores = F.log_softmax(tag_space)
return scores