【深度学习】 基于Keras的Attention机制代码实现及剖析——Dense+Attention

说明大部分代码来源于网上,但网上的代码一下子可能难以入门或因版本原因报错,此处整理后进行详细分析。  参考的代码来源1:Attention mechanism Implementation for Keras.网上大部分代码都源于此,直接使用时注意Keras版本,若版本不对应,在merge处会报错,解决办法为:导入Multiply层并将attention_dense.py第17行的:att...
摘要由CSDN通过智能技术生成

说明

  1. 大部分代码来源于网上,但网上的代码一下子可能难以入门或因版本原因报错,此处整理后进行详细分析。
      参考的代码来源1Attention mechanism Implementation for Keras.网上大部分代码都源于此,直接使用时注意Keras版本,若版本不对应,在merge处会报错,解决办法为:导入Multiply层并将attention_dense.py第17行的:
    attention_mul = merge([inputs, attention_probs], output_shape=32, name=‘attention_mul’, mode=‘mul’),改为:attention_mul = Multiply()([inputs, attention_probs])即可。
      参考的代码来源2[深度应用]·Keras极简实现Attention结构。这相当于来源1的简化版本,其将注意力层还做了封装,可直接使用。但此方法运用了两个注意力层,使我有些不太理解,这个问题在后面会进行讨论。
      本文主体将在来源1的基础上进行分析探讨。
  2. Attention机制大致过程就是分配权重,所有用到权重的地方都可以考虑使用它,另外它是一种思路,不局限于深度学习的实现方法,此处仅代码上分析,且为深度学习的实现版本。更多理论请看解读大牛文章深度学习中的注意力机制(2017版),还可以看解读这篇文章的大牛文章:[深度概念]·Attention机制实践解读
  3. 此处仅介绍Dense+Attention,进阶篇LSTM+Attention请看【深度学习】 基于Keras的Attention机制代码实现及剖析——LSTM+Attention

  如果你对本系列感兴趣,可接以下传送门:

实验目的

  1. 在简单的分类模型(如最简的全连接网络)基础上实现Attention机制的运用。
  2. 检验Attention是否真的捕捉到了关键特征,即被Attention分配的关键特征的权重是否更高。
  3. 在已有的模型基础上适当做些变化,如调参或新加层,看看Attention的稳定性如何。

数据集构造

  因为是在分类问题上进行应用,所以需要构造特征(X)和标签(Y),此处数据随机产生,但为了进行Attention机制的有效性验证,我们将特征X的某一列置成和标签完全相同,如果Attention有效,那么模型学出来,自然这一列的权重就要最高。
  默认设置:attention_column=1,即将 第“1”列(从0开始数) 与标签置成相同。
  同时为了简化问题,将分类设置为二分类问题,即randint的参数high设置为2。(注意randint是左闭右开,所以当high=2时,y要么为0,要么为1)

def get_data(n, input_dim, attention_column=1):
    """
    Data generation. x is purely random except that it's first value equals the target y.
    In practice, the network should learn that the target = x[attention_column].
    Therefore, most of its attention should be focused on the value addressed by attention_column.
    :param n: the number of samples to retrieve.
    :param input_dim: the number of dimensions of each element in the series.
    :param attention_column: the column linked to the target. Everything else is purely random.
    :return: x: model inputs, y: model targets
    """
    x = np.random.standard_normal(size=(n, input_dim))
    y = np.random.randint(low=0, high=2, size=(n, 1))
    x[:, attention_column] = y[:, 0]
    return x, y

   我们输出X,Y的前三行,看看是不是和我们想要的一致。可以看到每一个x∈X的“第1列”都等于标签号,一致了。
在这里插入图片描述

模型搭建

  下面开始在单隐层全连接网络的基础上用keras搭建注意力层。

def build_model():
    K.clear_session() #清除之前的模型,省得压满内存
    inputs = Input(shape=(input_dim,)) #输入层

    # ATTENTION PART STARTS HERE 注意力层
    attention_probs = Dense(input_dim, activation='softmax', name='attention_vec')(inputs)
    attention_mul =  Multiply()([inputs, attention_probs])
    # ATTENTION PART FINISHES HERE

    attention_mul = Dense(64)(attention_mul) #原始的全连接
    output = Dense(1, activation='sigmoid')(attention_mul) #输出层
    model = Model(input=[inputs], output=output)
    return model

  可以看到注意力层就两行代码,分别是一个Dense(全连接)层和一个Multiply操作,注意Multiply是对应元素相乘。
在这里插入图片描述
  如果画出加Attention前后的结构图,可如下图所示:
在这里插入图片描述

模型训练及验证

  设置随机种子可以调试对比每次结果的异同,输入必要参数,调用模型就可以开始训练了,由于是二分类问题,所以损失函数用二分类交叉熵。训练集测试集8:2进行验证。

if __name__ == '__main__':
    np.random.seed(1337)  # for reproducibility
    input_dim = 32 #特征数
    N = 10000 #数据集总记录数
    inputs_1, outputs = get_data(N, input_dim) #构造数据集

    m = build_model() #构造模型
    m.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    m.summary()

    m.fit([inputs_1], outputs, epochs=20, batch_size=64, validation_split=0.2)

  后台会输出我们的模型架构,看看是不是和设计的一样:
在这里插入图片描述
  之前设置的是20个Epoch,看看训练结果:
在这里插入图片描述

  • 64
    点赞
  • 354
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 32
    评论
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lechuan_dafo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值