在几篇学术论文中,研究人员使用以下位置编码来表示元素在序列中的位置,无论是基于时间序列的序列,还是用于NLP目的的句子中的单词。
我的问题是,在输入深层神经网络(在我的例子中是变压器网络)之前,定位是如何实际应用于数据的:
MultiHeadAttention
层实际上已经包含了一个负责位置编码的Embeeding
层吗?还是不呢?我感兴趣的是实际的实现细节,而不是位置编码的概念部分,因为我已经阅读了大多数关于位置编码的学术论文。不幸的是,大多数学术论文都没有详细描述在什么阶段以及如何将位置编码应用于数据结构。
谢谢!
发布于 2021-07-22 03:47:23
位置编码只是让模型区分两个元素(单词)的一种方式,它们是相同的,但在一个序列中出现在不同的位置。
例如,在LM语言模型中应用嵌入后,我们添加PE来添加关于每个单词位置的信息。
是直接添加到序列中元素的实际值(或单词表示值)中的位置值吗?还是连在一起?位置嵌入是数据预处理阶段的一部分吗?
是的,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]
,Tensorflow/Keras MultiHeadAttention层实际上已经包含了一个负责位置编码的Embeeding层吗?还是不想?
简单地说不。你得自己做体育课。
--数据的规范化又如何?是否只将实际元素值规范化,然后将位置编码添加到该规范化值中?还是将位置编码值添加到元素的原始值并将结果值规范化?
正常化部分由你自行决定。你想做什么就做什么。但你应该实行正常化。此外,PE被添加到规范化值中,而不是实际值。
https://stackoverflow.com/questions/68477306
复制相似问题