読者です 読者をやめる 読者になる 読者になる

新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。気づけば社会人3年目に突入。

学習記録:ゼロから作るDeepLearning

参考文献

2章:パーセプトロン

パーセプトロンとは

複数の信号を入力として受取,ひとつの信号を出力するアルゴリズム
パーセプトロンの信号は流すか流さないか(1/0)の二値の値をとる。
入力信号(xi)には重み(wi)が乗算され,信号の総和が閾値(θ)を超えると出力(y)が1になる(=ニューロンが発火する)。

単純な論理回路

ANDゲートは,二つの入力値x1とx2を持ち,両方が1のときだけ出力も1となる。
このANDゲートをパーセプトロンで表現しようとすると,これを満たすw1, w2, θの値を決める必要がある。
この値の組み合わせは無限にあり,例えば(0.5, 0.5, 0.7)などがANDゲートの条件を満たす。

同様に,NANDゲートは(-0.5,-0.5,-0.7),ORゲートは(0.5,0.5,0.2)などで表現できる。

パーセプトロンの実装

先の論理回路Pythonで実装すると以下のようになる。

def AND(x1, x2):
    w1, w2, theta = 0.5, 0.5, 0.7
    tmp = x1*w1 + x2*w2
    if tmp <= theta:
        return 0
    else:
        return 1

print(AND(0,0))
print(AND(1,0))
print(AND(0,1))
print(AND(1,1))

このプログラムの出力は以下になり,想定どおりの結果になっていることがわかる。

% python AND.py
0
0
0
1

この実装は素直でわかりやすいが,以降のことを考えて,重みとバイアスによる実装方法に変更する。
閾値θを-bとして表すと,b + wi*xiの和が0以下なら出力は1に,0より大きければ出力は1になる。
このbをバイアスと呼び,これを使うと実装は以下のようになる。

import numpy as np

def AND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.7
    tmp = np.sum(x*w) + b
    if tmp <= 0:
        return 0
    else:
        return 1

def NAND(x1, x2):
    x = np.array([x1, x2])
    w = np.array([-0.5, -0.5])
    b = 0.7
    tmp = np.sum(x*w) + b
    if tmp <= 0:
        return 0
    else:
        return 1

def OR(x1, x2):
    x = np.array([x1, x2])
    w = np.array([0.5, 0.5])
    b = -0.2
    tmp = np.sum(x*w) + b
    if tmp <= 0:
        return 0
    else:
        return 1

ここで,同時にORゲートも実装したが,ANDとの違いは重みとバイアス部分だけであることがわかる。

では,XORゲートはどのように実装すればよいか?
XORゲートではx1かx2のどちらかだけが1のときだけ出力が1になるが,考えてみるとどのような重み・バイアスを設定してもこれを実装できないことがわかる。
一見するとパーセプトロンではXORゲートを表現できないように思えるが,層を重ねることでこれを実現できる。

多層パーセプトロン

XORゲートを作る方法の一つに,これまで作ってきたゲートを組み合わせる方法がある。
NANDとORを前段におき,それぞれの出力をANDゲートに繋ぐことでXORゲートが実現できる。

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

print(XOR(0, 0))
print(XOR(1, 0))
print(XOR(0, 1))
print(XOR(1, 1))

このように複数の層を重ねたパーセプトロンと多層パーセプトロンと呼び,今回のXORゲートは2層のパーセプトロンとなる。