【问题标题】:Pytorch LSTM - generating sentence- word by word?Pytorch LSTM - 逐字生成句子?
【发布时间】:2022-01-01 16:01:17
【问题描述】:

我正在尝试实现一个神经网络来生成句子(图像说明),为此我正在使用 Pytorch 的 LSTM (nn.LSTM)。

我想在训练中输入的输入来自大小batch_size * seq_size * embedding_size,因此seq_size 是句子的最大大小。例如 - 64*30*512

在 LSTM 之后有一个 FC 层 (nn.Linear)。 据我了解,这种类型的网络使用隐藏状态(在这种情况下为h,c),并且每次都预测下一个单词。

我的问题是-在训练中-我们是否必须在forward函数中手动将句子逐字输入LSTM,或者LSTM知道如何自己做?

我的转发函数如下所示:

    def forward(self, features, caption, h = None, c = None):
        batch_size = caption.size(0)
        caption_size = caption.size(1)
        
        no_hc = False
        if h == None and c == None:
            no_hc = True
            h,c = self.init_hidden(batch_size)
        
        embeddings = self.embedding(caption)  
        output = torch.empty((batch_size, caption_size, self.vocab_size)).to(device)

        for i in range(caption_size): #go over the words in the sentence
            if i==0:
                lstm_input = features.unsqueeze(1)
            else: 
                lstm_input = embeddings[:,i-1,:].unsqueeze(1)
            
            out, (h,c) = self.lstm(lstm_input, (h,c))
            out = self.fc(out)

            output[:,i,:] = out.squeeze()
        
        if no_hc:
            return output

        return output, h,c    

(灵感来自here

这里forward的输出来自大小batch_size * seq_size * vocab_size,这很好,因为它可以与损失函数中原始batch_size * seq_size大小的标题进行比较。

问题是forward 内的这个for 循环是否真的需要一个接一个地输入单词,或者我可以以某种方式一次输入整个句子并获得相同的结果?

(我看到了一些这样做的例子,例如this one,但我不确定它是否真的等效)

【问题讨论】:

    标签: neural-network pytorch lstm recurrent-neural-network


    【解决方案1】:

    答案是,LSTM 知道如何自行完成。您不必逐个手动输入每个单词。 一种直观的理解方式是,您发送的批次的形状包含seq_length (batch.shape[1]),它使用它来决定句子中的单词数量。单词通过LSTM Cell 生成隐藏状态和C。

    【讨论】:

    • 谢谢!你知道如果我需要在我的模型中使用 Attention 会发生什么吗? (例如 nn.multiheadAttention)它仍然可以一个接一个地执行,还是我需要循环?
    • 为了使用注意力,您必须定义哪些向量将用作键、查询和值。如果单词被视为查询和值,LSTM in PyTorch 返回三个项目:outputh_nc_n。虽然h_nc_n 包含发送到LSTM Cell 的最后一个单词的信息,但output 包含聚合的隐藏状态输出(仔细观察,它的形状包含seq_len 作为维度之一)。您可以使用与seq_len 中每个单词对应的张量进行查询和值。 @Shir
    • 谢谢harraj!如果我使用注意力,我需要一个一个地输入单词而不是全部输入吗?因为据我了解,我需要每次都运行一个注意力步骤,然后是一个注意力步骤,所以如果我理解正确 - 那里需要前向循环。是真的吗?
    • @Shir 我不明白是什么让你认为使用注意力需要逐个发送单词,但答案是否定的。即使使用nn.MultiheadAttention,你也不需要循环的话。如果您看到documentation 表示输入张量的形状,他们期望的维度L(或S)代表seq_len。整批单词要一次性传递,它会在内部完成所有需要的工作。
    • 为了将nn.multihesdattention 添加到我的模型中,我是否需要在嵌入和lstm 之前添加它,然后将输入发送到lstm?我读了注意应该得到输入尺寸batch* seq_len * embed_size,所以我想我应该复制特征(图像)seq 次。然后我想我应该将输出与标题连接起来以提供 lstm,但是 lstm 的输出是batch * 2seq_len * embed,我不知道如何减小中间尺寸的大小。非常感谢您的帮助!
    猜你喜欢
    • 2017-09-13
    • 1970-01-01
    • 2019-02-02
    • 2019-10-14
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    相关资源
    最近更新 更多