-Deep Learning- パーセプトロンの実装

まずは,以下にANDゲートの実装例を以下に示します.

 
# Definition of Class
# AND Gate
def AND(x1, x2):
    w1, w2, theta = 0.5, 0.5, 0.7
    tmp = x1 * w1 + x2 * w2
    if tmp <= theta: 
        return 0
    elif tmp > theta: 
        return 1
 
# Execution part
print(AND(0, 0))    # Output 0
print(AND(1, 0))    # Output 0
print(AND(0, 1))    # Output 0
print(AND(1, 1))    # Output 1
 
上記の例では,引数として x1, x2を受け取る AND という関数を定義しています.
実行結果は以下のようになります.
0
0
0
1
 
上記の AND ゲートの実装を別の方法に修正していきます.
AND ゲートでは下式を実装しています.
 
 
この θ -b として,次式で表します(表記を変えただけで同じ意味).
 
 
ここで,b をバイアスと呼び,w1, w2を重みと呼びます.パーセプトロンでは,入力信号に重みが乗算された値とバイアスの和が計算され,その値が 0 を上回れば 1 を出力し,そうでなければ 0 を出力します.
 
以下に,NumPy を使って実装してみます.
 
# Import Module
import numpy as np
 
x = np.array([0, 1])        # input
w = np.array([0.5, 0.5])    # Weight
b = -0.7                    # bias
 
# Execution part
print(w * x)
print(np.sum(w * x))
print(np.sum(w * x) + b)
 
これを実行すると以下のようになります.
[0.  0.5]
0.5
-0.19999999999999996
 
ここで示したように,NumPy 配列の乗算では,2つの配列の要素数が同じ場合,その要素同士が乗算されます.w * x の計算では,各要素の乗算が計算されます.np.sum(w*x) では各要素の総和が計算されます.この重み付き和にバイアスを加算すれば,計算は終了します.


重みとバイアスによる方法を用いれば,AND ゲートは以下のように実装することができます.

 
# Import Module
import numpy as np
 
# Definition of Class
# AND Gate
def AND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.7
    tmp = np.sum(w * x) + b
 
    if tmp <= 0
        return 0
    else:
        return 1
 
# Execution part
print(AND(0, 0))    # Output 0
print(AND(1, 0))    # Output 0
print(AND(0, 1))    # Output 0

 

print(AND(1, 1))    # Output 1
 
実行結果は以下のようになります.
0
0
0
1
 
バイアスは,重みのw1wとは別の働きをします.具体的には,w1wは入力信号への重要度をコントロールするパラメータとして機能しますが,バイアスは発火のしやすさ(出力信号が 1 を出力する度合い)を調整するパラメータとして機能します.
 
上記のプログラムにNANDゲートとORゲートを付け加えた実装例を以下に示します.
 
# Import Module
import numpy as np
 
# Definition of Class
# AND Gate
def AND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.7
    tmp = np.sum(w * x) + b
 
    if tmp <= 0
        return 0
    else:
        return 1
 
# NAND Gate
def NAND(x1, x2):       # Only weights and bias are different from AND Gate
    x = np.array([x1, x2])
    w = np.array([-0.5, -0.5])
    b = 0.7
    tmp = np.sum(w * x) + b
 
    if tmp <= 0
        return 0
    else:
        return 1
 
# OR Gate           # Only weights and bias are different from AND Gate
def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.2
    tmp = np.sum(w * x) + b
 
    if tmp <= 0
        return 0
    else:
        return 1
 
# Execution part
print ('AND Gate')
print(AND(0, 0))    # Output 0
print(AND(1, 0))    # Output 0
print(AND(0, 1))    # Output 0
print(AND(1, 1))    # Output 1
 
print ('NAND Gate')
print(NAND(0, 0))    # Output 1
print(NAND(1, 0))    # Output 1
print(NAND(0, 1))    # Output 1
print(NAND(1, 1))    # Output 0
 
print ('OR Gate')
print(OR(0, 0))     # Output 0
print(OR(1, 0))     # Output 1
print(OR(0, 1))     # Output 1
print(OR(1, 1))     # Output 1
 
実行結果は以下のようになります.
AND Gate
0
0
0
1
NAND Gate
1
1
1
0
OR Gate
0
1
1
1

さらに,XORゲートを追加するには,NANDゲート,ORゲート,およびANDゲートを活用して,以下を追加します.
 
# XOR Gate
def XOR(x1, x2): 
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y  = AND(s1, s2)

    return y
 
print ('XOR Gate')
print(XOR(0, 0))    # Output 0
print(XOR(1, 0))    # Output 1
print(XOR(0, 1))    # Output 1
print(XOR(1, 1))    # Output 0
 
これを実行すると,以下のようになります.
XOR Gate
0
1
1
0