relative position encoding快速看懂相对位置编码代码实现

先理解相对位置:
在这里插入图片描述
在这里插入图片描述
举例如果有5个token,相对位置就有9种情况。

def _generate_relative_positions_matrix(length, max_relative_position,
                                        cache=False):
  """Generates matrix of relative positions between inputs."""
  if not cache:
    range_vec = tf.range(length)
    range_mat = tf.reshape(tf.tile(range_vec, [length]), [length, length])
    distance_mat = range_mat - tf.transpose(range_mat)
  else:
    distance_mat = tf.expand_dims(tf.range(-length+1, 1, 1), 0)
  distance_mat_clipped = tf.clip_by_value(distance_mat, -max_relative_position,
                                          max_relative_position)
  # Shift values to be >= 0. Each integer still uniquely identifies a relative
  # position difference.
  final_mat = distance_mat_clipped + max_relative_position
  return final_mat  # 解释前面是如何得到相对位置的

结合具体例子快速理解前面代码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后是通过前面的相对位置矩阵,得到相对位置编码

def _generate_relative_positions_embeddings(length, depth,
                                            max_relative_position, name,
                                            cache=False):
  """Generates tensor of size [1 if cache else length, length, depth]."""
  with tf.variable_scope(name):
    relative_positions_matrix = _generate_relative_positions_matrix(
        length, max_relative_position, cache=cache)
    vocab_size = max_relative_position * 2 + 1
    # Generates embedding for each relative position of dimension depth.
    embeddings_table = tf.get_variable("embeddings", [vocab_size, depth])
    embeddings = tf.gather(embeddings_table, relative_positions_matrix)
    #tf.gather函数是TensorFlow中的一个操作,用于从一个张量中提取指定索引位置的元素。
    return embeddings

大模型解释教学,感觉讲地很清楚:
在这里插入图片描述
在这里插入图片描述

好的,我来回答您的问题。 首先,我们需要了解一下正交位置编码和相对位置编码的概念。 正交位置编码是指将位置信息编码加入到模型中,使得模型能够感知到每个位置的信息,从而提高模型的准确性和泛化能力。 相对位置编码则是在正交位置编码的基础上,考虑不同位置之间的相对距离,从而更好地捕捉序列中的长程依赖关系。 接下来,我会给您介绍如何使用PaddlePaddle实现正交位置编码和相对位置编码。 1. 正交位置编码 正交位置编码可以通过添加位置嵌入向量来实现。具体步骤如下: ```python import paddle import paddle.nn as nn class PositionalEncoding(nn.Layer): def __init__(self, d_model, max_seq_len=512): super(PositionalEncoding, self).__init__() self.d_model = d_model self.max_seq_len = max_seq_len self.pos_encoder = self._get_position_encoding(max_seq_len, d_model) def _get_position_encoding(self, max_seq_len, d_model): pos_encoder = paddle.zeros([max_seq_len, d_model]) position = paddle.arange(0, max_seq_len, dtype='float32').unsqueeze(1) div_term = paddle.exp(paddle.arange(0, d_model, 2, dtype='float32') * (-math.log(10000.0) / d_model)) pos_encoder[:, 0::2] = paddle.sin(position * div_term) pos_encoder[:, 1::2] = paddle.cos(position * div_term) return paddle.to_tensor(pos_encoder) def forward(self, x): x = x * paddle.sqrt(paddle.to_tensor(self.d_model)) x = x + self.pos_encoder[:x.shape[1], :] return x ``` 在这段代码中,我们首先定义了一个PositionalEncoding类,它继承自PaddlePaddle的nn.Layer。在构造函数中,我们定义了d_model和max_seq_len两个参数,分别表示模型的维度和最大序列长度。然后,我们调用_get_position_encoding方法生成位置编码矩阵pos_encoder。最后,在forward方法中,我们将输入x与位置编码矩阵相加,得到最终的输出。 2. 相对位置编码 相对位置编码可以通过在正交位置编码的基础上,添加相对位置编码向量来实现。具体步骤如下: ```python class RelativePositionalEncoding(nn.Layer): def __init__(self, d_model, max_seq_len=512): super(RelativePositionalEncoding, self).__init__() self.d_model = d_model self.max_seq_len = max_seq_len self.pos_encoder = self._get_position_encoding(max_seq_len, d_model) self.rel_pos_encoder = self._get_relative_position_encoding(max_seq_len, d_model) def _get_position_encoding(self, max_seq_len, d_model): pos_encoder = paddle.zeros([max_seq_len, d_model]) position = paddle.arange(0, max_seq_len, dtype='float32').unsqueeze(1) div_term = paddle.exp(paddle.arange(0, d_model, 2, dtype='float32') * (-math.log(10000.0) / d_model)) pos_encoder[:, 0::2] = paddle.sin(position * div_term) pos_encoder[:, 1::2] = paddle.cos(position * div_term) return paddle.to_tensor(pos_encoder) def _get_relative_position_encoding(self, max_seq_len, d_model): rel_pos_encoder = paddle.zeros([2 * max_seq_len - 1, d_model]) position = paddle.arange(-(max_seq_len - 1), max_seq_len, dtype='float32').unsqueeze(1) div_term = paddle.exp(paddle.arange(0, d_model, 2, dtype='float32') * (-math.log(10000.0) / d_model)) rel_pos_encoder[:, 0::2] = paddle.sin(position * div_term) rel_pos_encoder[:, 1::2] = paddle.cos(position * div_term) return paddle.to_tensor(rel_pos_encoder) def forward(self, x): x = x * paddle.sqrt(paddle.to_tensor(self.d_model)) seq_len = x.shape[1] position = paddle.arange(seq_len, dtype='float32').unsqueeze(0) position = position.repeat(seq_len, 1) rel_position = position - paddle.transpose(position, [1, 0]) rel_position = rel_position + self.max_seq_len - 1 rel_pos_encoding = paddle.index_select(self.rel_pos_encoder, index=rel_position.flatten().astype('int64'), axis=0) rel_pos_encoding = rel_pos_encoding.reshape([seq_len, seq_len, self.d_model]) rel_pos_encoding = paddle.transpose(rel_pos_encoding, [1, 0, 2]) x = x + rel_pos_encoding x = paddle.layer_norm(x, normalized_shape=[x.shape[-1]]) return x ``` 在这段代码中,我们定义了一个RelativePositionalEncoding类,它也继承自PaddlePaddle的nn.Layer。在构造函数中,我们定义了d_model和max_seq_len两个参数,同样是模型的维度和最大序列长度。然后,我们调用_get_position_encoding方法和_get_relative_position_encoding方法生成位置编码矩阵pos_encoder和相对位置编码矩阵rel_pos_encoder。在forward方法中,我们首先计算出每个位置之间的相对距离,然后根据相对距离在相对位置编码矩阵中查找对应的编码向量,并将其与输入x相加得到最终的输出。 希望这个回答能够帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值