自注意力机制并没有改进 LSTM 分类模型

数据挖掘 机器学习 深度学习
2021-09-18 21:06:20

我正在使用时间序列数据进行 8 类分类。

看来自注意力机制的实现对模型没有影响,所以我认为我的实现有一些问题。但是,我不知道如何使用keras_self_attention模块以及如何设置参数。

问题是如何将keras_self_attention模块用于这样的分类器。

第一个混淆矩阵是 2 层 LSTM。

   
    lstm_unit = 256
    
    model = tf.keras.models.Sequential()
    model.add(Masking(mask_value=0.0, input_shape=(X_train.shape[1], X_train.shape[2])))
    model.add(Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True)))

    model.add(Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True)))

    model.add(keras.layers.Flatten())
    model.add(Dense(num_classes, activation='softmax'))

第二个混淆矩阵是 2 lSTM + 2 self-attention。

    lstm_unit = 256
    
    model = tf.keras.models.Sequential()
    model.add(Masking(mask_value=0.0, input_shape=(X_train.shape[1], X_train.shape[2])))
    model.add(Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True)))

    model.add(Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True)))

    model.add(SeqSelfAttention(attention_type=SeqSelfAttention.ATTENTION_TYPE_MUL,
attention_activation='sigmoid'))

   

    model.add(keras.layers.Flatten())
    model.add(Dense(num_classes, activation='softmax'))

在此处输入图像描述

我进一步尝试了模块中的不同功能,例如

1.多头

    model.add(MultiHead(Bidirectional(LSTM(units=32)), layer_num=10, name='Multi-LSTMs'))

  1. 剩余连接
 inputs = Input(shape=(X_train.shape[1],X_train.shape[2]))
    x = Masking(mask_value=0.0)(inputs)

    x2 = SeqSelfAttention(attention_type=SeqSelfAttention.ATTENTION_TYPE_MUL,
    attention_activation='sigmoid')(x)

    x = x + x2

    x = Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True))(x)
    x = Flatten()(x)
    
    output = Dense(num_classes, activation='softmax')(x)

    model = Model(inputs=inputs, outputs=output)

在此处输入图像描述 但它们或多或少相同,对 MAR MAP 和 ACC 没有太大影响。

我有 2 Titan Xp 所以计算能力对我来说不是问题,有没有办法让模型更准确?

1个回答

似乎自注意力机制的实现对模型没有影响,所以我认为我的实现有一些问题。

我注意到的第一件事是您的基本模型表现不佳,F1 分数较低,尤其是对于 1..7 类。会不会是训练数据中没有那么多信号,而 2 层 LSTM 已经把它全部吸光了?

我的第二个想法是,self-attention 擅长发现项目之间的联系,无论它们在序列中相距甚远。但是 LSTM 在这方面也相当出色。所以也许更多相同的东西不是你需要的。Self-attention 是 Transformer 的重要组成部分,因为它是唯一跨序列工作的组件;唯一的其他组件是 FFN,它单独对每个项目进行操作。

把这两件事从我的胸口拿开后,我在实验中注意到的一件事(同样,这些都是在变压器的背景下)是剩余连接的重要性。如果我去掉 self-attention 和 FFN 之间的剩余连接,我会得到一个更糟糕的模型。(即使我仍然在每一层都有剩余的连接。)

因此,您可以尝试在 self-attention 中添加残差连接。

另一个想法是更早地移动self-attention。将它放在 LSTM 之前,而不是在它们之后。(再次在其上存在剩余连接。)

这是(未经测试的)代码中的想法。我已经将自注意力模块移到了第一个 LSTM 层之前,然后取输入和输出的总和——这就是在它之间建立残差连接的原因。

...

x = Masking(mask_value=0.0, input_shape=(X_train.shape[1], X_train.shape[2])))

x2 = SeqSelfAttention(attention_type=SeqSelfAttention.ATTENTION_TYPE_MUL,
attention_activation='sigmoid')(x)

x = x + x2

x = Bidirectional(LSTM(lstm_unit, dropout=dropout,return_sequences=True))(x)

...

请注意,您不能使用 Keras 顺序类(因为数据流不再是顺序的)。

参考:https ://keras.io/examples/nlp/text_classification_with_transformer/残差部分一开始很难发现,因为它是作为两层规范调用的输入完成的。