โจทย์
Attention ไม่สนใจลำดับของคำ ดังนั้น Transformer ต้นฉบับจึงบวก การเข้ารหัสตำแหน่ง เข้ากับ embedding ของแต่ละ token สำหรับตำแหน่ง pos และมิติ j (ทั้งคู่เริ่มที่ 0) ในโมเดลขนาด d_model:
- '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 ใช้ความถี่ถัดไป และต่อไปเรื่อย ๆ
จง implement positional_encoding(length, d_model)
อินพุต
length: จำนวนตำแหน่ง (0 ถึง length - 1)
d_model: ขนาดของ embedding
เอาต์พุต
คืนค่าเมทริกซ์ขนาด length × d_model
เงื่อนไข
1 ≤ length ≤ 200, 1 ≤ d_model ≤ 128
ตัวอย่าง
อินพุต:
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]
อินพุต:
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}
};
คำอธิบาย
เมื่อมีเพียงมิติเดียว จะใช้แค่ sin(pos): [[0], [0.841471], [0.909297]]
แหล่งอ้างอิง
โจทย์นี้ปรับให้เหมาะกับ CodeUtility กรุณาทำตามคำชี้แจงและข้อจำกัดด้านบน