关于机器学习:位置编码PE是如何在Transformers中发挥作用的

7次阅读

共计 2220 个字符,预计需要花费 6 分钟才能阅读完成。

在人类的语言中,单词的程序和它们在句子中的地位是十分重要的。如果单词被从新排序后整个句子的意思就会扭转,甚至可能变得毫无意义。

Transformers 不像 LSTM 具备解决序列排序的内置机制,它将序列中的每个单词视为彼此独立。所以应用地位编码来保留无关句子中单词程序的信息。

什么是地位编码?

地位编码(Positional encoding)能够通知 Transformers 模型一个实体 / 单词在序列中的地位或地位,这样就为每个地位调配一个惟一的示意。尽管最简略的办法是应用索引值来示意地位,但这对于长序列来说,索引值会变得很大,这样就会产生很多的问题。

地位编码将每个地位 / 索引都映射到一个向量。所以地位编码层的输入是一个矩阵,其中矩阵中的每一行是序列中的编码字与其地位信息的和。

如下图所示为仅对地位信息进行编码的矩阵示例。

Transformers 中的地位编码层

假如咱们有一个长度为 L 的输出序列,并且咱们须要对象在该序列中的地位。地位编码由不同频率的正弦和余弦函数给出:

d:输入嵌入空间的维度

pos:输出序列中的单词地位,0≤pos≤L/2

i:用于映射到列索引 其中 0≤i<d/2,并且 I 的单个值还会映射到正弦和余弦函数

在下面的表达式中,咱们能够看到偶数地位对应用正弦函数,奇数地位应用 余弦函数。

从头编写地位编码矩阵

上面是一小段应用 NumPy 实现地位编码的 Python 代码。代码通过简化,便于了解地位编码。

def getPositionEncoding(seq_len,dim,n=10000):
  PE = np.zeros(shape=(seq_len,dim))
  for pos in range(seq_len):
    for i in range(int(dim/2)):
      denominator = np.power(n, 2*i/dim)
      PE[pos,2*i] = np.sin(pos/denominator)
      PE[pos,2*i+1] = np.cos(pos/denominator)

  return PE

PE = getPositionEncoding(seq_len=4, dim=4, n=100)
print(PE)

为了更好的了解地位彪马,咱们能够对其进行可视化,让咱们在更大的值上可视化地位矩阵。咱们将从 matplotlib 库中应用 Python 的 matshow() 办法。比方设置 n =10,000,失去:

因而,地位编码层将单词嵌入与序列中每个标记的地位编码矩阵相加,作为下一层的输出。这里须要留神的是地位编码矩阵的维数应该与词嵌入的维数雷同。

在 Keras 中编写本人的地位编码层

首先,让咱们编写导入所有必须库。

import tensorflow as tf
from tensorflow import convert_to_tensor, string
from tensorflow.keras.layers import TextVectorization, Embedding, Layer
from tensorflow.data import Dataset
import numpy as np

以下代码应用 Tokenizer 对象将每个文本转换为整数序列(每个整数是字典中标记的索引)。

output_sequence_length = 4
vocab_size = 10
sentences = ["How are you doing", "I am doing good"]
tokenizer = Tokenizer()
tokenizer.fit_on_texts(sentences)
tokenzied_sent = tokenizer.texts_to_sequences(sentences)
print("Vectorized words:", tokenzied_sent)

实现 transformer 模型时,必须编写本人的地位编码层。这个 Keras 示例展现了如何编写 Embedding 层子类:

class PositionEmbeddingLayer(Layer):
    def __init__(self, sequence_length, vocab_size, output_dim, **kwargs):
        super(PositionEmbeddingLayer, self).__init__(**kwargs)
        self.word_embedding_layer = Embedding(input_dim=vocab_size, output_dim=output_dim)
        self.position_embedding_layer = Embedding(input_dim=sequence_length, output_dim=output_dim)

    def call(self, inputs):        
        position_indices = tf.range(tf.shape(inputs)[-1])
        embedded_words = self.word_embedding_layer(inputs)
        embedded_indices = self.position_embedding_layer(position_indices)
        return embedded_words + embedded_indices

这样咱们的地位嵌入就实现了

https://avoid.overfit.cn/post/dc84ff7287e540b48da2eadfabd306bc

作者:Srinidhi Karjol

正文完
 0