SIGMA-SE Math & Tech Library

SIGMA-SE Math & Tech Library


数学と情報技術をテーマに、書籍や教材だけではつかみにくい考え方を具体例とともに簡潔にわかりやすく伝える解説サイトです。
技術の歴史や背景、関連知識の整理、学習のための覚書や要約記事も掲載しています。

Python - ニューラルネットワーク:1/14 単純パーセプトロンの仕組みと実装

概要

単純パーセプトロンの考え方を、論理回路の例とPython実装を通して整理する。

パーセプトロンは、入力に重みを掛けて合計し、しきい値を超えるかどうかで出力を決める単純なモデルとなる。

ここではAND、NAND、ORのような論理回路を例に、重み、バイアス、発火という考え方を確認する。

この記事の構成

概念の説明と実装サンプル

パーセプトロンとは

  • パーセプトロンの概要

    1943年にマカロックとピッツが形式ニューロンを提案し、その考え方を発展させてフランク・ローゼンブラットが1950年代にパーセプトロンを提案した。
    ※ 形式ニューロンとは、脳神経細胞(ニューロン)をモデル化したニューロンのことを指す。

    パーセプトロンは、ニューラルネットワークやディープラーニングなどAI分野の礎になっており、これらを理解する上では必要不可欠な概念となる。

    パーセプトロンには、入力層出力層のみの2層からなる単純パーセプトロンと、多層からなる多層パーセプトロンがある。ここでは、単純パーセプトロンの動作を実装サンプルで確認する。

単純パーセプトロンの動作原理

  • 入力・重み・閾値の関係

    入力信号が2つである場合を例にすると、入力信号 \(x_{1}\), \(x_{2}\) と重み \(w_{1}\), \(w_{2}\) があった時、それぞれを乗算した合計 \(x_{1}w_{1} + x_{2}w_{2}\) が閾値 \(\theta\) 以下である場合、出力信号 \(y\) を \(0\) で出力し、閾値 \(\theta\) より大きければ、出力信号 \(y\) を\(1\) で出力する。
    ※ 閾値 \(\theta\) を超え、\(y = 1\) となるとき「ニューロンが発火する」と表現することもある。

    これが単純パーセプトロンの動作原理で下記は、上記の説明を数式で表したもの。

    \[ {\small y = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + x_{2}w_{2} \leqq \theta\\ 1 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + x_{2}w_{2} > \theta \end{cases}\hspace{5mm}・・・(A) } \]

    そして、上記\((A)\)の入力信号を \(n\) 個とし、一般化すると

    \[ y = {\small \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + … + x_{n}w_{n}\leqq \theta\\ 1 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + … + x_{n}w_{n} > \theta \end{cases}\hspace{5mm}・・・(B) } \]

    さらにまとめて

    \[ {\small y = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}\sum_{i=1}^{n} x_{i}w_{i} \leqq \theta\\ 1 \hspace{5pt}\text{if}\hspace{5pt}\sum_{i=1}^{n} x_{i}w_{i} > \theta \end{cases}\hspace{5mm}・・・(C) } \]

    となり上記\((C)\)のように表すことができる。

