マルチヘッドアテンションにより、Transformer は複数のことに同時に注目できます。入力 X(n トークン × d 列)と d × d の重み行列について:
- Q = X × w_q、K = X × w_k、V = X × w_v
- d 列を
num_heads個のヘッドに分けます。各ヘッドは連続する d_k = d / num_heads 列を持ちます(ヘッド h は列 h×d_k から (h+1)×d_k - 1 を使う)。 - 各ヘッドで、その列だけを使ってスケールド・ドット積アテンションを実行します。トークン i について、そのヘッドの列で score_j = (Q_i · K_j) / √d_k を計算し、n 個すべてのトークン j でソフトマックスをとり、出力 = Σ weight_j × V_j(そのヘッドの列)。
- 各ヘッドの出力を元の列に戻し(連結し)、w_o を掛けます。
multi_head_attention(x, w_q, w_k, w_v, w_o, num_heads) を実装してください。
入力
x: n × d の入力行列。
w_q, w_k, w_v, w_o: d × d の重み行列。
num_heads: ヘッドの数(d はこの数で割り切れる)。
出力
n × d の出力行列を返してください。
制約
1 ≤ n ≤ 30、1 ≤ d ≤ 32、1 ≤ num_heads ≤ d で、d は num_heads で割り切れる
-5 ≤ 各値 ≤ 5
例
入力:
x = [
[1.0, 0.0],
[0.0, 1.0]
]
w_q = [
[0.0, 0.0],
[0.0, 0.0]
]
w_k = [
[1.0, 0.0],
[0.0, 1.0]
]
w_v = [
[1.0, 0.0],
[0.0, 1.0]
]
w_o = [
[1.0, 0.0],
[0.0, 1.0]
]
num_heads = 1
期待される出力:
[
[0.5, 0.5],
[0.5, 0.5]
]
解説
w_q がすべて 0 なので、スコアはすべて 0 となり、各トークンは値の行の平均になります。V = X なので、両方の行が [0.5, 0.5] になります。
入力:
x = [
[2.0, 4.0]
]
w_q = [
[1.0, 0.0],
[0.0, 1.0]
]
w_k = [
[1.0, 0.0],
[0.0, 1.0]
]
w_v = [
[1.0, 0.0],
[0.0, 1.0]
]
w_o = [
[0.0, 1.0],
[1.0, 0.0]
]
num_heads = 2
期待される出力:
[
[4.0, 2.0]
]
解説
トークンが1つだけなので各ヘッドは自分自身だけに注目し、連結した出力は V = [2, 4] です。w_o が2つの列を入れ替えるので [4, 2] になります。
参考資料
-
例 1 未実行入力:
x = [ [1.0, 0.0], [0.0, 1.0] ] w_q = [ [0.0, 0.0], [0.0, 0.0] ] w_k = [ [1.0, 0.0], [0.0, 1.0] ] w_v = [ [1.0, 0.0], [0.0, 1.0] ] w_o = [ [1.0, 0.0], [0.0, 1.0] ] num_heads = 1期待される出力:[ [0.5, 0.5], [0.5, 0.5] ]あなたの出力 -
例 2 未実行入力:
x = [ [2.0, 4.0] ] w_q = [ [1.0, 0.0], [0.0, 1.0] ] w_k = [ [1.0, 0.0], [0.0, 1.0] ] w_v = [ [1.0, 0.0], [0.0, 1.0] ] w_o = [ [0.0, 1.0], [1.0, 0.0] ] num_heads = 2期待される出力:[ [4.0, 2.0] ]あなたの出力
提出時に非公開テスト4件も実行されます。 失敗したテストがあれば、そのテストが表示されます。チャレンジを解くとすべて見られます。
Online JavaScript Runner
Write, run, and debug JavaScript or Node.js online in a full-featured browser IDE. Work with multiple files and packages, save your workspace, and collaborate in real time.
⚡ この JavaScript(Node.js)オンライン実行ツールについて
CodeUtility JavaScript Executor は、ブラウザ上で最新の JavaScript コードを、 セットアップ不要ですぐに実行できるツールです。実際の Node.js 環境でサンドボックス化されたコンテナ内にて安全に実行し、 16、18、20 の各バージョンに対応しています。
Node.js のスニペットのテスト、ES6+ 構文の確認、ループ・関数・配列・Promise・async/await といった JavaScript の基本概念の学習に最適です。
アルゴリズムの検証や小さなスクリプトのデバッグ、実行時ロジックの試行にも使えます。ローカルに Node をインストールせずに済むので、 学習者、バックエンド開発者、ブラウザだけで素早く JavaScript を実行したい方にぴったりです。
同じ実行環境で、複数ファイル対応エディター、分離された実行ターミナル、ランタイム別ライブラリ、永続ワークスペース、共有、リアルタイム共同作業を利用できます。
この実行環境の使い方
ランタイムを選択し、ファイルを開くか作成してコードを記述し、[実行]を選択します。出力はターミナルに表示されます。サインインしたユーザーは、ワークスペースにファイルを保存し、ライブラリをインストールして、共有を通じて共同作業できます。
- バージョンを選択して現在のファイルを編集するか、ワークスペース内の別のファイルを開きます。
- コードを実行し、求められた場合はターミナルに入力して、保存された実行履歴を確認します。
- 複数のコードスニペットが必要な作業では、ライブラリ、ワークスペースツール、共有、チャットを利用します。
💡 初心者向け Node.js 基本ガイド
1. 変数と定数の宣言
let または const はブロックスコープの変数用です。const は定数に使います。
let x = 10;
const PI = 3.14;
let name = "Alice";
let isActive = true;
2. 条件分岐(if / switch)
制御フローには if、else if、else、switch を使います。
let x = 2;
if (x === 1) {
console.log("1");
} else if (x === 2) {
console.log("2");
} else {
console.log("その他");
}
switch (x) {
case 1:
console.log("1");
break;
case 2:
console.log("2");
break;
default:
console.log("その他");
}
3. ループ
データの反復処理には for、while、forEach を使います。
for (let i = 0; i < 3; i++) {
console.log(i);
}
let n = 3;
while (n > 0) {
console.log(n);
n--;
}
4. 配列
配列は順序付きの値のリストを保持します。インデックスでアクセスします。
let fruits = ["apple", "banana", "cherry"];
console.log(fruits[0]);
console.log(fruits.length);
5. 配列操作
push、pop、slice、reverse などのメソッドを使います。
fruits.push("kiwi");
fruits.pop();
console.log(fruits.slice(0, 2));
console.log(fruits.reverse());
let squares = [1, 2, 3, 4, 5].map(x => x * x);
console.log(squares);
6. コンソール入出力
出力には console.log を、入力には readline モジュールを使います。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("お名前は? ", name => {
console.log(`こんにちは、${name}`);
rl.close();
});
7. 関数
関数は宣言または関数式で定義できます。モダンな JavaScript ではアロー関数がよく使われます。
function greet(name) {
return `こんにちは、${name}`;
}
const add = (a, b) => a + b;
console.log(greet("Alice"));
console.log(add(2, 3));
8. オブジェクト(マップ)
オブジェクトはキーと値の組を保持します。辞書やマップに似ています。
let person = { name: "Bob", age: 25 };
console.log(person.name);
console.log(person["age"]);
// ES6 の Map
const map = new Map();
map.set("a", 1);
console.log(map.get("a"));
9. 例外処理
try、catch、finally を使って安全にエラー処理します。
try {
throw new Error("問題が発生しました");
} catch (e) {
console.log(e.message);
} finally {
console.log("必要なら後処理");
}
10. ファイル入出力
Node.js の fs モジュールでファイルの読み書きを行います。
const fs = require("fs");
fs.writeFileSync("test.txt", "Hello File");
const data = fs.readFileSync("test.txt", "utf8");
console.log(data);
11. 文字列操作
trim()、toUpperCase()、replace()、split() などを使います。
let text = " Hello World ";
console.log(text.trim());
console.log(text.toUpperCase());
console.log(text.replace("Hello", "Hi"));
console.log(text.split(" "));
12. クラスとオブジェクト
ES6+ は class 構文で OOP をサポートします。
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `こんにちは、私は ${this.name} です`;
}
}
const p = new Person("Alice");
console.log(p.greet());
13. 参照
JavaScript のオブジェクトや配列は参照で渡されます。
function update(arr) {
arr.push("changed");
}
let data = ["original"];
update(data);
console.log(data); // ["original", "changed"] になる