python機械学習編集中

Python Deeplearning パーセプトロン

ディープラーニング

パーセプトロン

ニューラルネットワーク(ディープラーニング)の起源となるアルゴリズム。
複数の信号を入力として受け取り、一つの信号を出力します。
パーセプトロンの信号は「流す・流さない(1か0)」の2値の値。
入力信号はニューロンに送られる際、それぞれに固有の重みが乗算されます。
ニューロンでは送られてきた信号の総和が計算され、その総和がある限界値を超えた場合にのみ1を出力します。
その限界値を閾値と呼びます。
パーセプトロンは、複数ある入力信号のそれぞれに固有の重みを持ちます。
その重みが大きければ大きいほど、その重みに対応する信号の重要性が高くなる。
パーセプトロンを使用して論理回路を表現できます。
機械学習とは、適切なパラメータをPCが自動的に決める作業であり、人が行う仕事はパーセプトロンのモデルを考え、PCに学習データを与える事。

$$ y = \begin{cases} 0 \quad (w_{1}x_{1} + w_{2}x_{2} \leqq θ)\\ 1 \quad (w_{1}x_{1} + w_{2}x_{2} > θ)\\ \end{cases} $$   \( θ\):閾値(バイアス)   \(w\):重み(連結強度)   \(x\):入力信号   \(y\):出力

論理回路

ANDゲート

論理積の論理ゲート。
2入力1出力のゲート。 2の入力が1のときだけ1を出力し、それ以外は0を出力。
言い換えると入力値の最小値を出力。 $$ \begin{array}{cc|c} x_1 & x_2 & y\\ \hline 0 & 0 & 0\\ 1 & 0 & 0\\ 0 & 1 & 0\\ 1 & 1 & 1\\ \end{array} $$

NANDゲート

否定論理積の論理ゲート。
0の入力が1つでもあれば1を出力する。
Not ANDを意味し、ANDゲートの出力を逆にしたもの。
いかなる組み合わせ論理回路もNANDゲートの組み合わせで実装できる。
$$ \begin{array}{cc|c} x_1 & x_2 & y\\ \hline 0 & 0 & 1\\ 1 & 0 & 1\\ 0 & 1 & 1\\ 1 & 1 & 0\\ \end{array} $$

ORゲート

論理和の論理ゲート。
入力信号の少なくとも1つが1であれば、出力が1になる。
言い換えると入力値の最大値を出力する。 $$ \begin{array}{cc|c} x_1 & x_2 & y\\ \hline 0 & 0 & 0\\ 1 & 0 & 1\\ 0 & 1 & 1\\ 1 & 1 & 1\\ \end{array} $$

XORゲート

排他的論理和の論理ゲート。
入力信号が片方が1の時は1を出力。 排他的とは自分以外は拒否の意味。 $$ \begin{array}{cc|c} x_1 & x_2 & y\\ \hline 0 & 0 & 0\\ 1 & 0 & 1\\ 0 & 1 & 1\\ 1 & 1 & 0\\ \end{array} $$

NORゲート

否定論理和の論理ゲート。
Not ORゲート。 全ての入力が0の場合にのみ出力が1になる。 $$ \begin{array}{cc|c} x_1 & x_2 & y\\ \hline 0 & 0 & 1\\ 1 & 0 & 0\\ 0 & 1 & 0\\ 1 & 1 & 0\\ \end{array} $$

パーセプトロンの実装

簡単な実装

In [8]:
# ANDゲートの簡単な実装
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

AND(1, 1)    
Out[8]:
1

重みとバイアスの導入

$$ y = \begin{cases} 0 \quad (w_{1}x_{1} + w_{2}x_{2} \leqq θ)\\ 1 \quad (w_{1}x_{1} + w_{2}x_{2} > θ)\\ \end{cases} $$ 上記の式の\( \quadθ= -b\quad \)として以下の式で表します。
$$ y = \begin{cases} 0 \quad (b+w_{1}x_{1}+w_{2}x_{2}\leqq 0)\\ 1 \quad (b+w_{1}x_{1}+w_{2}x_{2}>0)\\ \end{cases} $$ ここで\(\quad b \quad\)はバイアスと呼びます。
バイアスはニューロンの発火のしやすさ(出力信号が1を出力する度合い)を調整します。

重みとバイアスによる実装

In [36]:
import numpy as np
import matplotlib.pyplot as plt

ANDゲート

In [20]:
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

