如何在pytorch中使用LSTM进行分类?

如何在pytorch中使用LSTM进行分类?,pytorch,Pytorch,我的代码如下: class Mymodel(nn.Module): def __init__(self, input_size, hidden_size, output_size, num_layers, batch_size): super(Discriminator, self).__init__() self.input_size = input_size self.hidden_size = hidden_size

我的代码如下:

class Mymodel(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers, batch_size):
        super(Discriminator, self).__init__()
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.num_layers = num_layers
        self.batch_size = batch_size

        self.lstm = nn.LSTM(input_size, hidden_size)
        self.proj = nn.Linear(hidden_size, output_size)
        self.hidden = self.init_hidden()


    def init_hidden(self):
        return (Variable(torch.zeros(self.num_layers, self.batch_size, self.hidden_size)),
                Variable(torch.zeros(self.num_layers, self.batch_size, self.hidden_size)))

    def forward(self, x):
        lstm_out, self.hidden = self.lstm(x, self.hidden)
        output = self.proj(lstm_out)
        result = F.sigmoid(output)
        return result

我想使用LSTM将句子分为好(1)或坏(0)。使用这段代码,我得到的结果是时间步长*批量大小*1,而不是0或1。如何编辑代码以获得分类结果?

作为最后一层,无论您想要多少类,都必须有一个线性层,即10层,如果您在MNIST中进行数字分类。对于您的情况,因为您正在进行是/否(1/0)分类,所以您有两个标签/类,所以线性层有两个类。我建议添加一个线性层作为

nn.线性(特征尺寸来自上一层,2)

然后利用交叉熵损失对模型进行训练

标准=nn.CrossEntropyLoss()

optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

理论: 回想一下,LSTM为序列中的每个输入输出一个向量。您使用的是句子,它是一系列单词(可能转换为索引,然后嵌入为向量)。LSTM中的这段代码清楚地说明了我的意思(***强调我的意思):

再一次:将“out”的最后一个片段与下面的“hidden”进行比较,它们是相同的。为什么?嗯

如果您熟悉LSTM,我建议您使用PyTorch LSTM。在output部分下,注意h_t是在每t处输出的

现在,如果你不习惯LSTM风格的方程,看看Chris Olah的。向下滚动至展开网络的示意图:

当你逐字输入你的句子时(
xi
-by-
xi+1
),你会从每个时间步得到一个输出。你需要解释整个句子来分类。所以你必须等到LSTM看到所有的文字。也就是说,你需要取
h\u t
,其中
t
是你句子中的单词数

代码: 这是一个编码。我不会复制粘贴整个内容,只会复制粘贴相关部分。魔法发生在self.hidden2label(lstm_out[-1])


您需要解决的主要问题是,在准备数据时,应将批大小放在哪个位置。据我所知,如果您没有在nn.LSTM()init函数中设置它,它会自动假定第二个dim是您的批处理大小,这与其他DNN框架有很大不同。也许你可以试试:

self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)

像这样要求您的模型将您的第一个dim视为批处理dim。

您知道如何解决此问题吗?@nnnmmm我发现avg pool可能有帮助,但我不知道如何在此代码中使用它?但我的代码已经有一个线性层。问题是,当程序在“output=self.proj(lstm_out)”这一行上运行时,会出现一条关于我前面提到的不匹配维度的错误消息。@Manoj acharyay您可能必须重新设置为正确的维度。对张量使用.view方法。它不应该是:`y=self.hidden2label(self.hidden[-1])@RameshK
lstm_out
是每个时间步的隐藏状态
lstm\u out[-1]
是最终隐藏状态
self.hidden
是最终隐藏向量和单元向量的2元组
(h\u f,c\u f)
。忽略任何必要的重塑,您可以使用
self.hidden[0]
。掩蔽和双向性有细微差别,所以我通常会说
self。隐藏[0]
是首选,但在这里它真的不重要。谢谢,但还是不确定。pytorch文档说:
-**h\u n**of shape
(num\u layers*num\u directions,batch,hidden\u size)
:包含
t=seq\u len
的隐藏状态的张量,其中输出是
输出:输出,(h\u n,c\n)
如何修改它以用于非nlp设置?我有一个脉冲(一系列向量)的时间序列数据,想将向量序列分类为1或0?Embedding_dim只是input dim?@这可能是它自己的问题,但您可以删除单词Embedding并直接将数据输入到
self.lstm
中,确保它与x具有相同的形状:
(序列长度、批量大小、向量维度)
class LSTMClassifier(nn.Module):

    def __init__(self, embedding_dim, hidden_dim, vocab_size, label_size, batch_size):
        ...
        self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.lstm = nn.LSTM(embedding_dim, hidden_dim)
        self.hidden2label = nn.Linear(hidden_dim, label_size)
        self.hidden = self.init_hidden()

    def init_hidden(self):
        return (autograd.Variable(torch.zeros(1, self.batch_size, self.hidden_dim)),
                autograd.Variable(torch.zeros(1, self.batch_size, self.hidden_dim)))

    def forward(self, sentence):
        embeds = self.word_embeddings(sentence)
        x = embeds.view(len(sentence), self.batch_size , -1)
        lstm_out, self.hidden = self.lstm(x, self.hidden)
        y  = self.hidden2label(lstm_out[-1])
        log_probs = F.log_softmax(y)
        return log_probs
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)