用于 Transformer DNN 模型的基于时间序列的数据的位置编码

Positional Encoding for time series based data for Transformer DNN models

在几篇学术论文中,研究人员使用以下位置编码来表示序列中元素的位置,无论是基于时间序列的序列还是用于 NLP 目的的句子中的单词。

我的问题是在将数据馈送到深度神经网络(在我的例子中是变压器网络)之前如何将定位实际应用于数据:

我对实际的实现细节感兴趣,而不是位置编码的概念部分,因为我已经阅读了大部分关于位置编码的学术论文。不幸的是,大多数学术论文都没有详细描述位置编码在什么阶段以及如何精确地应用于数据结构。

谢谢!!!

位置编码只是一种让模型区分两个相同但出现在序列中不同位置的元素(单词)的方法。

例如,在 LM - 语言模型中应用嵌入后,我们添加 PE 以添加有关每个单词位置的信息。

Are the positional values added directly to the actual values of the elements in the sequence (or to the word representation values)? Or are they concatinated? Is the positional embedding part of the data preprocessing stage?

是的 PE 值只是直接添加到实际值(LM 中的嵌入)。这将导致出现在序列开头的单词 a 的嵌入向量与出现在序列中间的相同单词的嵌入向量不同。不,PE 不是数据预处理阶段的一部分。

这是一个代码示例:

class PositionalEncodingLayer(nn.Module):
    
    def __init__(self, d_model, max_len=100):
        super(PositionalEncodingLayer, self).__init__()
        self.d_model = d_model
        self.max_len = max_len
    
    def get_angles(self, positions, indexes):
        d_model_tensor = torch.FloatTensor([[self.d_model]]).to(positions.device)
        angle_rates = torch.pow(10000, (2 * (indexes // 2)) / d_model_tensor)
        return positions / angle_rates

    def forward(self, input_sequences):
        """
        :param Tensor[batch_size, seq_len] input_sequences
        :return Tensor[batch_size, seq_len, d_model] position_encoding
        """
        positions = torch.arange(input_sequences.size(1)).unsqueeze(1).to(input_sequences.device) # [seq_len, 1]
        indexes = torch.arange(self.d_model).unsqueeze(0).to(input_sequences.device) # [1, d_model]
        angles = self.get_angles(positions, indexes) # [seq_len, d_model]
        angles[:, 0::2] = torch.sin(angles[:, 0::2]) # apply sin to even indices in the tensor; 2i
        angles[:, 1::2] = torch.cos(angles[:, 1::2]) # apply cos to odd indices in the tensor; 2i
        position_encoding = angles.unsqueeze(0).repeat(input_sequences.size(0), 1, 1) # [batch_size, seq_len, d_model]
        return position_encoding

class InputEmbeddingAndPositionalEncodingLayer(nn.Module):

    def __init__(self, vocab_size, max_len, d_model, dropout):
        super(InputEmbeddingAndPositionalEncodingLayer, self).__init__()
        self.vocab_size = vocab_size
        self.max_len = max_len
        self.d_model = d_model
        self.dropout = nn.Dropout(p=dropout)
        self.token_embedding = nn.Embedding(vocab_size, d_model)
        self.position_encoding = PositionalEncodingLayer(d_model=d_model, max_len=max_len)

    def forward(self, sequences):
        """
        :param Tensor[batch_size, seq_len] sequences
        :return Tensor[batch_size, seq_len, d_model]
        """
        token_embedded = self.token_embedding(sequences) # [batch_size, seq_len, d_model]
        position_encoded = self.position_encoding(sequences) # [batch_size, seq_len, d_model]
        return self.dropout(token_embedded) + position_encoded # [batch_size, seq_len, d_model]

Does the Tensorflow/Keras MultiHeadAttention layer actually already contain an Embeeding layer that takes care of the positional encoding? Or not?

不行,必须自己搭建PE。

What about the normalization of data? Are only the actual element values normalized and then the positional encoding is added to that normalized value? Or is the positional encoding value added to the raw value of the element and the resulting values are normalized?

规范化部分由您自行决定。你做你想做的。但是你应该应用规范化。此外,PE 添加到标准化值而不是实际值。