AttentionMechanism类

源代码
TensorFlow函数:tf.layers.Layer
Luong-style 注意力机制有两种类型:
①standard Luong attention
Effective Approaches to Attention-based Neural Machine Translation 2015
②scaled form inspired partly by the normalized form of Bahdanau attention

1. 基 类 A t t e n t i o n M e c h a n i s m ( o b j e c t ) : \color{purple}基类 AttentionMechanism(object): AttentionMechanism(object):
存在两个函数
@ p r o p e r t y d e f        a l i g n m e n t s _ s i z e ( s e l f ) : \color{green}\begin{array}l@property&\\ def \,\,\,\,\,\,alignments\_size(self):\end{array} @propertydefalignments_size(self):
@ p r o p e r t y d e f        s t a t e _ s i z e ( s e l f ) : \color{green}\begin{array}l@property&\\ def \,\,\,\,\,\,state\_size(self):\end{array} @propertydefstate_size(self):
2. _ p r e p a r e _ m e m o r y 函 数 : \color{purple} \_prepare\_memory函数: _prepare_memory:
转换成张量,并将memory(encoder输出)中超过序列长度的屏蔽,将memory转你换成恰当的格式。( C o n v e r t   t o   t e n s o r   a n d   p o s s i b l y   m a s k   m e m o r y . \color{pink}Convert\, to\, tensor\, and \,possibly\, mask \,memory. Converttotensorandpossiblymaskmemory.)

def _prepare_memory(memory, memory_sequence_length, check_inner_dims_defined):

参数介绍:
memory: 张量, 形状为 [batch_size, max_time, ...]
memory_sequence_length: int32 类型张量,形状为[batch_size]。与输入memory对应,每行的值,代表着对应memory行中序列的长度
check_inner_dims_defined: 布尔值。 如果为真,检查上面memory参数的形状,确保除两个最外层维度外(batch_size,max_time)的所有维度都已明确定义。
Returns:
A (possibly masked), checked, new memory.
Raises:
ValueError: If check_inner_dims_defined is True and not memory.shape[2:].is_fully_defined().
此函数包含一个子函数, _ m a y b e _ m a s k ( m , s e q _ l e n _ m a s k ) \color{green}\_maybe\_mask(m, seq\_len\_mask) _maybe_mask(m,seq_len_mask)

  memory = nest.map_structure(lambda m: ops.convert_to_tensor(m, name="memory"), memory)

上述代码行的含义是,将memory中的所有元素都转换成张量
①nest.map_structure()函数:
tf.contrib.framework.nest.map_structure(func, *structure, **check_types_dict)
作用:对一个可循环结构的元素一次应用函数。返回一个与参数structure有相同参数数量的新结构。
②ops.convert_to_tensor()函数:
作用:将不同数据变成张量:比如可以让数组变成张量、也可以让列表变成张量

  if memory_sequence_length is not None:
  		memory_sequence_length = ops.convert_to_tensor(memory_sequence_length, name="memory_sequence_length")

上述代码将memory_sequence_lenght转换成张量

  if check_inner_dims_defined:
    def _check_dims(m):
      if not m.get_shape()[2:].is_fully_defined():
        raise ValueError("Expected memory %s to have fully defined inner dims, "
                         "but saw shape: %s" % (m.name, m.get_shape()))
nest.map_structure(_check_dims, memory)

如果check_inner_dims_defined为True,检查memory形状,如果任一元素没有被彻底定义,报错

  if memory_sequence_length is None:
    seq_len_mask = None
  else:
    seq_len_mask = array_ops.sequence_mask(
        memory_sequence_length,
        maxlen=array_ops.shape(nest.flatten(memory)[0])[1],
        dtype=nest.flatten(memory)[0].dtype)
    seq_len_batch_size = (
        memory_sequence_length.shape[0].value
or array_ops.shape(memory_sequence_length)[0])

