【问题标题】:LSTM/RNN in pytorch The relation between forward method and training modelpytorch中的LSTM/RNN前向方法与训练模型的关系
【发布时间】:2021-01-16 18:48:05
【问题描述】:

我对神经网络还很陌生,对于以下内容的任何含糊之处,请事先深表歉意。

在语言任务的“标准”LSTM 实现中,我们有以下内容(抱歉,草图非常粗略):

class LSTM(nn.Module):
    def __init__(*args):
    ...

    def forward(self, input, states):
         
        lstn_in = self.model['embed'](input)
        lstm_out, hidden = self.model['lstm'](lstm_in,states)

        return lstm_out, hidden

稍后,我们在训练步骤中调用此模型:

def train(*args):
      
    for epoch in range(epochs):
        ....
        *init_zero_states
        ...
        out, states = model(input, states)
        ...
    return model

假设我有 3 个句子作为输入:

sents = [[The, sun, is, shiny],
 [The, beach, was, very, windy],
 [Computer, broke, down, today]]
model = train(LSTM, sents)

所有句子中的所有单词都被转换为嵌入并加载到模型中。

现在的问题:

  1. self.model['lstm'] 是否会遍历所有文章中的所有单词并在每个单词之后生成一个输出?还是每句话?

  2. 模型如何区分这 3 个句子,例如在得到“The”、“sun”、“is”、“shiny”之后,在 'lstm' 重置和开始中做某事(例如状态)重新来过?

  3. out, states = model(input, states) 之后训练步骤中的“输出”是运行所有 3 个句子后的输出,因此是所有 3 个句子的组合“信息”?

谢谢!

【问题讨论】:

    标签: pytorch lstm recurrent-neural-network


    【解决方案1】:

    在 Pytorch 中使用 LSTM 时,您通常使用 nn.LSTM 函数。这是一个简单的示例,然后解释内部发生的情况:

    class Model(nn.Module):
        def __init__(self):
            super(Model, self).__init__()
            
            self.embedder = nn.Embedding(voab_size, embed_size)
    
            self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
            self.fc = nn.Linear(hidden_size, output_size)
            self.softmax = nn.Softmax(dim=1)
    
        def forward(self, x):
            x = self.embedder(x)
            
            # every time you pass a new sentence into the model you need to create
            # a new hidden-state (the LSTM requires, unlike RNNs, two hidden-states in a tuple)
    
            hidden = (torch.zeros(num_layers, batch_size, hidden_size), torch.zeros(num_layers, batch_size, hidden_size))
            x, hidden = self.lstm(x, hidden)
            
            # x contains the output states of every timestep, 
            # for classifiction we mostly just want the last one
            x = x[:, -1]
    
            x = self.fc(x)
            x = self.softmax(x)
            return x
    

    因此,当查看nn.LSTM 函数时,您会看到所有 N 个嵌入的单词都同时传递给它,并且您会得到所有 N 个输出(每个时间步一个)作为输出。这意味着在 lstm 函数内部,它遍历句子嵌入中的所有单词。我们只是在代码中看不到这一点。它还返回每个时间步的隐藏状态,但您不必进一步使用它。在大多数情况下,您可以忽略它。

    作为伪代码:

    def lstm(x):
        hiddenstates = init_with_zeros()
        outputs, hiddenstates = [], []
        for e in x:
            output, hiddenstate = neuralnet(e, hiddenstate)
        
            outputs.append(output)
            hiddenstates.append(hiddenstate)
    
        return outputs, hiddenstates
    
    sentence = ["the", "sun", "is", "shiny"]
    sentence = embedding(sentence)
    
    outputs, hiddenstates = lstm(sentence)
    

    【讨论】:

    • 如果在传递新句子之前创建了一个新的归零隐藏状态,这是否意味着输出中的隐藏状态对(hidden,cell)仅包含有关当前句子的信息? LSTM 不是在句子之间学习,还是那些“学到”的信息是通过更新 LSTM 的权重来保存的?
    • lstm 在序列中的所有序列元素之间学习。当您序列是一个句子时,序列元素就是单词。因此,隐藏状态仅在该句子中从一个单词传递到下一个单词。但这取决于你的问题。您的序列也可以是一个文本,其中每个序列元素都是一个句子。但是您的序列也可以是一个单词,其中每个序列元素都是一个字母。序列元素始终是您嵌入的内容。这取决于您要解决的问题。
    • 太棒了。在对句子进行分类的任务中,我会想象,一个序列对应于一个句子,因此在使用该句子中的每个单词创建隐藏层之后的每个句子之后都会初始化一个新的零状态?
    • 你想对一个句子进行分类(就像在情感分析中,如果一条推文有仇恨言论)?那么答案是肯定的。
    • 太棒了。这解释了很多。我想我必须对我当前的实现稍作改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2017-12-30
    • 1970-01-01
    • 2019-09-11
    相关资源
    最近更新 更多