単純パーセプトロンを論理回路表現

  • 論理ゲートによる表現

    上記数式\((A)\)の入力信号が2つある単純パーセプトロンをANDゲート、NANDゲート、ORゲートで表現し、Pythonの実装サンプルを用いてそれぞれ説明する。

    • 1. ANDゲートの単純パーセプトロンサンプル

      • ANDゲート真理値表
        \(x_{1}\) \(x_{2}\) \(y\)
        0 0 0
        1 0 0
        0 1 0
        1 1 1
      • Pythonサンプル
        上記のANDゲートを満たすパラメータとなるように \(w_{1}, w_{2}, \theta\) を \((w_{1}, w_{2}, \theta)\) \(= (0.5, 0.5, 0.9)\) と置いて、Pythonで表現してみる。
        $ python
        >>> def AND(x1, x2):
        ...     w1, w2, theta = 0.5, 0.5, 0.9
        ...     y = x1*w1 + x2*w2
        ...     if y <= theta:
        ...         return 0
        ...     elif y > theta:
        ...         return 1
        ...
        >>> AND(0, 0)    # ANDゲートのパラメータ x1 = 0, x2 = 0 ⇒ y = 0
        0
        >>> AND(1, 0)    # ANDゲートのパラメータ x1 = 1, x2 = 0 ⇒ y = 0
        0
        >>> AND(0, 1)    # ANDゲートのパラメータ x1 = 0, x2 = 1 ⇒ y = 0
        0
        >>> AND(1, 1)    # ANDゲートのパラメータ x1 = 1, x2 = 1 ⇒ y = 1
        1
        >>>
        
    • 2. NANDゲートの単純パーセプトロンサンプル

      • NANDゲート真理値表
        \(x_{1}\) \(x_{2}\) \(y\)
        0 0 1
        1 0 1
        0 1 1
        1 1 0
      • Pythonサンプル
        上記 1. と同様に上記のNANDゲートを満たすパラメータ \(w_{1}, w_{2}, \theta\) を \((w_{1}, w_{2}, \theta)\) \(= (-0.5, -0.5, -0.9)\) と置いて、Pythonで表現したもの。
        $ python
        >>> def NAND(x1, x2):
        ...     w1, w2, theta = -0.5, -0.5, -0.9
        ...     y = x1*w1 + x2*w2
        ...     if y <= theta:
        ...         return 0
        ...     elif y > theta:
        ...         return 1
        ...
        >>> NAND(0, 0)    # NANDゲートのパラメータ x1 = 0, x2 = 0 ⇒ y = 1
        1
        >>> NAND(1, 0)    # NANDゲートのパラメータ x1 = 1, x2 = 0 ⇒ y = 1
        1
        >>> NAND(0, 1)    # NANDゲートのパラメータ x1 = 0, x2 = 1 ⇒ y = 1
        1
        >>> NAND(1, 1)    # NANDゲートのパラメータ x1 = 1, x2 = 1 ⇒ y = 0
        0
        >>>
        
    • 3. ORゲートの単純パーセプトロンサンプル

      • ORゲート真理値表
        \(x_{1}\) \(x_{2}\) \(y\)
        0 0 0
        1 0 1
        0 1 1
        1 1 1
      • Pythonサンプル
        上記 1.2. と同様に上記のORゲートを満たすパラメータ \(w_{1}, w_{2}, \theta\) を \((w_{1}, w_{2}, \theta)\) \(= (0.9, 0.9, 0.5)\) と置いて、Pythonで表現したもの。
        $ python
        >>> def OR(x1, x2):
        ...     w1, w2, theta = 0.9, 0.9, 0.5
        ...     y = x1*w1 + x2*w2
        ...     if y <= theta:
        ...         return 0
        ...     elif y > theta:
        ...         return 1
        ...
        >>> OR(0, 0)    # ORゲートのパラメータ x1 = 0, x2 = 0 ⇒ y = 0
        0
        >>> OR(1, 0)    # ORゲートのパラメータ x1 = 1, x2 = 0 ⇒ y = 1
        1
        >>> OR(0, 1)    # ORゲートのパラメータ x1 = 0, x2 = 1 ⇒ y = 1
        1
        >>> OR(1, 1)    # ORゲートのパラメータ x1 = 1, x2 = 1 ⇒ y = 1
        1
        >>>
        

    上記 1.3. のPythonサンプルにて、関数 AND、NAND、OR を定義しているが、パラメータ \(w_{1}\)(重み1), \(w_{2}\)(重み2), \(\theta\)(閾値)以外は、すべて同じロジックとなっている。

    この結果からも分かるように全く同じ構造のパーセプトロンでも、パラメータ次第でAND、NAND、ORの論理回路を表現することができる。

    上記 1.3. のパラメータ決定(\(w_{1}\)(重み1), \(w_{2}\)(重み2), \(\theta\)(閾値))では、AND、NAND、ORの真理値表を満たすように人間が事前に考えて記載しているが、機械学習ではこのパラメータ を決定する作業をすべてコンピュータに任せている。
    (人間がパーセプトロンの構造を考えてコンピュータに様々な学習データを与え、コンピュータは膨大な数のパラメータ決定を繰り返し、結果の正確さや妥当性を高めていく)

