【问题标题】:Keras LSTM go_backwards usageKeras LSTM go_backwards 用法
【发布时间】:2018-04-20 17:30:02
【问题描述】:

我有一个关于在 Keras LSTM 模型层中使用 go_backwards 参数的问题。该层的文档可以在这里找到:https://keras.io/layers/recurrent/#lstm

问题 1:如果我将“go_backwards”标志设置为 True,我是否仍会在训练过程中“向前”馈送输入数据。例如,如果一个英文输入句子通常读作“I fall”,而它的德文翻译读作“Ich fiel”,我是向前输入(“I fall”、“Ich fiel”)还是向后输入(“fell I”? , "field Ich") 在训练过程中。

问题 2:与进行模型预测的问题相同,数据是前馈(“我摔倒”)还是反向馈送(“我摔倒”)?

问题 3:如果我尝试使用下面的模型并想要反转语料库数据,我会在两个 LSTM 层中将 go_backwards 标志设置为 true 还是只在一个层中设置?

model = Sequential()
model.add(Embedding(src_vocab, embedding_dim, input_length=source_steps, mask_zero=True))
model.add(LSTM(embedding_dim,go_backwards=True))
model.add(RepeatVector(target_steps))
model.add(LSTM(embedding_dim, return_sequences=True))
model.add(TimeDistributed(Dense(tar_vocab, activation='softmax')))
# compile model
model.compile(optimizer='adam', loss='categorical_crossentropy')
# summarize defined model
model.summary()

我认为我应该转发所有数据,但我找不到任何文档让我相信这是正确的。

【问题讨论】:

    标签: python tensorflow nlp deep-learning keras


    【解决方案1】:

    go_backwards 只是反转你给 LSTM 的任何序列。 code 非常清晰易懂。

    if go_backwards: 
        inputs = reverse(inputs, 0)
    

    问题 1:如果我将“go_backwards”标志设置为 True,我是否仍会喂食 输入数据在训练过程中“向前”。例如,如果 英文输入句通常读作“I fall”,是德文 翻译为“Ich fiel”,我会向前馈送它吗(“I fall”,“Ich fiel"),或在训练期间倒退("fell I"、"fiel Ich") 过程。

    是的,您按照数据发生的顺序(转发)提供数据,go_backwards 只是将其反转。

    问题 2:与进行模型预测相同的问题是数据 前馈(“我摔倒”),还是反向馈送(“我摔倒”)?

    在推理期间也会发生同样的事情。

    问题 3:如果我尝试使用下面的模型并想要 反转语料库数据,我是否将 go_backwards 标志设置为 true 两个 LSTM 层还是只有一个?

    不确定为什么要反转解码器(第二个)LSTM 的输入。在original seq2seq paper 中,如果我没记错的话,只有输入被反转,而不是目标。所以我建议将go_backwards 应用于第一个 LSTM。

    P.S:我建议阅读来自官方 Keras blog 的 seq2seq 教程/示例,而不是您尝试使用的任何代码。

    【讨论】:

      【解决方案2】:

      我猜 Q1 和 Q2 的答案很好,我同意 @scarecrow。

      关于 Q3,反转编码器序列的原因在很大程度上取决于您要解决的问题(稍后详细讨论)。这个想法是,它有助于在编码器和解码器之间建立强通信,帮助解码器更有效地解码。例如,假设您要将A B C 翻译成alpha beta gamma delta。通过反转源序列,任务变为,

      C B A -> alpha beta gamma delta

      如果Aalpha 密切相关,这为解码器提供了一个很好的起点。是的,它在每个序列中的最后一个词之间创造了更大的距离。

      但是,当您快要完成解码时,您可以通过更多地依赖目前已解码的内容来进行补偿,以提供良好的下一个预测。例如,在翻译任务中,如果解码了I snore in my ______,则无需对应的源词就可以很好地解决这个问题。 注意:这个关于预测词尾的讨论,是我的看法。

      但也要注意,在某些情况下,这可能比帮助更有害。想想源语言是subject-verb-object 而目标语言是object-subject-verb 的情况。反转源会得到object-verb-subject,这使得解码器的起始词远离源对应的词。

      【讨论】:

        【解决方案3】:

        反转输入的另一个好处如下:

        由于 RNN 要求一批训练数据中的所有序列都具有相同的长度,因此在较短句子的末尾使用填充标记,以便批次中的所有句子/序列具有相同的长度。所以在编码器结束时,大多数标记将是填充标记,因此在解码器输出和编码器输入之间产生了很长的距离:

        例如,假设序列长度设置为 10。

        问:你要去哪里?

        A:我要去游乐场。

        编码器输入:你要去哪里? PAD_token PAD_token PAD_token PAD_token PAD_token

        解码器输出:我要去操场EOS_token

        在编码器输入的最后一个字和解码器输出的第一个字之间有 5 个无用的填充标记。

        反向编码器输入:PAD_token PAD_token PAD_token PAD_token PAD_token ?去你在哪里

        解码器输出:我要去操场EOS_token

        现在,实际编码器输入和解码器输出之间的距离更小了!

        在seq-to-seq架构中引入attention后,attention值解决了这个问题,并且不需要反转输入(注意:最后一句只是我的观察)。编码器将源序列映射到隐藏向量这是最后一个编码器状态——当不使用注意力时,这个上下文/思想向量被输入到解码器状态[除了前一个解码器状态和目标/输出序列中的前一个词]。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-07
          • 2018-11-06
          • 2020-05-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多