上述代码,else部分,seq_len_mask是一个seq_len_batch_size × \times ×array_ops.shape(nest.flatten(memory)[0])[1]大小的张量
①sequence_mask(lenghts, maxlen=None,dtype=tf.bool,name=None)
参数:
lengths:整数张量,其所有值小于等于maxlen。
maxlen:标量整数张量,返回张量的最后维度的大小;默认值是lengths中的最大值。
dtype:结果张量的输出类型。
name:操作的名字
作用:将[batch_size]转换成[batch_size, seq_length]

  def _maybe_mask(m, seq_len_mask):
    rank = m.get_shape().ndims
    rank = rank if rank is not None else array_ops.rank(m)
    extra_ones = array_ops.ones(rank - 2, dtype=dtypes.int32)
    m_batch_size = m.shape[0].value or array_ops.shape(m)[0]
    if memory_sequence_length is not None:
      message = ("memory_sequence_length and memory tensor batch sizes do not "
                 "match.")
      with ops.control_dependencies([
          check_ops.assert_equal(
              seq_len_batch_size, m_batch_size, message=message)]):
        seq_len_mask = array_ops.reshape(
            seq_len_mask,
            array_ops.concat((array_ops.shape(seq_len_mask), extra_ones), 0))
        return m * seq_len_mask
    else:
return m

判断上一步生成的seq_len_mask中的seq_len_batch_size与memory的m_batch_size是否相等。
3.定义了一个_maybe_mask_score函数,
_ m a y b e _ m a s k _ s c o r e ( s c o r e , m e m o r y _ s e q u e n c e _ l e n g t h , s c o r e _ m a s k _ v a l u e ) \color{green}\_maybe\_mask\_score(score, memory\_sequence\_length, score\_mask\_value) _maybe_mask_score(score,memory_sequence_length,score_mask_value)

4. 类 _ B a s e A t t e n t i o n M e c h a n i s m 继 承 了 类 A t t e n t i o n M e c h a n i s m \color{red}{类\_BaseAttentionMechanism继承了类AttentionMechanism} _BaseAttentionMechanismAttentionMechanism
提供公共功能的一个AttentionMechanism基类。
通用的功能包括:

  1. 存储查询和内存层(query layers and memory layers)。
  2. 预处理和存储memory。
  def __init__(self,
               query_layer,
               memory,
               probability_fn,
               memory_sequence_length=None,
               memory_layer=None,
               check_inner_dims_defined=True,
               score_mask_value=None,
               name=None):

参数:
q u e r y _ l a y e r \color{green}query\_layer query_layer: Callable. tf.layers.Layers的实例。层深必须和memory_layer的深度一样。如果没有提供query_layerquery的形状必须和memory_layers一致。这是因为对于公式 s c o r e ( s t , h i ) =   v a T t a n h ( W a [ s t ; h i ] ) score(s_t, h_i)=\,v_a^Ttanh(W_a[s_t;h_i]) score(st,hi)=vaTtanh(Wa[st;hi])中的 W a [ s t ; h i ] ) W_a[s_t;h_i]) Wa[st;hi])部分,代码是通过两部分实现的,即query_layer层实现 s t s_t st部分,memory_layer层实现 h i h_i hi部分,所以需要两层的深度一致,可以在后面的代码中看到,两层是通过相加结合在一起的。
m e m o r y \color{green}memory memory:要查询的memory(这里的memory是RNN encoder的输出);尺寸[batch_size, max_time,...] 这 里 的 m a x _ t i m e 代 表 的 是 什 么 呢 ? 是 代 表 e n c o d e r 的 步 数 吗 \color{red}这里的max\_time代表的是什么呢?是代表encoder的步数吗 max_timeencoder
p r o b a b i l i t y _ f n \color{green}probability\_fn probability_fn: callable.将score和previous alignment转换为概率( 这 里 的 s o r e 应 该 是 e n c o d e r 输 出 和 d e c o d e r 输 出 的 对 齐 程 度 \color{red}{这里的sore应该是encoder输出和decoder输出的对齐程度} soreencoderdecoder),公式如下:probabilities = probability_fn(score, state),state代表所有的score。
m e m o r y s e q u e n c e l e n g t h ( o p t i o n a l ) \color{green}memory_sequence_length(optional) memorysequencelength(optional): memory(Encoder输出)中每条(batch entries)序列长度。如果提供,encoder输出张量行中超过各自序列长度的值,用0进行屏蔽。
m e m o r y _ l a y e r \color{green}memory\_layer memory_layer:tf.layers.Layer的实例(也可能为None)。 m e m o r y _ l a y e r 和 q u e r y _ l a y e r 的 关 系 是 什 么 ? \color{red}memory\_layer和query\_layer的关系是什么? memory_layerquery_layermemory_layer层的深度必须和query_layer的深度一致。If memory_layer is not provided, the shape of memory must match that of query_layer.
c h e c k _ i n n e r _ d i m s _ d e f i n e d \color{green}check\_inner\_dims\_defined check_inner_dims_defined:布尔值。如果为真,则核查memory参数形状,用以确保处最外面两个维度(batch_size, max_time)外其余所有维度已被完全定义。
s c o r e _ m a s k _ v a l u e \color{green}score\_mask\_value score_mask_value:(可选)The mask value for score before passing into
probability_fn. The default is -inf. Only used if
memory_sequence_length is not None.
n a m e \color{green}name name:操作的名称

