すべてのチャレンジ
中級 0件解決済み 正答率0%

正弦波による位置エンコーディング

Transformer がトークンの埋め込みに加える、sin と cos による位置ベクトルを計算します。

このチャレンジで学べること

  • サインとコサインの位置ベクトルを計算する
  • 次元ごとに異なる周波数を使う
  • Transformer が語順を知る仕組みを理解する

問題

原文(英語)を表示

アテンションは単語の順序を無視するため、元の Transformer は各トークンの埋め込みに位置エンコーディングを加えます。サイズ d_model のモデルで、位置 pos と次元 j(どちらも 0 から)について:

  • j が偶数:PE[pos][j] = sin(pos / 10000^(j / d_model))
  • j が奇数:PE[pos][j] = cos(pos / 10000^((j - 1) / d_model))

つまり次元 0 と 1 は同じ周波数、次元 2 と 3 は次の周波数、というように続きます。

positional_encoding(length, d_model) を実装してください。

入力

length: 位置の数(0 から length - 1)。

d_model: 埋め込みのサイズ。

出力

length × d_model の行列を返してください。

制約

1 ≤ length ≤ 200、1 ≤ d_model ≤ 128

例

例 1
入力:
length = 2
d_model = 4

期待される出力:
expected = [
    [0.0, 1.0, 0.0, 1.0],
    [0.841471, 0.540302, 0.01, 0.99995]
]
入力:
long long length = 2;
long long d_model = 4;

期待される出力:
std::vector<std::vector<double>> expected = {
    {0.0, 1.0, 0.0, 1.0},
    {0.841471, 0.540302, 0.01, 0.99995}
};
入力:
long length = 2;
long d_model = 4;

期待される出力:
double[][] expected = new double[][] {
    new double[] {0.0, 1.0, 0.0, 1.0},
    new double[] {0.841471, 0.540302, 0.01, 0.99995}
};

解説

位置 0 はどのペアも sin(0) = 0、cos(0) = 1 なので [0, 1, 0, 1]。位置 1 は周波数 1 と 1 / 10000^(2/4) = 0.01 を使います:[sin 1, cos 1, sin 0.01, cos 0.01] ≈ [0.841471, 0.540302, 0.01, 0.99995]。

例 2
入力:
length = 3
d_model = 1

期待される出力:
expected = [
    [0.0],
    [0.841471],
    [0.909297]
]
入力:
long long length = 3;
long long d_model = 1;

期待される出力:
std::vector<std::vector<double>> expected = {
    {0.0},
    {0.841471},
    {0.909297}
};
入力:
long length = 3;
long d_model = 1;

期待される出力:
double[][] expected = new double[][] {
    new double[] {0.0},
    new double[] {0.841471},
    new double[] {0.909297}
};

解説

次元が1つだけなので sin(pos) だけを使います:[[0], [0.841471], [0.909297]]。

参考資料

この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。

他の人の解答から学ぶ

コミュニティの解答

まだ公開された解答がありません。この課題を解いて最初の解答を共有しましょう。