首页 文章

在PyTorch中使用预先训练好的句子嵌入

提问于
浏览
0

[Original post, see below for edited]

我是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] Improved Code

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

model:

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

1 回答

  • 0
    • 是的,也许,在 autograd.Variable(torch.from_numpy(embeds[0]).float().cuda()) 中 - 你不需要 .float() ,因为 embeds 已经是一个浮动张量 . 顺便说一下,将单词向量组合成句子向量是可以的,但是为什么你需要RNN来生成句子表示?请仔细阅读您正在做的事情 .

    • 是的,你正在跟随随机梯度下降(在每个句子后运行backprop) . 要了解如何使用小批量梯度下降,您可以看到任何基于语言模型的pytorch示例 . 例如,snli是文本分类的一个很好的例子 .

    • 这取决于您想如何使用它 . 我相信,在pytorch中没有使用预先训练好的句子嵌入的“最合适的方式”的概念 .

    • 您的代码存在严重问题 . 例如,模型中的LSTM没有做任何事情!此外,如果您想调试代码,我建议您打印损失值并检查损失值是否随着迭代次数的增加而下降 . 如果没有,那么你需要找出你的模型没有学习任何东西的原因 .

    建议:从你的问题来看,你看起来像是pytorch的新手 . 因此,我建议您在继续之前先阅读官方教程和示例 .

相关问题