中級 0件解決済み 正答率0%

レイヤー正規化

各行を平均 0、分散 1 に正規化してからスケーリングとシフトを行います。すべての Transformer ブロックで使われます。

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

  • 各行を平均 0、分散 1 に正規化する
  • gamma と beta でスケールとシフトを行う
  • epsilon が必要な理由を理解する

問題

原文(英語)を表示

レイヤー正規化は、各トークンの活性値を安定したスケールに保ちます。行列の各行 x について:

  1. mean = Σ x / d、var = Σ (x - mean)² / d(行の d 個の値に対する母分散)
  2. x̂ = (x - mean) / √(var + epsilon)
  3. 出力 = gamma × x̂ + beta(要素ごと:列 j は gamma[j] と beta[j] を使う)

layer_norm(x, gamma, beta, epsilon) を実装してください。

入力

x: トークンごとに1行、d 列の行列。

gamma, beta: 学習されたスケールとシフト、それぞれ d 個の値。

epsilon: ゼロ除算を避けるための小さな数。

出力

x と同じ形の正規化された行列を返してください。

制約

1 ≤ 行数 ≤ 100、1 ≤ d ≤ 128

-100 ≤ 各値 ≤ 100、0 < epsilon ≤ 0.001

例

例 1
入力:
x = [
    [1.0, 2.0, 3.0]
]
beta = [0.0, 0.0, 0.0]
gamma = [1.0, 1.0, 1.0]
epsilon = 1.0e-05

期待される出力:
expected = [
    [-1.224736, 0.0, 1.224736]
]
入力:
std::vector<std::vector<double>> x = {
    {1.0, 2.0, 3.0}
};
std::vector<double> beta = {0.0, 0.0, 0.0};
std::vector<double> gamma = {1.0, 1.0, 1.0};
double epsilon = 1.0e-05;

期待される出力:
std::vector<std::vector<double>> expected = {
    {-1.224736, 0.0, 1.224736}
};
入力:
double[][] x = new double[][] {
    new double[] {1.0, 2.0, 3.0}
};
double[] beta = new double[] {0.0, 0.0, 0.0};
double[] gamma = new double[] {1.0, 1.0, 1.0};
double epsilon = 1.0e-05;

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

解説

mean = 2、var = (1 + 0 + 1) / 3 ≈ 0.666667 なので、√(var + epsilon) ≈ 0.816503。行は約 [-1.224736, 0, 1.224736] になり、中心が 0、分散が 1 になります。

例 2
入力:
x = [
    [5.0, 5.0]
]
beta = [1.0, -1.0]
gamma = [2.0, 3.0]
epsilon = 1.0e-05

期待される出力:
expected = [
    [1.0, -1.0]
]
入力:
std::vector<std::vector<double>> x = {
    {5.0, 5.0}
};
std::vector<double> beta = {1.0, -1.0};
std::vector<double> gamma = {2.0, 3.0};
double epsilon = 1.0e-05;

期待される出力:
std::vector<std::vector<double>> expected = {
    {1.0, -1.0}
};
入力:
double[][] x = new double[][] {
    new double[] {5.0, 5.0}
};
double[] beta = new double[] {1.0, -1.0};
double[] gamma = new double[] {2.0, 3.0};
double epsilon = 1.0e-05;

期待される出力:
double[][] expected = new double[][] {
    new double[] {1.0, -1.0}
};

解説

2つの値はどちらも平均と等しいので x̂ = [0, 0] となり、出力は beta そのもの [1, -1] です。epsilon がゼロ除算を防ぎます。

参考資料

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

他の人の解答から学ぶ

コミュニティの解答

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