用于异常检测的LSTM自动编码器

2024-05-08 07:33:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在测试LSTM自动编码器在2D输入异常检测上的不同实现。 我的问题不是关于代码本身,而是关于理解每个网络的基本行为

两种实现具有相同数量的单元(16)。型号2是一个“典型”的顺序到顺序自动编码器,编码器的最后一个序列重复“n”次以匹配解码器的输入。 我想了解为什么模型1似乎很容易超越模型2,为什么模型2不能比平均值做得更好

型号1:

class LSTM_Detector(Model):
  def __init__(self, flight_len, param_len, hidden_state=16):
    super(LSTM_Detector, self).__init__()
    self.input_dim = (flight_len, param_len)
    self.units = hidden_state
    self.encoder = layers.LSTM(self.units,
                  return_state=True,
                  return_sequences=True,
                  activation="tanh",
                  name='encoder',
                  input_shape=self.input_dim)
    
    self.decoder = layers.LSTM(self.units,
                  return_sequences=True,
                  activation="tanh",
                  name="decoder",
                  input_shape=(self.input_dim[0],self.units))
    
    self.dense = layers.TimeDistributed(layers.Dense(self.input_dim[1]))
    
  def call(self, x):
    output, hs, cs = self.encoder(x)
    encoded_state = [hs, cs] # see https://www.tensorflow.org/guide/keras/rnn  
    decoded = self.decoder(output, initial_state=encoded_state)
    output_decoder = self.dense(decoded)

    return output_decoder

型号2:

class Seq2Seq_Detector(Model):
  def __init__(self, flight_len, param_len, hidden_state=16):
    super(Seq2Seq_Detector, self).__init__()
    self.input_dim = (flight_len, param_len)
    self.units = hidden_state
    self.encoder = layers.LSTM(self.units,
                  return_state=True,
                  return_sequences=False,
                  activation="tanh",
                  name='encoder',
                  input_shape=self.input_dim)
    
    self.repeat = layers.RepeatVector(self.input_dim[0])
    
    self.decoder = layers.LSTM(self.units,
                  return_sequences=True,
                  activation="tanh",
                  name="decoder",
                  input_shape=(self.input_dim[0],self.units))
    
    self.dense = layers.TimeDistributed(layers.Dense(self.input_dim[1]))
    
  def call(self, x):
    output, hs, cs = self.encoder(x)
    encoded_state = [hs, cs] # see https://www.tensorflow.org/guide/keras/rnn 
    repeated_vec = self.repeat(output)
    decoded = self.decoder(repeated_vec, initial_state=encoded_state)
    output_decoder = self.dense(decoded)

    return output_decoder

我在一个数据样本(89, 1500, 77)上对这两个模型进行了200个时代的拟合,每个输入都是一个二维数组(1500, 77)。和测试数据(10,1500,77)。两种模型都只有16 units

这里或自动编码器的结果上的一个测试数据的功能

结果模型1:(黑线为真值,重建图像为红色)

enter image description here

结果模型2:

enter image description here

我知道第二个更具限制性,因为输入序列中的所有信息都被压缩到一个步骤中,但我仍然感到惊讶的是,它几乎不能比预测平均值做得更好

另一方面,我觉得模型1在不返回输入的情况下更容易受到新数据的“影响”。请参见下面的模型1示例,其中有一条平线作为输入:

enter image description here

PS:我知道这类模型的数据不多,我有更多的可用数据,但在这个阶段,我只是在尝试,试图建立我的理解

PS 2:两个模型都没有过度拟合数据,训练和验证曲线几乎都是教科书式的

有人能解释为什么在行为方面存在这样的差距吗

多谢各位


Tags: 数据模型selftrueencoderinputoutputlen
1条回答
网友
1楼 · 发布于 2024-05-08 07:33:42

在模型1中,77个特征的每个点都以以下方式进行压缩和解压缩:77->;16->;16->;77以及前面步骤中的一些信息。在这种情况下,似乎用just TimeDistributed(density(…)替换LSTMs也可以,但不能肯定,因为我不知道数据。第三个图像可能会变得更好

当输入中没有有用的信号时,通常会发生预测模型2的情况,并且模型能做的最好的事情(好的,优化做)就是预测训练集的平均目标值

在模型2中,您有:

...
    self.encoder = layers.LSTM(self.units,
                  return_state=True,
                  return_sequences=False,
...

然后

    self.repeat = layers.RepeatVector(self.input_dim[0])

所以,事实上,当它

    repeated_vec = self.repeat(output)
    decoded = self.decoder(repeated_vec, initial_state=encoded_state)

它只需从编码器获取最后一个输出(在本例中代表1500的最后一步),将其复制1500次(input_dim[0]),并尝试根据最后几个值的信息预测所有1500个值。这里是模型丢失大部分有用信号的地方。它没有关于输入的足够/任何信息,为了最小化损失函数(我假设在本例中是MSE或MAE),它能学到的最好的东西是预测每个特征的平均值

此外,seq-to-seq模型通常将解码器步骤的预测作为输入传递给下一个解码器步骤,在当前情况下,它总是相同的值

TL;DR1)seq-to-seq不是这种情况下的最佳模型;2) 由于瓶颈问题除了预测每个特征的平均值外,它无法真正学会做任何更好的事情

相关问题 更多 >

    热门问题