如何使用 tf.keras.layers.Attention 构建自注意力模型?

数据挖掘 喀拉斯 张量流 lstm
2021-10-14 08:59:28

我已经完成了一个简单的多对一 LSTM 模型,如下所示。

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dropout
model=Sequential()
model.add(LSTM(2**LSTM_units,input_length=data.shape[1],input_dim=data.shape[2],return_sequences=True))
model.add(Dropout(dropout))
model.add(Dense(1))
model.fit(data,res)
prediction=model.predict(test)

哪里data.shape是(日期,时间间隔,因素)和res.shape是(日期,1)。

我想用注意力替换 LSTM。如何使用 tf.keras.layers.Attention 获得类似的结果?

4个回答

目前,Self attention 不能作为 Keras 层使用。您可以在tensorflow.keras文档中找到的层有两个:

  • AdditiveAttention()层,实现Bahdanau注意力,
  • Attention()层,落实Luong注意。

对于 self-attention,您需要编写自己的自定义层。我建议你看看这个TensorFlow 教程,了解如何从头开始实现 Transformer。Transformer 是推广 self-attention 概念的模型,通过研究它可以找出更通用的实现。特别是查看Multi-Head Attention部分,他们在其中开发了一个自定义MultiHeadAttention()层。这就是所有与注意力相关的动作发生的地方。特别是,研究如何在其中使用K, V,Q张量来计算注意力公式。

这并不容易,但它肯定是一个超级有趣的练习。如果你用它制作了一些很酷的模型,请分享到 GitHub 存储库的链接。祝你好运!


编辑:

您可以使用一个技巧:由于 self-attention 属于乘法类型,因此您可以使用一个Attention()层并两次输入相同的张量(对于 Q、V 和间接 K)。

您不能以顺序方式构建模型,您需要功能模型。所以你会得到类似的东西:

attention = Attention(use_scale=True)(X, X)

其中 X 是你想要获得自我关注的张量。

注意use_scale=Truearg:这是自注意力张量的缩放,类似于原始 Transformer 论文中发生的那个。其目的是防止梯度消失(发生在 softmax 的极端区域)。唯一的区别是,在这个级别中,缩放参数是学习的,而不是一个固定的标量。它默认为False.

这个怎么样?https://pypi.org/project/keras-self-attention/

我使用它,但在没有 LSTM 层的情况下我还没有尝试过。此外,您必须直接使用 keras,而不是 tensorflow.keras。这是我现在正在运行的工作模型。

    model = keras.models.Sequential()
    model.add(keras.layers.LSTM(cfg.LSTM, input_shape=(cfg.TIMESTEPS,
              cfg.FEATURES),
              return_sequences=True))
    model.add(SeqSelfAttention(attention_activation='sigmoid'))
    model.add(keras.layers.Dense(cfg.DENSE))
    model.add(keras.layers.Dense(OUTPUT, activation='sigmoid'))

另外,看这里,有不少https://awesomeopensource.com/projects/attention-mechanism

至少有十几种主要的注意力类型,其中大多数是与 2014 年出现的第一个注意力模型(Bahdanau 等人)相比的微小变化。每种类型都可以通过多种方式实现,因此这可能会让某些人感到困惑谁想为她/他的模型添加一个简单的注意力层。此处分享了 Keras 中 Attention 的简单自定义实现:https ://stackoverflow.com/questions/63060083/create-an-lstm-layer-with-attention-in-keras-for-multi-label-text-classification/ 64853996#64853996

上面的几个答案建议使用现有的库来引起注意。我这样做的经验如下:

  • tf.keras.layers.Attention 和 AdditiveAttention 的用法:在分析 tf.keras.layers.Attention Github 代码以更好地理解它的工作原理时,我遇到的第一行是——“这个类适用于 Dense 或 CNN 网络,而不适用于 RNN 网络”。因此,对于您的情况,不建议这样做。

  • Cyber​​ZHG 维护的另一个开源版本称为 keras-self-attention。据我所知,这不是 Keras 或 TensorFlow 库的一部分,似乎是一段独立的代码。这包含两个类 - SeqWeightedAttention 和 SeqSelfAttention 层类。前者返回 2D 值,后者返回 3D 值。前者似乎松散地基于 Raffel 等人,可用于 Seq 分类,后者似乎是 Bahdanau 的变体。回购 QnA 包含代码所基于的相关注意论文。

一般来说,我建议您编写注意力层。这可以在不到六行代码中完成(基本原理。参见例如:https ://towardsdatascience.com/create-your-own-custom-attention-layer-understand-all-flavours- 2201b5e8be9e )...比您在集成、调试或理解这些外部库中的代码所花费的时间要少得多。