def initial_alignments(self,batch_size,dtype)

  def initial_alignments(self, batch_size, dtype):
    max_time = self._alignments_size
	return _zero_state_tensors(max_time, batch_size, dtype)

为“AttentionWrapper”类创建初始对齐值(权重)。这对于使用前面的对齐来计算下一个时间步(例如monotonic attention)的对齐的注意力机制很重要。默认返回一个全零张量。
参数介绍:
batch_size: int32 标量, the batch_size.
dtype: The dtype.
Returns:
A dtype tensor shaped [batch_size, alignments_size]
(alignments_size is the values’ max_time).

def initial_state(self, batch_size, dtype)
为“AttentionWrapper”类创建初始状态值。这对于使用前面对齐的注意力机制计算下一个时间步的对齐(例如单调注意)非常重要。默认行为是返回与initial_alignments相同的输出。

  def initial_state(self, batch_size, dtype):
	return self.initial_alignments(batch_size, dtype)

参数介绍:
batch_size: int32 scalar, the batch_size.
dtype: The dtype.
Returns:
A structure of all-zero tensors with shapes as described by state_size.

5. 类 L u o n g A t t e n t i o n \color{red}类LuongAttention LuongAttention

6. 类 B a h d a n a u A t t e n t i o n \color{red}类BahdanauAttention BahdanauAttention
继承基类:_BaseAttentionMechanism
Bahdanau注意力机制共有两种形式:
Bahdanau attention: Neural Machine Traslation by Jointly Learning to Align and Translate 2015
normalized form: Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks.

在这个类之前定义了一个 _ b a h d a n a u _ s c o r e ( p r o c e s s e d _ q u e r y , k e y s , n o r m a l i z e ) : \color{purple}\_bahdanau\_score(processed\_query, keys, normalize): _bahdanau_score(processed_query,keys,normalize):函数。如果normilize为False,此函数处理如下公式:
s c o r e ( s t , h i ) =   v a T t a n h ( W a [ s t ; h i ] ) score(s_t, h_i)=\,v_a^Ttanh(W_a[s_t;h_i]) score(st,hi)=vaTtanh(Wa[st;hi])

return math_ops.reduce_sum(v * math_ops.tanh(keys + processed_query), [2])

其中,keys对应 h i h_i hi(memory)encoder的输出,形状为[batch_size, max_time, num_units]
processed_query对应 s t s_t stdecoder的隐藏状态,形状为[batch_size, num_units]
返回值的形状为[batch_size, max_time],即分数

