LSTM自动编码器的这些实现之间的区别?

岩石

引起这个问题的具体原因是return_sequenceTensorFlow的LSTM层版本争论。

文档说:

布尔值。是否返回最后的输出。在输出序列或完整序列中。默认值:False。

我已经看到了一些实现,尤其是自动编码器,该编码器使用此参数剥离除输出序列中的最后一个元素以外的所有内容,作为自动编码器一半的“编码器”的输出。

以下是三种不同的实现。我想了解差异背后的原因,因为看起来差异非常大,但所有人都称自己是同一回事。

示例1(TensorFlow):

此实现剥离了LSTM的所有输出(序列的最后一个元素除外),然后重复该元素几次以重建序列:

model = Sequential()
model.add(LSTM(100, activation='relu', input_shape=(n_in,1)))
# Decoder below
model.add(RepeatVector(n_out))
model.add(LSTM(100, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))

在PyTorch中查看自动编码器的实现时,我没有看到作者这样做。取而代之的是,它们将LSTM的整个输出用于编码器(有时紧随其后是密集层,有时则不行)。

示例1(PyTorch):

此实现在应用LSTM层之前训练了一个嵌入...似乎几乎破坏了基于LSTM的自动编码器的想法...序列在到达LSTM层时已经被编码。

class EncoderLSTM(nn.Module):
  def __init__(self, input_size, hidden_size, n_layers=1, drop_prob=0):
    super(EncoderLSTM, self).__init__()
    self.hidden_size = hidden_size
    self.n_layers = n_layers

    self.embedding = nn.Embedding(input_size, hidden_size)
    self.lstm = nn.LSTM(hidden_size, hidden_size, n_layers, dropout=drop_prob, batch_first=True)

  def forward(self, inputs, hidden):
    # Embed input words
    embedded = self.embedding(inputs)
    # Pass the embedded word vectors into LSTM and return all outputs
    output, hidden = self.lstm(embedded, hidden)
    return output, hidden

示例2(PyTorch):

此示例编码器首先使用一个LSTM层扩展输入,然后通过具有较少数量隐藏节点的第二个LSTM层进行压缩。除了扩展,这似乎与我发现的这篇论文一致:https : //arxiv.org/pdf/1607.00148.pdf

但是,在此实现的解码器中,没有最终的密集层。解码通过第二个lstm层进行,该层将编码扩展回与原始输入相同的维度。在这里看到它这与论文不符(尽管我不知道论文是否权威)。

class Encoder(nn.Module):
  def __init__(self, seq_len, n_features, embedding_dim=64):
    super(Encoder, self).__init__()
    self.seq_len, self.n_features = seq_len, n_features
    self.embedding_dim, self.hidden_dim = embedding_dim, 2 * embedding_dim
    self.rnn1 = nn.LSTM(
      input_size=n_features,
      hidden_size=self.hidden_dim,
      num_layers=1,
      batch_first=True
    )
    self.rnn2 = nn.LSTM(
      input_size=self.hidden_dim,
      hidden_size=embedding_dim,
      num_layers=1,
      batch_first=True
    )
  def forward(self, x):
    x = x.reshape((1, self.seq_len, self.n_features))
    x, (_, _) = self.rnn1(x)
    x, (hidden_n, _) = self.rnn2(x)
    return hidden_n.reshape((self.n_features, self.embedding_dim))

题:

我想知道实现中的这种差异。差异似乎很大。所有这些完成同一件事的有效方法吗?还是在“真正的” LSTM自动编码器中进行了一些误导的尝试?

卢卡·安吉洛尼(Luca Angioloni)

没有官方或正确的方法来设计基于LSTM的自动编码器的体系结构。名称唯一提供的细节是该模型应该是自动编码器,并且应该在某个地方使用LSTM层。

您发现的实现各自不同,并且各自独特,即使它们可以用于同一任务。

让我们描述一下:

  • TF的实现

    • 它假定输入只有一个通道,这意味着序列中的每个元素都只是一个数字,并且已经过预处理
    • 的默认行为LSTM layerKeras / TF是只输出LSTM的最后输出,您可以将其设置为输出都与输出步骤return_sequences参数。
    • 在这种情况下,输入数据已缩小到 (batch_size, LSTM_units)
    • 考虑一下,LSTM的最后一个输出当然是先前输出的函数(特别是如果它是有状态的LSTM)
    • Dense(1)在最后一层应用a以获得与输入相同的形状。
  • PyTorch 1

    • 他们将嵌入应用于输入,然后再将其馈送到LSTM。
    • 这是标准做法,例如,它有助于将每个输入元素转换为向量形式(例如,请参见word2vec,其中在文本序列中,不是向量的每个词都映射到向量空间中)。这只是一个预处理步骤,因此数据具有更有意义的形式。
    • 这不会破坏LSTM自动编码器的思想,因为嵌入是独立应用于输入序列的每个元素的,因此当它进入LSTM层时不会被编码。
  • PyTorch 2

    • 在这种情况下,输入形状(seq_len, 1)与第一个TF示例中的不同,因此解码器不需要之后的密集。作者在LSTM层中使用了等于输入形状的多个单位。

最后,根据要训练的数据来选择模型的体系结构,尤其是:性质(文本,​​音频,图像),输入形状,所拥有的数据量等等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

LSTM自动编码器问题

来自分类Dev

从LSTM自动编码器输入分类器数据

来自分类Dev

LSTM自动编码器输出层

来自分类Dev

LSTM / GRU 自动编码器收敛

来自分类Dev

减少自动编码器的损耗

来自分类Dev

自动编码器形状

来自分类Dev

如何在Keras的LSTM自动编码器中获得Middel层的输出

来自分类Dev

LSTM 自动编码器的可变长度输入 - Keras

来自分类Dev

如何在Pytorch中实现压缩自动编码器?

来自分类Dev

使用自动编码器实现成对的文本相似性

来自分类Dev

使用RBM的深度自动编码器

来自分类Dev

Keras自动编码器的精度/损耗不变

来自分类Dev

自动编码器中的捆绑权重

来自分类Dev

keras变分自动编码器损失函数

来自分类Dev

用相同的图像训练自动编码器

来自分类Dev

转换自动编码器层级数

来自分类Dev

如何评估用于降维的自动编码器

来自分类Dev

可视化自动编码器输出

来自分类Dev

Theano中的反卷积自动编码器

来自分类Dev

什么是caffe自动编码器中的稀疏字段?

来自分类Dev

使用自动编码器的 1 的不兼容形状

来自分类Dev

Keras 中的有状态自动编码器

来自分类Dev

猫图像的 Keras 自动编码器的微调

来自分类Dev

自动编码器输出维度与输入维度不同

来自分类Dev

自动编码器尺寸的结果不正确

来自分类Dev

在 pytorch 中对自动编码器进行上采样

来自分类Dev

了解LSTM自动编码器的输出,并使用它来检测序列中的异常值

来自分类Dev

从Encog中的自动编码器抓取编码器/解码器

来自分类Dev

在编码器和解码器 keras 上拆分自动编码器