H

2つのニューロンでXORの学習は可能か?

 XORの学習は、ディープラーニングの学習をしたことがある人は、誰でも入門書で見たことがあるはずです。でもその多くの場合、ニューロンは3個以上使われています。

 

 今回の記事では、疑問に思ったので2つのニューロンでのXORの学習が可能か検証してみました。

 そもそも何故一つのニューロンでXORの学習が無理なのでしょうか?

 その理由は線形分離ができない事にあります。例えばANDの場合、一つの線で出力の境界を設定できます。しかしXORは二つの線が必要です。

f:id:SCUSER:20210424220523p:plain




 自分の頭の中には、下のような図がありました。

f:id:SCUSER:20210424201323p:plain

 

 上の図に従って、コードを書いてみました。

import numpy

x = numpy.array([[00], [01], [10], [11]])
t = numpy.array([0110])

eta = 0.8

y = numpy.zeros(4)

u1 = numpy.zeros(4)
u2 = numpy.zeros(4)

b1 = 0 #出力用ニューロン
b2 = 0 #入力用ニューロン

w1 = numpy.zeros(3)
w2 = numpy.zeros(2)

def f(x):
  return max*1

def Derivative(x):
  return [1 if x > 0 else 0 for i in range(1)][0]

for nyan in range(100):
  for i, e in enumerate(x):
    u2[i] = numpy.dot(e, w2) + b2
    u1[i] = numpy.dot(numpy.array([e[0], f(u2[i]), e[1]]), w1) + b1
    y[i] = f(u1[i])

    if i == 3:
      sigma = y - t
      u2 = numpy.where(u2 == 0u2 + 0.0001u2)
      sigma2 = (
          sigma * numpy.array([Derivative(u2[neko]) for neko in range(4)])
      ) * w1[1]
      nyaaan = numpy.array([Derivative(u2[neko]) for neko in range(4)])
      w1 = w1 - eta * numpy.array([
        numpy.dot(sigma, x[:, 0])/4,
        numpy.dot(sigma, nyaaan)/4,
        numpy.dot(sigma, x[:, 1])/4
      ])
      w2 = w2 - eta * numpy.array([
        numpy.dot(sigma2, x[:, nyago]) for nyago in range(2)
      ])
      b1 = b1 - eta * (numpy.sum(sigma) / 4)
      b2 = b2 - eta * (numpy.sum(sigma2) / 4)

print(y)

 

出力の結果

[0.5 0.5 0.5 0.5]

 

 ......あれ学習に失敗しましたね。何故でしょうか。

 エポック不足でしょうかね。変えて見ましょう。

  • 10エポック:[0.43826893 0.49031629 0.49031629 0.54236365]
  • 100エポック:[0.49999965 0.49999994 0.49999994 0.50000024]
  • 1000エポック:[0.5 0.5 0.5 0.5]
  • 1000000エポック:[0.5 0.5 0.5 0.5]

 ふーむ。これを見る限りエポック数が原因ではなさそうですね。

 じゃあyの変動を見てみましょう。

 import matplotlib.pyplot as pltして、新しい変数Graph_yを追加して、yをappendして、plot......

 できました!

f:id:SCUSER:20210424212915p:plain

変わってないですねぇ......

じゃあw1は......

 

f:id:SCUSER:20210424213057p:plain

変わってますねぇ。

f:id:SCUSER:20210424213225p:plain

 w2も変わってますね。つまり学習自体はしているっぽいですね。

 じゃあ3次元グラフを作ってみましょう!

 まずニューロン1というか、図で言う所の真ん中らへんのニューロンの動きを見てましょう。

f:id:SCUSER:20210424215051p:plain

 あれ、、、変化がない。と思ってたらバイアスをつけるの忘れてました。

 修正後がこれ。

f:id:SCUSER:20210424215249p:plain

 あらら。これは、、、なんの役割も果たしてませんね。

 ではニューロン2の方は?

f:id:SCUSER:20210424215413p:plain

 変化ないですね。ただし上のグラフはxのみの入力に対してです。

 ではyの入力にはどう対応するのでしょうか?

f:id:SCUSER:20210424215955p:plain

 うーん。変動しませんね。

 

 結論として、二つのニューロンでXORの学習はできないという事になりました。

 

*1:0, x