Todos os desafios
Médio 0 resolvidos 0% de aceitação

Codificação posicional senoidal

Calcule os vetores de posição seno e cosseno que os Transformers somam aos embeddings dos tokens.

O que você vai aprender

  • Calcular vetores de posição com seno e cosseno
  • Usar frequências diferentes por dimensão
  • Entender como os Transformers sabem a ordem das palavras

Problema

Ver original (inglês)

A atenção ignora a ordem das palavras, por isso o Transformer original soma uma codificação posicional ao embedding de cada token. Para a posição pos e a dimensão j (ambas a partir de 0) em um modelo de tamanho d_model:

  • 'j par: PE[pos][j] = sin(pos / 10000^(j / d_model))'
  • 'j ímpar: PE[pos][j] = cos(pos / 10000^((j - 1) / d_model))'

Assim, as dimensões 0 e 1 compartilham uma frequência, as dimensões 2 e 3 a seguinte, e assim por diante.

Implemente positional_encoding(length, d_model).

Entrada

length: O número de posições (de 0 a length - 1).

d_model: O tamanho do embedding.

Saída

Retorne uma matriz length × d_model.

Restrições

1 ≤ length ≤ 200, 1 ≤ d_model ≤ 128

Exemplos

Exemplo 1
Entrada:
length = 2
d_model = 4

Saída esperada:
expected = [
    [0.0, 1.0, 0.0, 1.0],
    [0.841471, 0.540302, 0.01, 0.99995]
]
Entrada:
long long length = 2;
long long d_model = 4;

Saída esperada:
std::vector<std::vector<double>> expected = {
    {0.0, 1.0, 0.0, 1.0},
    {0.841471, 0.540302, 0.01, 0.99995}
};
Entrada:
long length = 2;
long d_model = 4;

Saída esperada:
double[][] expected = new double[][] {
    new double[] {0.0, 1.0, 0.0, 1.0},
    new double[] {0.841471, 0.540302, 0.01, 0.99995}
};

Explicação

A posição 0 é sin(0) = 0 e cos(0) = 1 para cada par: [0, 1, 0, 1]. A posição 1 usa as frequências 1 e 1 / 10000^(2/4) = 0.01: [sin 1, cos 1, sin 0.01, cos 0.01] ≈ [0.841471, 0.540302, 0.01, 0.99995].

Exemplo 2
Entrada:
length = 3
d_model = 1

Saída esperada:
expected = [
    [0.0],
    [0.841471],
    [0.909297]
]
Entrada:
long long length = 3;
long long d_model = 1;

Saída esperada:
std::vector<std::vector<double>> expected = {
    {0.0},
    {0.841471},
    {0.909297}
};
Entrada:
long length = 3;
long d_model = 1;

Saída esperada:
double[][] expected = new double[][] {
    new double[] {0.0},
    new double[] {0.841471},
    new double[] {0.909297}
};

Explicação

Com apenas uma dimensão, só sin(pos) é usado: [[0], [0.841471], [0.909297]].

Referências

Este desafio foi adaptado para o CodeUtility. Siga o enunciado e as restrições acima.

Aprenda com outros

Soluções da comunidade

Ainda não há soluções publicadas. Resolva este desafio para compartilhar a primeira.