わかりやすい パターン認識

第3章 誤差評価に基づく学習

3.1 Widrow-Hoffの学習規則

[2] 閉じた形の解に引き続き、「[3] 逐次近似による解(p.36)」を例題に当てはめて解いてみる(Widrow-Hoffの学習規則)。

学習パターンと教師ベクトルは「閉じた形の解」と同じだが、列ベクトルの形式で、

とする。

パターンごとに

として を更新する(Widrow-Hoffの学習規則)。

の初期値は適当に、

として、計算してみる。

(1) パターン1に適用

以後パターン2〜6も同様に計算して一周させると、

となり、識別の値 となる。 閉じた形で求めた結果と近い値が得られている。

コード

# learn_widrow_hoff.py
# coding: UTF-8
import numpy as np

def main():
  # パターン行列
  X = np.matrix([[1., 1.2],
                 [1., 0.2],
                 [1., -0.2],
                 [1., -0.5],
                 [1., -1.0],
                 [1., -1.5]])
  # パターンごとの、クラスiに属するかどうかの教師行列
  b = np.matrix([[1., 0.],
                 [1., 0.],
                 [1., 0.],
                 [0., 1.],
                 [0., 1.],
                 [0., 1.]])

  # 識別関数のウェイトをランダムで初期化する
  W = np.matrix(np.random.random((b.shape[1], X.shape[1])))

  rho = 0.4  # 学習率
  for k in xrange(1):  # TODO: 収束するまで 
    for i in xrange(X.shape[0]):
      learn_widrow_hoff(W, X[i, :].T, b[i, :].T, rho)
  print W
  x = -(W[0, 0] - W[0, 1]) / (W[1, 0] - W[1, 1])
  print 'x=', x, 'error=', calc_error(W, X, b)

# Widrow-Hoffの学習規則でパターン1つに対して学習させる
def learn_widrow_hoff(W, xp, bp, rho):
  e = W.T * xp - bp
  W -= rho * (xp * e.T)

def calc_error(W, X, b):
  #J = 0.
  #for i in xrange(X.shape[0]):
  #  xp = X[i, :].T
  #  bp = b[i, :].T
  #  e = W.T * xp - bp
  #  J += e.T.dot(e).sum()
  e = X * W - b
  J = np.vectorize(lambda x: x * x)(e).sum()
  return J

if __name__ == '__main__':
  main()

# [[ 0.75759575  0.49664788]
#  [ 0.4370989  -0.31125436]]
# x= -0.348696099486 error= 1.29145201213