すべてのチャレンジ
難しい 0件解決済み 正答率0%

XOR を解くニューラルネットワークを学習させる

すべてを組み合わせ、2-2-1 の sigmoid ネットワークを誤差逆伝播法で XOR を学習するまで訓練します。

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

  • 小さなネットワークを最初から最後まで学習させる
  • XOR に隠れ層が必要な理由を知る
  • 順伝播と逆伝播を組み合わせる

問題

原文(英語)を表示

XOR(排他的論理和)は、1つのニューロンでは解けないが、隠れ層を1つ持つネットワークなら解ける古典的な問題です。入力2つ、隠れニューロン2つ、出力1つで、すべて sigmoid(σ(z) = 1 / (1 + e^(-z)))のネットワークを、損失 L = (y - target)² で学習させてください。

学習データは、どのエポックでも常にこの順番で使います。

入力target
[0, 0]0
[0, 1]1
[1, 0]1
[1, 1]0

各例について:

  1. 順伝播:a_j = σ(x₁ × hidden_weights[j][0] + x₂ × hidden_weights[j][1] + hidden_biases[j])、y = σ(a₁ × output_weights[0] + a₂ × output_weights[1] + output_bias)
  2. delta_out = 2 × (y - target) × y × (1 - y)、delta_j = delta_out × output_weights[j] × a_j × (1 - a_j)。この例での更新前の重みを使います
  3. 学習率 lr ですべてのパラメータを更新:output_weights[j] -= lr × delta_out × a_j、output_bias -= lr × delta_out、hidden_weights[j][i] -= lr × delta_j × x_i、hidden_biases[j] -= lr × delta_j

train_xor(hidden_weights, hidden_biases, output_weights, output_bias, learning_rate, epochs) を実装してください。

出力

学習後、入力 [0, 0]、[0, 1]、[1, 0]、[1, 1] に対するネットワークの予測 y を、この順番で返してください。

制約

0 ≤ epochs ≤ 5,000

0 < learning_rate ≤ 5

-2 ≤ 初期の各重みとバイアス ≤ 2

例

例 1
入力:
epochs = 0
output_bias = 0.0
hidden_biases = [0.0, 0.3]
learning_rate = 1.5
hidden_weights = [
    [0.2, 0.8],
    [0.9, -0.7]
]
output_weights = [-0.6, 0.4]

期待される出力:
expected = [0.482451, 0.436972, 0.494378, 0.452729]
入力:
long long epochs = 0;
double output_bias = 0.0;
std::vector<double> hidden_biases = {0.0, 0.3};
double learning_rate = 1.5;
std::vector<std::vector<double>> hidden_weights = {
    {0.2, 0.8},
    {0.9, -0.7}
};
std::vector<double> output_weights = {-0.6, 0.4};

期待される出力:
std::vector<double> expected = {0.482451, 0.436972, 0.494378, 0.452729};
入力:
long epochs = 0;
double output_bias = 0.0;
double[] hidden_biases = new double[] {0.0, 0.3};
double learning_rate = 1.5;
double[][] hidden_weights = new double[][] {
    new double[] {0.2, 0.8},
    new double[] {0.9, -0.7}
};
double[] output_weights = new double[] {-0.6, 0.4};

期待される出力:
double[] expected = new double[] {0.482451, 0.436972, 0.494378, 0.452729};

解説

0 エポックでは何も学習しないので、結果は初期の重みでの順伝播そのもので、約 [0.482, 0.437, 0.494, 0.453] です。学習前のネットワークはどの入力にもほぼ同じ答えを返します。

例 2
入力:
epochs = 2000
output_bias = 0.0
hidden_biases = [0.0, 0.3]
learning_rate = 1.5
hidden_weights = [
    [0.2, 0.8],
    [0.9, -0.7]
]
output_weights = [-0.6, 0.4]

期待される出力:
expected = [0.015727, 0.982119, 0.985515, 0.013682]
入力:
long long epochs = 2000;
double output_bias = 0.0;
std::vector<double> hidden_biases = {0.0, 0.3};
double learning_rate = 1.5;
std::vector<std::vector<double>> hidden_weights = {
    {0.2, 0.8},
    {0.9, -0.7}
};
std::vector<double> output_weights = {-0.6, 0.4};

期待される出力:
std::vector<double> expected = {0.015727, 0.982119, 0.985515, 0.013682};
入力:
long epochs = 2000;
double output_bias = 0.0;
double[] hidden_biases = new double[] {0.0, 0.3};
double learning_rate = 1.5;
double[][] hidden_weights = new double[][] {
    new double[] {0.2, 0.8},
    new double[] {0.9, -0.7}
};
double[] output_weights = new double[] {-0.6, 0.4};

期待される出力:
double[] expected = new double[] {0.015727, 0.982119, 0.985515, 0.013682};

解説

2,000 エポック後の予測は約 [0.016, 0.982, 0.986, 0.014] です。[0, 0] と [1, 1] では低く、[0, 1] と [1, 0] では高くなっています。ネットワークは XOR を学習しました。

参考資料

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

他の人の解答から学ぶ

コミュニティの解答

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