{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 多層パーセプトロン" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "XORを実装するためには, AND, NAND, ORゲートを組み合わせなければならない。\n", "\n", "入力を $x_1$, $x_2$, NANDの出力を $s_1$, ORの出力を $s_2$ とすると、$s_1$, $s_2$を入力としたANDの出力 $y$ は以下の表の通りになる:\n", "\n", "| $x_1$ | $x_2$ | $s_1$ | $s_2$ | $y$ |\n", "| ----- | ----- | ----- | ----- | --- |\n", "| $0$ | $0$ | $1$ | $0$ | $0$ |\n", "| $1$ | $0$ | $1$ | $1$ | $1$ |\n", "| $0$ | $1$ | $1$ | $1$ | $1$ |\n", "| $1$ | $1$ | $0$ | $1$ | $0$ |\n", "\n", "では、前に作成したNAND, ORを使用して、XORの結果を出力する関数を作成しよう。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from matplotlib import pyplot as plt\n", "\n", "def AND(x1, x2):\n", " \"\"\"\n", " AND関数\n", " \n", " Parameters\n", " ----------\n", " x1 : float\n", " 入力1\n", " x2 : float\n", " 入力2\n", " \"\"\"\n", " x = np.array([x1, x2])\n", " w = np.array([0.5, 0.5])\n", " b = -0.7\n", " tmp = np.sum(w * x) + b\n", " if tmp <= 0:\n", " return 0\n", " else:\n", " return 1\n", "\n", "def NAND(x1, x2):\n", " \"\"\"\n", " NAND関数\n", " \n", " Parameters\n", " ----------\n", " x1 : float\n", " 入力1\n", " x2 : float\n", " 入力2\n", " \"\"\"\n", " x = np.array([x1, x2])\n", " w = np.array([-0.5, -0.5])\n", " b = 0.7\n", " tmp = np.sum(w * x) + b\n", " if tmp <= 0:\n", " return 0\n", " else:\n", " return 1\n", "\n", "def OR(x1, x2):\n", " \"\"\"\n", " OR関数\n", " \n", " Parameters\n", " ----------\n", " x1 : float\n", " 入力1\n", " x2 : float\n", " 入力2\n", " \"\"\"\n", " x = np.array([x1, x2])\n", " w = np.array([0.5, 0.5])\n", " b = -0.2\n", " tmp = np.sum(w * x) + b\n", " if tmp <= 0:\n", " return 0\n", " else:\n", " return 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## XORゲートの実装" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def XOR(x1, x2):\n", " \"\"\"\n", " XOR関数\n", " \n", " Parameters\n", " ----------\n", " x1 : float\n", " 入力1\n", " x2 : float\n", " 入力2\n", " \"\"\"\n", " s1 = NAND(x1, x2)\n", " s2 = OR(x1, x2)\n", " return AND(s1, s2)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "XOR(0, 0)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "XOR(1, 0)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "XOR(0, 1)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "XOR(1, 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "このように、複数のパーセプトロンを組み合わせたパーセプトロンのことを **多層パーセプトロン** という。 \n", "XORは、NAND, ORの出力とANDの出力の組み合わせなので、2層のパーセプトロンである。\n", "(本によっては、入力$x_1$, $x_2$も入れて3層とすることもある)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 🤔XORをグラフにすると?" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "from matplotlib import pyplot as plt\n", "import itertools\n", "\n", "if __name__ == \"__main__\":\n", " xs = np.array([[0, 0],\n", " [1, 0],\n", " [0, 1],\n", " [1, 1]], dtype=np.float32) # データ\n", "\n", "\n", "\n", " w = np.array([0, 0], dtype=np.float32) # 重み\n", " b = 0 # バイアス\n", " lr = 0.01 # 学習率\n", "\n", " def predict(x):\n", " u = np.dot(x, w) - b\n", " return np.where(u > 0, 1, 0)\n", "\n", " # グラフの描画 from https://teratail.com/questions/177319\n", " fig, ax = plt.subplots()\n", " ax.set_xticks([0, 1]), ax.set_yticks([0, 1])\n", " ax.set_xlim(-0.5, 1.5), ax.set_ylim(-0.5, 1.5)\n", "\n", " # サンプルを描画する。\n", " ax.scatter(xs[:, 0], xs[:, 1], s=30)\n", "\n", " # 各点の推論結果を得る。\n", " X, Y = np.meshgrid(np.linspace(*ax.get_xlim(), 100),\n", " np.linspace(*ax.get_ylim(), 100))\n", " XY = np.column_stack([X.ravel(), Y.ravel()])\n", " Z = np.array([XOR(x[0], x[1]) for x in XY]).reshape(X.shape)\n", "\n", " # 等高線を描画する。\n", " ax.contourf(X, Y, Z, alpha=0.4, cmap='RdBu')\n", "\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "曲線にならなかったね…" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" } }, "nbformat": 4, "nbformat_minor": 4 }