Đề bài
Attention không quan tâm thứ tự từ, nên Transformer gốc cộng một mã hóa vị trí vào embedding của mỗi token. Với vị trí pos và chiều j (cùng bắt đầu từ 0) trong mô hình kích thước d_model:
- j chẵn: PE[pos][j] = sin(pos / 10000^(j / d_model))
- j lẻ: PE[pos][j] = cos(pos / 10000^((j - 1) / d_model))
Như vậy chiều 0 và 1 dùng chung một tần số, chiều 2 và 3 dùng tần số tiếp theo, và cứ thế.
Hãy cài đặt positional_encoding(length, d_model).
Đầu vào
length: Số vị trí (từ 0 đến length - 1).
d_model: Kích thước embedding.
Đầu ra
Trả về ma trận kích thước length × d_model.
Ràng buộc
1 ≤ length ≤ 200, 1 ≤ d_model ≤ 128
Ví dụ
Đầu vào:
length = 2
d_model = 4
Kết quả mong đợi:
expected = [
[0.0, 1.0, 0.0, 1.0],
[0.841471, 0.540302, 0.01, 0.99995]
]
Đầu vào:
long long length = 2;
long long d_model = 4;
Kết quả mong đợi:
std::vector<std::vector<double>> expected = {
{0.0, 1.0, 0.0, 1.0},
{0.841471, 0.540302, 0.01, 0.99995}
};
Đầu vào:
long length = 2;
long d_model = 4;
Kết quả mong đợi:
double[][] expected = new double[][] {
new double[] {0.0, 1.0, 0.0, 1.0},
new double[] {0.841471, 0.540302, 0.01, 0.99995}
};
Giải thích
Vị trí 0 là sin(0) = 0 và cos(0) = 1 cho mọi cặp: [0, 1, 0, 1]. Vị trí 1 dùng tần số 1 và 1 / 10000^(2/4) = 0.01: [sin 1, cos 1, sin 0.01, cos 0.01] ≈ [0.841471, 0.540302, 0.01, 0.99995].
Đầu vào:
length = 3
d_model = 1
Kết quả mong đợi:
expected = [
[0.0],
[0.841471],
[0.909297]
]
Đầu vào:
long long length = 3;
long long d_model = 1;
Kết quả mong đợi:
std::vector<std::vector<double>> expected = {
{0.0},
{0.841471},
{0.909297}
};
Đầu vào:
long length = 3;
long d_model = 1;
Kết quả mong đợi:
double[][] expected = new double[][] {
new double[] {0.0},
new double[] {0.841471},
new double[] {0.909297}
};
Giải thích
Với một chiều thì chỉ dùng sin(pos): [[0], [0.841471], [0.909297]].
Tham khảo
Thử thách này đã được điều chỉnh cho CodeUtility. Hãy làm theo đề bài và các ràng buộc ở trên.