【Python】単純パーセプトロンの重み計算(勾配降下法・最急降下法)

この記事では、Python+NumPyで単純パーセプトロンの重みを勾配降下法(最急降下法)で計算する方法をソースコード付きで紹介します。

単純パーセプトロンの重み算出(勾配降下法・最急降下法)


単純パーセプロトンとは、0番目の入力x_0を1、重みw_0を閾値とした場合のニューロンモデルのことです。
単純パーセプトロンの重みを最急降下法で計算した場合の手順は以下の通りです。

説明
1 初期パラメータ(学習率とエポック最大数)を設定します。
2 教師データxと正解ラベルtのセットを用意します。
3 重みwの初期値を適当に決めます。
4 教師データxを単純パーセプトロンに入力します。
5 出力yと正解ラベルtを比較し、一致しなければ最急降下法で重みを更新します。
6 手順3~5をエポック最大数分だけ繰り返します。
単純パーセプトロンの原理についてはこちら
関連記事 【ニューラルネット】基本原理と単純パーセプトロンの学習計算

今回はこれをPython + NumPyで実装してみます。

ソースコード(Python3)

サンプルプログラムのソースコードです。

# -*- coding: utf-8
import numpy as np

# 活性化関数(ステップ関数)
def f(x):
    x = np.array(x)
    x[x>=0] = 1
    x[x<0] = -1
    return x

# 出力
def feed_forward(w, x):
    return f(np.dot(w, x))

# 学習
def train(w, x, t, eps):
    y = feed_forward(x, w)
    # 出力と正解が異なれば重み更新
    if(t != y):
        w += eps * t * x
    return w


def main():
    # パラメータ
    eps = 0.1 # 学習率
    max_epoch = 100 # エポック最大数(計算回数の最大値)

    # 教師データ
    X = np.array([[1,0,0], [1,0,1], [1,1,0], [1,1,1]], dtype=np.float32) # 入力
    t = np.array([-1,-1,-1,1], dtype=np.float32) # 正解ラベル

    # 重みの初期化(適当な値をセット)
    w  = np.array([0,0,0], dtype=np.float32)

    # 単純パーセプトロンで学習
    for e in range(max_epoch):
        # 学習
        for i in range(t.size):
            w = train(w, X[i], t[i], eps)

    # 検証
    y = f(np.sum(w*X, 1))
    print("出力:", y)
    print("正解:", t)
    print("重み:", w)

if __name__ == "__main__":
    main()

教師データ

x_0 x_1 x_2 t
1 0 0 -1(不正解)
1 0 1 -1(不正解)
1 1 0 -1(不正解)
1 1 1 1(正解)

AND演算(x_1*x_2)を学習させます。
x_0はバイアス項なので全て1

実行結果

サンプルプログラムの実行結果です。

出力: [-1. -1. -1.  1.]
正解: [-1. -1. -1.  1.]
重み: [-0.2  0.2         0.1       ]
- 関連記事
1 【Python】機械学習プログラミング入門
2 【機械学習入門】アルゴリズム&プログラミング
3 【Python入門】サンプル集
4 【NumPy入門】サンプル集
関連記事