[程序员] 深度学习中位置编码的本质是不是就是一层 nn.Parameter()而已?

近日阅读 Bert 源码,读到其中所谓“可训练式”的位置编码的部分,似乎具体实现就是初始化一个可训练的,然后把它加到输入上,这就算是可训练的位置编码了。

def __init__(self): super() positional_encoding = nn.Parameter()
def forward(self, x): x += positional_encoding

我不太能确定是否就是这么简单,还是我理解错了。

另外我注意到按照经典 Bert 的实现:

BertModel( (embeddings): BertEmbeddings( (word_embeddings): Embedding(30522, 768, padding_idx=0) (position_embeddings): Embedding(512, 768) (token_type_embeddings): Embedding(2, 768) (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True) (dropout): Dropout(p=0.1, inplace=False) ) (encoder): BertEncoder( (layer): ModuleList( (0): BertLayer(...) ... (pooler): BertPooler(...)

实际上它只进行了一次 positional_embedding ,也就是在输入的时候,这是否意味着实际上所谓的能把握序列信息的也只有第一层,后面的 bert 层是无法识别位置信息的?

但是这么说的话,按照我上一个帖子的内容 https://v2ex.com/t/868398#reply5 ,bert 的输出根据设置一般有两部分,一部分是类似原始输入序列长度对应长度的数组,表示每个字经过特征提取后的消息,另一部分是一个表示全句子整体信息的层。理论上前者应该与输入是一一对应的,但是它都不能捕捉位置,这不是很矛盾吗