Source code for xmodaler.modeling.embedding.position_embedding

# Copyright 2021 JD.com, Inc., JD AI
"""
@author: Yehao Li
@contact: yehaoli.sysu@gmail.com
"""
import math
import torch
from torch import nn

from xmodaler.utils.registry import Registry

POSITION_ENC_REGISTRY = Registry("POSITION_ENC")
POSITION_ENC_REGISTRY.__doc__ = """
Registry for positional encoding
"""

__all__ = ["SinusoidEncoding", "NNEmbeddingEncoding"]

def build_position_encoding(cfg, dim, max_len):
    name = cfg.MODEL.TOKEN_EMBED.POSITION
    return POSITION_ENC_REGISTRY.get(name)(dim, max_len)

[docs]@POSITION_ENC_REGISTRY.register() class SinusoidEncoding(nn.Module):
[docs] def __init__(self, dim, max_len): super(SinusoidEncoding, self).__init__() pe = torch.zeros(max_len, dim) position = torch.arange(0, max_len).unsqueeze(1).float() div_term = torch.exp(torch.arange(0, dim, 2).float() * -(math.log(max_len * 2.0) / dim)) pe[:, 0::2] = torch.sin(position * div_term) pe[:, 1::2] = torch.cos(position * div_term) pe = pe.unsqueeze(0) self.register_buffer('pe', pe)
[docs] def forward(self, x): if isinstance(x, int): return self.pe[:, x] else: x_size = x.size(1) return self.pe[:, :x_size]
[docs]@POSITION_ENC_REGISTRY.register() class NNEmbeddingEncoding(nn.Module):
[docs] def __init__(self, dim, max_len): super(NNEmbeddingEncoding, self).__init__() self.position_embeddings = nn.Embedding(max_len, dim)
[docs] def forward(self, x): if isinstance(x, int): position_embeddings = self.position_embeddings(torch.tensor([x], dtype=torch.long).cuda()) else: x_size = x.size(1) position_ids = torch.arange(x_size, dtype=torch.long, device=x.device) position_embeddings = self.position_embeddings(position_ids) return position_embeddings