単純パーセプトロンで、ANDゲート・NANDゲート・ORゲート・XORゲートを実装する。ただし、XORゲートは単層では実装できない。非線形領域は単純パーセプトロンで分離できないからだ。そこで、他の3種を組み合わせることで、XORゲートも実装する。
入力([x1, x2])は、
import numpy as np X = np.array([ [0, 0], [1, 0], [0, 1], [1, 1] ])
の4通りで、1が真(信号を流す)、0が偽(信号を流さない)に対応している。
出力(y)は、ANDゲートであれば、[x1, x2] = [1, 1]の場合のみ1で、その他は0になる。つまり、
Y = np.array([ 0, 0, 0, 1 ])
となる。
NANDゲートであれば、[1, 1]の場合のみ0で、その他は1になる。
Y = np.array([ 1, 1, 1, 0 ])
ORゲートであれば、[0, 0]の場合のみ0で、その他は1になる。
Y = np.array([ 0, 1, 1, 1 ])
XORゲートであれば、[1, 0], [0, 1]の場合に1で、その他は0になる。
Y = np.array([ 0, 1, 1, 0 ])
さて、単純パーセプトロンは、入力の加重総和にヘヴィサイドステップ関数を適用して出力する。
一般的には、出力層以外の層にバイアスニューロンをつけ加える。バイアスニューロンは、常に1を出力する特別なタイプのニューロンだ。これと次の層の接続部に与えられる重みのことをバイアスという。バイアス(b)は、ニューロンの発火のしやすさをコントロールし、その他の重み(w1, w2)は、各信号の重要性をコントロールする。
パラメータ(バイアスと重み)を適切に設定することで、AND・NAND・ORは実現できる。適切なパラメータの組み合わせは無限にある。
そして、XORゲートは、以下のような配線で実現できる。
Logic Gates by Perceptron¶
In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
def heaviside_step(z):
return np.where(z < 0, 0, 1)
In [3]:
x = np.arange(-5.0, 5.0, 0.1)
y = heaviside_step(x)
In [4]:
plt.plot(x, y)
plt.ylim(-0.1, 1.1)
plt.show()
In [5]:
class Perceptron:
def __init__(self, weights):
self.weights = weights
def output(self, input):
return self.__activate(np.dot(input, self.weights[1:]) + self.weights[0])
def __activate(self, weighted_sum):
return self.__heaviside_step(weighted_sum)
def __heaviside_step(self, z):
return np.where(z < 0, 0, 1)
In [6]:
X = np.array([
[0, 0],
[1, 0],
[0, 1],
[1, 1]
])
In [7]:
and_gate = Perceptron(np.array([-0.7, 0.5, 0.5]))
out = and_gate.output(X)
out
Out[7]:
In [8]:
nand_gate = Perceptron(np.array([0.7, -0.5, -0.5]))
out = nand_gate.output(X)
out
Out[8]:
In [9]:
or_gate = Perceptron(np.array([-0.3, 0.5, 0.5]))
out = or_gate.output(X)
out
Out[9]:
In [10]:
class XOR:
def __init__(self):
self.and_gate = Perceptron(np.array([-0.7, 0.5, 0.5]))
self.nand_gate = Perceptron(np.array([0.7, -0.5, -0.5]))
self.or_gate = Perceptron(np.array([-0.3, 0.5, 0.5]))
def output(self, input):
nand_output = self.nand_gate.output(input)
or_output = self.or_gate.output(input)
and_input = np.vstack([nand_output, or_output]).T
return self.and_gate.output(and_input)
In [11]:
xor_gate = XOR()
out = xor_gate.output(X)
out
Out[11]:
ソースコード