単純パーセプトロンの一般的な表現

  • バイアスを用いた一般化

    上記\((A)\)、\((B)\)、\((C)\)で不等式の右辺を閾値 \(\theta\)とし、単純パーセプトロンの動作原理で説明したが、可視性や利便上表現を少し変える。

    理屈は閾値 \(\theta\) と同じだが、\(-\theta\) をバイアス \(b\) と表現を変え、上記\((A)\)を以下\((D)\)のように表す。
    ※\((A)\)から閾値 \(\theta\) を左辺に移項し、\(-\theta\) を \(b\) に置き換えている。
    バイアスとは「ゲタをはく」という意味があり、入力がオール \(0\) の時、どれだけ値を上乗せするかという意味を持つ。

    \[ y = {\small \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + x_{2}w_{2} \leqq \theta \\ 1 \hspace{5pt}\text{if}\hspace{5pt}x_{1}w_{1} + x_{2}w_{2} > \theta \end{cases}\hspace{5mm}・・・(A) } \]

    閾値 \(\theta\) を左辺に移項し、\(-\theta\) を \(b\) に置換。

    \[ {\small y = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}b + x_{1}w_{1} + x_{2}w_{2} \leqq 0 \\ 1 \hspace{5pt}\text{if}\hspace{5pt}b + x_{1}w_{1} + x_{2}w_{2} > 0 \end{cases}\hspace{5mm}・・・(D) } \]

    そして上記\((D)\)の入力信号を \(n\) 個とし、

    \[ {\small y = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}b + x_{1}w_{1} + … + x_{n}w_{n}\leqq 0 \\ 1 \hspace{5pt}\text{if}\hspace{5pt}b + x_{1}w_{1} + … + x_{n}w_{n} > 0 \end{cases}\hspace{5mm}・・・(E) } \]

    さらにまとめて

    \[ {\small y = \begin{cases} 0 \hspace{5pt}\text{if}\hspace{5pt}\sum_{i=1}^{n} x_{i}w_{i} + b \leqq 0 \\ 1 \hspace{5pt}\text{if}\hspace{5pt}\sum_{i=1}^{n} x_{i}w_{i} + b > 0 \end{cases}\hspace{5mm}・・・(F) } \]
    と表現できる。

単純パーセプトロンの実装サンプル

  • NumPyによる論理ゲート実装

    上記\((D)\)をANDゲートで表現した実装サンプルを説明する。

    もちろん、単純パーセプトロンの動作原理の解説と同様に\((D)\)についても NANDゲート、ORゲートは、パラメータ\(w_{1}\)(重み1),\(w_{2}\)(重み2), \(b\)(バイアス)を変えることで表現できる。

    $ python
    >>> import numpy as np
    >>> def AND(x1, x2):
    ...     x = np.array([x1, x2])    # 入力
    ...     w = np.array([0.5, 0.5])    # 重み
    ...     b = -0.7    # バイアス
    ...     y = np.sum(w*x) + b    # ・・・ (*)
    ...     if y <= 0:
    ...         return 0
    ...     else:
    ...         return 1
    ...
    >>> AND(0, 0)
    0
    >>> AND(1, 0)
    0
    >>> AND(0, 1)
    0
    >>> AND(1, 1)
    1
    >>>
    

    互いの配列要素が同じNumPy配列の乗算は、要素同士が乗算されるため、要素が\(n\)個であっても、上記実装サンプル(*)の一行で実行できる。

    重み(\(w_{1}\), \(w_{2}\))の程度にもよるが、基準となるニューロン発火のしやすさ(出力が1となる度合)は、バイアス(\(b\))が要となる。

まとめ

  • 単純パーセプトロンは、入力と重みの合計をしきい値で判定するモデルで、しきい値を左辺へ移したものをバイアスとして扱える。
  • AND、NAND、ORは重みとバイアスを変えて表現できるが、ここでは値を手で決めており、データから学習しているわけではない。
  • XORのように直線で分離できない問題は単純パーセプトロンでは表現できず、多層構造が必要になる。

参考文献

この記事を共有
Xで共有 Facebookで共有 LINEで共有



Copyright SIGMA-SE All Rights Reserved.
s-hama@sigma-se.jp