用于 Transformer DNN 模型的基于时间序列的数据的位置编码
Positional Encoding for time series based data for Transformer DNN models
在几篇学术论文中,研究人员使用以下位置编码来表示序列中元素的位置,无论是基于时间序列的序列还是用于 NLP 目的的句子中的单词。
我的问题是在将数据馈送到深度神经网络(在我的例子中是变压器网络)之前如何将定位实际应用于数据:
- 位置值是否直接添加到序列中元素的实际值(或单词表示值)?或者它们是连接的? positional embedding部分是数据预处理阶段吗?
- Tensorflow/Keras
MultiHeadAttention
层实际上是否已经包含负责位置编码的 Embeeding
层?还是不行?
- 数据的规范化呢?是否仅对实际元素值进行归一化,然后将位置编码添加到该归一化值?或者是将位置编码值添加到元素的原始值并将结果值归一化?
我对实际的实现细节感兴趣,而不是位置编码的概念部分,因为我已经阅读了大部分关于位置编码的学术论文。不幸的是,大多数学术论文都没有详细描述位置编码在什么阶段以及如何精确地应用于数据结构。
谢谢!!!
位置编码只是一种让模型区分两个相同但出现在序列中不同位置的元素(单词)的方法。
例如,在 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 添加到标准化值而不是实际值。
在几篇学术论文中,研究人员使用以下位置编码来表示序列中元素的位置,无论是基于时间序列的序列还是用于 NLP 目的的句子中的单词。
我的问题是在将数据馈送到深度神经网络(在我的例子中是变压器网络)之前如何将定位实际应用于数据:
- 位置值是否直接添加到序列中元素的实际值(或单词表示值)?或者它们是连接的? positional embedding部分是数据预处理阶段吗?
- Tensorflow/Keras
MultiHeadAttention
层实际上是否已经包含负责位置编码的Embeeding
层?还是不行? - 数据的规范化呢?是否仅对实际元素值进行归一化,然后将位置编码添加到该归一化值?或者是将位置编码值添加到元素的原始值并将结果值归一化?
我对实际的实现细节感兴趣,而不是位置编码的概念部分,因为我已经阅读了大部分关于位置编码的学术论文。不幸的是,大多数学术论文都没有详细描述位置编码在什么阶段以及如何精确地应用于数据结构。
谢谢!!!
位置编码只是一种让模型区分两个相同但出现在序列中不同位置的元素(单词)的方法。
例如,在 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 添加到标准化值而不是实际值。