Tất cả thử thách
Trung bình 0 đã giải Tỷ lệ chấp nhận 0%

Mã hóa vị trí dạng sin

Tính các vector vị trí dùng sin và cos mà Transformer cộng vào embedding của token.

Bạn sẽ học được gì

  • Tính vector vị trí sin và cos
  • Dùng tần số khác nhau cho mỗi chiều
  • Hiểu cách Transformer biết thứ tự từ

Đề bài

Xem bản gốc (English)

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ụ

Ví dụ 1
Đầ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].

Ví dụ 2
Đầ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.

Học hỏi từ người khác

Giải pháp cộng đồng

Chưa có giải pháp nào được chia sẻ. Hãy giải thử thách này để đăng giải pháp đầu tiên.