Bahdanau注意力机制的初始化函数:

  def __init__(self,
               num_units,
               memory,
               memory_sequence_length=None,
               normalize=False,
               probability_fn=None,
               score_mask_value=None,
               dtype=None,
               name="BahdanauAttention"):

参数介绍:
num_units q u e r y    m e c h a n i s m \color{green}query\,\, mechanism querymechanism(注意力机制)的深度
memory:注意力机制的输入;通常是RNN编码器的输出。此张量的形状为:[batch_size, max_time, ...]
memory_sequence_lenght(可选):注意力输入(memory)中批处理条目的序列长度。如果给定,则对注意力输入(memory)这个张量的行进行如下处理,对于超过相应序列长度的值,行用0进行屏蔽。
normalize:布尔值。如果normalize=True,那么选择第二种形式的注意力机制
probability_fn:(可选)A callable。将分数转换成概率。对应于论文中下面的这个公式, α t , i    = a l i g n ( y t , x i ) 表示 y t 与 x i 的对齐程度                = e x p ( s c o r e ( s t − 1 , h i ) ) ∑ i ′ = 1 n e x p ( s c o r e ( s t − 1 , h i ′ ) ) 表示一些预定义对齐得分的Softmax \alpha_{t, i}\;= align(y_t, x_i)\text{表示${y_t}$与$x_i$的对齐程度} \\\;\;\;\;\;\; \,\,= \frac{exp(score(s_{t-1}, h_i))}{\sum_{i^{'} =1}^nexp(score(s_{t-1}, h_{i^{'}}))}\text{表示一些预定义对齐得分的Softmax} αt,i=align(yt,xi)表示ytxi的对齐程度=i=1nexp(score(st1,hi))exp(score(st1,hi))表示一些预定义对齐得分的Softmax默认形式为tf.nn.softmax,其他选项包括:tf.contrib.seq2seq.hardmaxtf.contrib.sparsemax.sparsemax。应用如下, probabilities = probability_fn(score),其中,probabilities代表了权重向量 α t \alpha_t αt
score_mask_value:(可选)在传递到probability_fn之前的分数掩码值。默认值是-inf。仅在memory_sequence_length不是None的情况下使用。
dtype:注意机制的查询层(query)和内存层(memory)的数据类型。默认为float32。
name:创建操作时使用的名称。
函 数 体 部 分 : \color{green}函数体部分:

    if probability_fn is None:
      probability_fn = nn_ops.softmax
    if dtype is None:
      dtype = dtypes.float32
    wrapped_probability_fn = lambda score, _: probability_fn(score)
    super(BahdanauAttention, self).__init__(
        query_layer=layers_core.Dense(
            num_units, name="query_layer", use_bias=False, dtype=dtype),
        memory_layer=layers_core.Dense(
            num_units, name="memory_layer", use_bias=False, dtype=dtype),
        memory=memory,
        probability_fn=wrapped_probability_fn,
        memory_sequence_length=memory_sequence_length,
        score_mask_value=score_mask_value,
        name=name)
    self._num_units = num_units
    self._normalize = normalize
    self._name = name

d e f     _ _ c a l l _ _ def\,\,\, \_\_call\_\_ def__call__函数实现了权重 α t \alpha_t αt的求取

def __call__(self, query, state):
    with variable_scope.variable_scope(None, "bahdanau_attention", [query]):
      processed_query = self.query_layer(query) if self.query_layer else query
      score = _bahdanau_score(processed_query, self._keys, self._normalize)
    alignments = self._probability_fn(score, state)
    next_state = alignments
    return alignments, next_state

参数介绍:
query:张量类型与 self.values 匹配,形状为[batch_size, query_depth]
state:张量类型与self.values匹配,形状为[batch_size, alignments_size]alignments_size 就是输入(memory)的 max_time
返回值:
alignments:张量类型与self.values匹配,形状为[batch_size, alignments_size]alignments_size 就是输入(memory)的 max_time

7. A t t e n t i o n W r a p p e r S t a t e \color{red}7.AttentionWrapperState 7.AttentionWrapperState
AttentionWrapperState

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值