AND(1,1)
Out[20]:
1
In [104]:
y = -x + 1.4
x = np.array([-1, 0, 1, 2])
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('AND gate')
plt.scatter(0, 0, c="blue", marker='o', label="output:0")
plt.scatter(1, 1, c="green", marker='^', label="output:1")
plt.grid(True)
plt.scatter(0, 1,c="blue", marker='o')
plt.scatter(1, 0, c="blue", marker='o')
plt.fill_between(x, y, -2, color="#ccffff", alpha=0.3)
plt.legend(loc="upper left")
plt.plot(x, y, "r-")
plt.show()

NANDゲート

In [26]:
def NAND(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(1, 1)
Out[26]:
0
In [107]:
y = -x + 1.4
x = np.array([-1, 0, 1, 2])
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('NAND gate')
plt.scatter(0, 0, c="green", marker='^')
plt.scatter(1, 1, c="blue", marker='o', label="output:0")
plt.grid(True)
plt.scatter(0, 1,c="green", marker='^', label="output:1")
plt.scatter(1, 0, c="green", marker='^')
plt.fill_between(x, y, 4, color="#ccffff", alpha=0.3)
plt.legend(loc="upper left")
plt.plot(x, y, "r-")
plt.show()

ORゲート

In [30]:
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

OR(1, 0)
Out[30]:
1
In [108]:
y = -x +0.4
x = np.array([-1, 0, 1, 2])
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('OR gate')
plt.scatter(0, 0, c="blue", marker='o', label="output:0")
plt.scatter(1, 1, c="green", marker='^', label="output:1")
plt.grid(True)
plt.scatter(0, 1,c="green", marker='^')
plt.scatter(1, 0, c="green", marker='^')
plt.fill_between(x, y, -2, color="#ccffff", alpha=0.3)
plt.legend(loc="upper left")
plt.plot(x, y, "r-")
plt.show()

NORゲート

In [39]:
def NOR(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

NOR(0,0)
Out[39]:
1
In [112]:
y = -x +0.4
x = np.array([-1, 0, 1, 2])
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('NOR gate')
plt.scatter(1, 1, c="blue", marker='o', label="output:0")
plt.scatter(0, 0, c="green", marker='^', label="output:1")
plt.grid(True)
plt.scatter(0, 1,c="blue", marker='o')
plt.scatter(1, 0, c="blue", marker='o')
plt.fill_between(x, y, 4, color="#ccffff", alpha=0.3)
plt.legend(loc="upper left")
plt.plot(x, y, "r-")
plt.show()

パーセプトロンの限界

XORゲート

単層のパーセプトロンではXORゲートを実装できない。
下の図を1本の直線によって、出力を分類できない。 このように1本の直線で分けた領域でしか表現できないのが、パーセプトロンの限界です。
直線による領域の事を線形な領域、曲線による領域の事を非線形な領域といいます。

In [117]:
x = np.array([-1, 0, 1, 2])
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('XOR gate')
plt.scatter(0, 0, c="blue", marker='o', label="output:0")
plt.scatter(1, 1, c="blue", marker='o')
plt.grid(True)
plt.scatter(0, 1,c="green", marker='^')
plt.scatter(1, 0, c="green", marker='^', label="output:1")
plt.legend(loc="center")
plt.show()

多層パーセプトロン

層を重ねることによってXORゲートを表現できる。

既存ゲートの組み合わせ

ANDゲート、NANDゲート、ORゲートでXORゲートを作成する。
\(s_1\) = NANDゲートによる出力
\(s_2\) = ORゲートによる出力
\(y\) = ANDゲートによる出力信号
\(x_{1}、x_{2}\)入力信号 $$ \begin{array}{cc|cc|c} 第0層 & &第1層 & &第2層\\ \hline x_1 & x_2 & s_1 & s_2 & y\\ \hline 0 & 0 & 1 & 0 & 0\\ 1 & 0 & 1 & 1 & 1\\ 0 & 1 & 1 & 1 & 1\\ 1 & 1 & 0 & 1 & 0\\ \end{array} $$ 上記の多層パーセプトロンは重みを持つ層は実質2層(0層と1層の間と1層と2層の間)のため、2層のパーセプトロンと呼ぶ。

XORゲートの実装

In [121]:
def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y
XOR(0, 1)
Out[121]:
1

まとめ

  • パーセプトロンは入出力を備えたアルゴリズムである。ある入力を与えたら、決まった値が出力される。
  • パーセプトロンでは、「重み」と「バイアス」をパラメータとして設定する。
  • パーセプトロンで論理回路を表現できる。
  • XORゲートは単層のパーセプトロンでは表現できず、2層のパーセプトロンで表現できる。
  • 単層のパーセプトロンでは線形領域しか表現できないが、多層パーセプトロンは非線形領域を表現できる。

コメントを残す