Pythonで多層パーセプトロンのXORゲートを実装する!

  • このエントリーをはてなブックマークに追加

機械学習のニューラルネットワークはパーセプトロンを基礎としています。パーセプトロンは線形分離可能な問題にしか適用できませんが、多層に連結することでその壁を超えることができます。ここではPythonを使って多層パーセプトロンのコーディングを習得します。

こんにちは。wat(@watlablog)です。
単一のパーセプトロンから発展し、ここでは多層パーセプトロンをコーディングしてみます

単一パーセプトロンのおさらい

パーセプトロンは可変の線形識別器になる

パーセプトロンとは、以下の図に示すように\(n\)個の入力\(x_{n}\)を重み\(w_{n}\)をかけてから足し合わせ、ある閾値\(\theta\)を使ったステップ関数\(f_{step}\)を通して0か1の出力\(y\)を得るモデルです。

パーセプトロン

このモデルを絵ではなく式にすると以下の式(1)で書くことができます。
非常に簡単な式ではありますが、この式の重み\(w_{n}\)と閾値\(\theta\)を変えるだけで線形の識別器が作れてしまう優れものなのです。

\[
y = \begin{cases}
0 & (w_{1}x_{1}+w_{2}x_{2})\leq \theta \\
1 & (w_{1}x_{1}+w_{2}x_{2})> \theta
\end{cases} (1)
\]

つまりパーセプトロンは、以下の図に示すように入力に対して赤丸や青丸のような2つのグループに分ける問題を出した時に直線で適切に分類することができるモデルということです。

線形分離識別機

AND/OR/NANDの論理ゲートを再現する(コード付き)

パーセプトロンには良く知られた代表的な例題として、論理演算ブーリアン演算)があります。

多層パーセプトロンに行く前に単一パーセプトロンで構築された論理ゲート問題を解いてみましょう。

ANDゲート

ANDゲートは以下の図で示される論理回路で、日本語で論理積を意味します。

ANDゲート

積を計算するため真理値表は下表になり、全ての入力が1にならないと1を返しません。

\(x_{1}\)\(x_{2}\)\(y\)
000
010
100
111

ここでいう1はTRUE(真)、0はFALSE(偽)と表現することもあります。

ANDゲートをパーセプトロンで表現したコードと実行例は「PythonでパーセプトロンのANDゲートを実装する!」で詳細を書いていますので、是非読んでみて下さい。

この記事の最後で通常論理演算ではありえない小数点や負値の入力を試した所、問題なく動作し下図のように境界線を見ることができました。

ANDゲートのパーセプトロンコード実行結果

ORゲート

一方ORゲートは下図に示す論理回路です。日本語では論理和と呼ばれます。

ORゲート

真理値表は下表で、入力に1が1つでもあれば1を返します。

\(x_{1}\)\(x_{2}\)\(y\)
000
011
101
111

パーセプトロンでORゲートをモデル化したPythonコードは「PythonでパーセプトロンのORゲートを実装する!」という記事に書きましたので、こちらも併せて読んで頂ければと思います。

ANDゲートと似ていますが、パーセプトロンでORゲートを模して計算した値は境界線の位置が異なっている結果を得ました。

ORゲートのパーセプトロンコード実行結果

NANDゲート

上記2つの論理回路の他に、NANDゲートNAND:Not AND)呼ばれるものもあります。これは日本語で否定論理積と呼ばれるもので、ANDゲートで得られた値を否定、つまりANDゲートで0であれば1、ANDゲートで1であれば0を返すというものです。

NANDゲート

出力の手前にポッチがありますが、これがNotを意味します。

真理値表は下表です。なんともひねくれたやつという印象です。

\(x_{1}\)\(x_{2}\)\(y\)
001
011
101
110

このNANDゲートもパーセプトロンで表現することができます
上で紹介した2つの記事と同じように、Pythonコードで書くと以下のように書けます。

このコードを実行すると以下の結果がコンソールに表示されます。

コードは過去記事のものとまったく同じで重み\(w_{1}\), \(w_{2}\)と閾値\(\theta\)が異なるだけです。他の入力値を入れて詳細なグラフを描いてみるとANDやORと同じようにある場所に境界線が位置し、0と1で分類できていることを確かめられますので、是非可視化にトライしてみて下さい。

線形分離可能な問題以外は対応できない理由

ここまででAND/OR/NANDゲートを見事表現できてきたパーセプトロンですが、お気づきのように分類に使われている境界線は全て直線です。

直線で分類可能な問題のことを線形分離可能と表現しますが、直線しか表現できないことが単一パーセプトロンが線形分離可能な問題以外は対応できない最大で唯一の理由となります

ダメじゃん!

…と諦めないのが科学者なので、このパーセプトロンをさらに沢山繋げた多層パーセプトロンというモデルが考案されました。

多層パーセプトロンの概要

多層パーセプトロンとは?

