チャレンジ一覧に戻る
中級 0件解決済み 正答率0%

パーセプトロンの学習アルゴリズム

間違えたときだけ重みを更新する、元祖パーセプトロンを学習させます。

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

  • 間違えたときだけ重みを更新する
  • 複数エポックにわたって学習する
  • 最初のニューラルモデルの仕組みを知る

問題

原文(英語)を表示

パーセプトロン(1958年)は、人工ニューロンのための最初の学習アルゴリズムです。ステップ関数で予測し、間違いから学びます。

すべての重みとバイアスを 0 から始めます。各エポックでサンプルを順番に処理し、ラベル y(0 または 1)を持つ各サンプル x について:

  1. x · weights + bias > 0 なら予測は 1、そうでなければ 0
  2. error = y - 予測(つまり -1、0、1 のいずれか)
  3. error ≠ 0 なら:すべての i について weights[i] ← weights[i] + learning_rate × error × x[i]、そして bias ← bias + learning_rate × error

train_perceptron(samples, labels, learning_rate, epochs) を実装してください。

入力

samples: n 個の特徴量を持つ m 個のサンプル。

labels: m 個のラベル(それぞれ 0 または 1)。

learning_rate, epochs: ステップ幅とデータを何周するか。

出力

最終的な重みと、その後にバイアス(n + 1 個の数)を返してください。

制約

1 ≤ m ≤ 100、1 ≤ n ≤ 10、1 ≤ epochs ≤ 100

0 < learning_rate ≤ 1

-10 ≤ 各特徴量 ≤ 10

例

例 1
入力:
epochs = 1
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

期待される出力:
expected = [1.0, 1.0, 1.0]
入力:
long long epochs = 1;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

期待される出力:
std::vector<double> expected = {1.0, 1.0, 1.0};
入力:
long epochs = 1;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

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

解説

[0, 0]:z = 0 で予測 0、正解。[0, 1] と [1, 0]:同じく予測 0 で正解。[1, 1]:予測は 0 だがラベルは 1 なので error = 1。重みは [1, 1]、バイアスは 1 になります。結果:[1, 1, 1]。

例 2
入力:
epochs = 10
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

期待される出力:
expected = [2.0, 1.0, -2.0]
入力:
long long epochs = 10;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

期待される出力:
std::vector<double> expected = {2.0, 1.0, -2.0};
入力:
long epochs = 10;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

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

解説

10 エポック後、パーセプトロンは AND ゲートを学習しています。重み [2, 1]、バイアス -2 では、z > 0 になるのは [1, 1] だけです。

解き方のヒント

まずは自分で考えてから、ヒントを 1 つずつ開いてみましょう。

ヒント 1

各エポックでサンプルを順に処理する。前の更新が後ろの予測に影響するため。

ヒント 2

予測クラスがラベルと違うときだけ更新し、weights と bias を同時に調整する。

ヒント 3

prediction rule は厳密な sign test を使うので、スコアが0なら class 0 になる。

目安の計算量

時間 O(epochs × m × n)、追加メモリ O(n)

参考資料

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

他の人の解答から学ぶ

コミュニティの解答

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