BiLSTM_Attention中的Attention

网上都是如下的模型结构图
在这里插入图片描述
从上图只能看出Attention层的位置是在BiLSTM的后面,从公式更直观一些:

  • 通过一个MLP获取隐含表示
    u i t = t a n h ( W w h i t + b w ) u_{it}=tanh(W_wh_{it}+b_w) uit=tanh(Wwhit+bw)
    其中 h i t h_{it} hit为LSTM层的输出,这个全连接层结构 W w h i t + b w W_wh_{it}+b_w Wwhit+bw并不会改变其维度。
    矩阵表示为 u = t a n h ( W h + b ) u=tanh(Wh+b) u=tanh(Wh+b),其维度变化 h ∈ R d × T h \in \mathbb{R}^{d \times T} hRd×T W ∈ R d × d W \in \mathbb{R}^{d \times d} WRd×d u ∈ R d × T u \in \mathbb{R}^{d \times T} uRd×T
  • 通过softmax归一化的权重
    α i t = e x p ( u i t T u w ) Σ t e x p ( u i t T u w ) \alpha_{it} = \frac{exp(\mathbf{u_{it}}^\mathrm{T}u_w)}{\Sigma_{t}exp(\mathbf{u_{it}}^\mathrm{T}u_w)} αit=Σtexp(uitTuw)exp(uitTuw)
    矩阵表示 α = s o f t m a x ( u u w ) \alpha = softmax(uu_{w}) α=softmax(uuw) u i t T u w u_{it}^\mathrm{T}u_w uitTuw是Attention的核心,其中 u w ∈ R d × 1 u_w \in \mathbb{R}^{d\times 1} uwRd×1是需要学习的参数,因此 α \alpha α的维度为 R T × 1 \mathbb{R}^{T\times 1} RT×1,这里的softmax是对整个序列的归一化
  • 计算Attention score
    s i = Σ t α i t h i t s_i=\Sigma_{t}\alpha_{it}h_{it} si=Σtαithit
    矩阵表示 s = Σ α ⋅ h s=\Sigma \alpha \cdot h s=Σαh, 其中 s ∈ R d × 1 s \in \mathbb{R}^{d\times 1} sRd×1。注意,先点乘,再对 T T T的维度求和!

上面的公式计算过程,通过代码的方式来表示,有以下两种方式:
代码实现1:

import tensorflow as tf

def attention(inputs):
    # inputs维度为:[B, T, D]
    hidden_size = inputs.shape[2].value
    u_omega = tf.get_variable("u_omega", [hidden_size], initializer=tf.keras.initializers.glorot_normal())  #[D, 1]

    with tf.name_scope('v'):
        v = tf.tanh(inputs) # [B, T, D]

    vu = tf.tensordot(v, u_omega, axes=1, name='vu')  #[B,T,D]*[D,1]->[B, T, 1]->[B, T]
    alphas = tf.nn.softmax(vu, name='alphas')  # (B,T) shape

    # 注意这里的点乘,是alphas的每个元素与矩阵的行相乘,reduce_sum操作的维度变化为[B, T, D]->[B,D]
    output = tf.reduce_sum(inputs * tf.expand_dims(alphas, -1), 1)

    # Final output with tanh
    output = tf.tanh(output)

    return output, alphas

代码实现2

def attention(self, H):
    """
    利用Attention机制得到句子的向量表示
    """
	# inputs维度为:[B, T, D]
    # 获得最后一层LSTM的神经元数量
    hiddenSize = config.model.hiddenSizes[-1]

    # 初始化一个权重向量,是可训练的参数,[D,1]
    W = tf.Variable(tf.random_normal([hiddenSize], stddev=0.1))

    # 对Bi-LSTM的输出用激活函数做非线性转换,[B, T, D]
    M = tf.tanh(H)

    # 维度变化过程:[B*T, D]*[D,1] -> [B*T, 1]
    newM = tf.matmul(tf.reshape(M, [-1, hiddenSize]), tf.reshape(W, [-1, 1]))

    # 对newM做维度转换成[B, T]
    restoreM = tf.reshape(newM, [-1, config.sequenceLength])

    # 用softmax做归一化处理[B, T]
    self.alpha = tf.nn.softmax(restoreM)

    # [B, D, T]*[B, T, 1] -> [B, D, 1]
    r = tf.matmul(tf.transpose(H, [0, 2, 1]), tf.reshape(self.alpha, [-1, config.sequenceLength, 1]))

    # 将三维压缩成二维sequeezeR=[B, D]
    sequeezeR = tf.reshape(r, [-1, hiddenSize])
	
    sentenceRepren = tf.tanh(sequeezeR)

    # 对Attention的输出可以做dropout处理
    output = tf.nn.dropout(sentenceRepren, self.dropoutKeepProb)

    return output

上面两种实现方法的主要区别在于,计算Attention score时,前者是点乘后再对T维度求和,后者是经过维度变化后矩阵相乘,来实现T维度求和。

注意:上面的代码里,没有进行MLP操作,直接对BiLSTM的输出做了tanh处理。

理解了BiLSTM_attention后,再去理解它与Encoder-Decoder里的Attention和Self-attention的区别就会容易很多,后续会介绍Encoder-Decoder里的Attention和Self-attention。

  • 1
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值