多層パーセプトロンMLP:Multi-Layer Perceptron)とは、本記事の最初に示した単一のパーセプトロンを複数繋げたものです。

多層パーセプトロンの例を下図に示します。

多層パーセプトロンの例

ここで示している多層パーセプトロンは2入力の場合ですが、入力が増えても入力数分の接続数が増えるだけで考え方は同じです。

先ほどまでは直線でしか分類ができない単純なパーセプトロンも、このように複数使うことで複雑な分類が可能になってきます。

なぜ多層にすることで線形以外の識別が可能になる?

線形分類不可能な問題の例:XORゲート

パーセプトロンを多層にすることで、線形分離不可能な問題に対応することができますが、これまで論理回路でパーセプトロンを学んできたので、同じく論理回路を例にした方がその仕組みを理解しやすいと思われます。

以下の図はXORゲートXOR:Exclusive OR)と呼ばれる論理回路で、日本語では排他的論理和と呼びます。

XORゲート

XORゲートの真理値表は下表です。一方が1で、もう一方が0の時だけ1となるゲートということがわかります。

\(x_{1}\)\(x_{2}\)\(y\)
000
011
101
110

グラフにプロットすると以下のようになります。この2種類の出力を1本の直線で分類しようとするのは無理ということは自明と言えます。

XORゲートのグラフ

つまり、「XORゲートは単一のパーセプトロンでは表現できない」ということですね!

XORゲートを多層パーセプトロンで表現する方法

XORゲートは単一のパーセプトロンでは表現できませんが、論理回路の分野では複数の論理回路を組み合わせればXORを構築することができるということが古くから知られています。

色々なパターンがありますが、シンプルなものは以下の図に示すようにNAND、OR、ANDを組み合わせたものが有名です。

XORゲートを複合論理回路で表現した例

上図の\(x_{1}\)と\(x_{2}\)に値を代入し、真理値表を作っていったものが下表です。最終的な出力である\(y\)の部分では見事XORゲートで欲しかった出力になっています。

\(x_{1}\)\(x_{2}\)NAND OR AND(\(y\))
00100
01111
10111
11010

ここで、NANDやOR,ANDゲートはそれぞれ単一のパーセプトロンで表現可能でした。つまり、パーセプトロンを複数使うことで線形分離不可能な問題にも対応できるということの証明にもなっています。

それではPythonによる多層パーセプトロンによるXORゲートの実装コードを書いていきましょう。

Pythonによる多層パーセプトロンコード

全コード

以下が全コードですが、パーセプトロンで書いたNANDゲート、ANDゲート、ORゲートを予め関数で用意しておき、先ほどの複合論理回路で示したようにNANDの出力とORの出力をANDの入力に使用することでパーセプトロンを多層に繋げるということを表現しています(for文の中)。

重み\(w\)や閾値\(\theta\)は既にdef文で書かれた関数の中に決め打ちで記載してあります。

実行結果

実行結果は以下です。y3が最終的な出力ですが、XORゲートの出力となっていることがわかります。

入力の範囲と分解能を変えて網羅的に見てみるコード

ANDゲートやORゲートの記事の時もやりましたが、0と1以外の入力を入れてみた時にどういう振る舞いをするか見てみましょう。

Python/matplotlib3Dプロット!面と散布図を作成」という記事で3D散布図の描き方を習得したので、グリッド軸を用意すれば簡単に入力の範囲を広げたり分解能を細かくしたりが可能であることがわかりました。

今回は3D散布図を使って網羅的に2入力に対する多層パーセプトロンの応答を見てみようと思います

以下が全コードです。3Dプロットの方法は先に紹介した記事に記載している通りですが、まずx1, x2の軸を用意してnp.meshgridを使ってグリッド軸を作成する所が特徴です。

実行結果

以下が実行結果です。

細かく見てみると[0,1]、[1,0]以外にも1を返す入力変数の組み合わせがあることがよくわかりました。

多層パーセプトロンの出力確認結果

1つだけの単純パーセプトロンではある境界で0と1が分かれていただけでしたが、今回の多層具合だとある範囲を1とするような分類の方法がとれるということみたいです。

まとめ

本記事はおさらいとして、ANDゲートやORゲート、NANDゲートをパーセプトロンで表現する方法を紹介しました。

そしてたった一つだけの単純パーセプトロンでは線形分離可能な問題しか対応できないことを学びましたが、同時に複数のパーセプトロンを組み合わせることでその壁を突破できることをXORゲートの仕組みから理解しました。

最後に、Pythonによる多層パーセプトロンのコードを紹介し、0と1以外の入力に対する応答を確認しました。

結果、今回の多層パーセプトロンはある範囲で0と1を分類できる識別器として作用していることがわかりました。

多層パーセプトロンでも組み合わせ次第で色々な分類問題に対応できそうですね!しかしまだ重みや閾値は決め打ちしているだけですので、これからどんどん先に進んで行きましょう!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!

SNSでもご購読できます。

コメント

コメントを残す

*