Skip to content

Instantly share code, notes, and snippets.

@yumatsuoka
Created August 16, 2016 03:59
Show Gist options
  • Save yumatsuoka/d73cc4ceb3abb657d5aa8c88736f31f4 to your computer and use it in GitHub Desktop.
Save yumatsuoka/d73cc4ceb3abb657d5aa8c88736f31f4 to your computer and use it in GitHub Desktop.
reconstruct former 3 layer neural net applied to XOR and Iris dataset with Numpy
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 非線形問題を解くNeuralNetwork(Numpy)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# -*-coding:utf-8-*-\n",
"\n",
"from __future__ import absolute_import\n",
"from __future__ import division\n",
"from __future__ import print_function\n",
"\n",
"%matplotlib inline\n",
"import six, time\n",
"import numpy as np\n",
"import pandas as pd\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 非線形性のNeural Net"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class InputLayer:\n",
" \"\"\"\n",
" Neural netの入力層の機能を持つクラス\n",
" コンストラクタの引数:入力データの次元dim(int)\n",
" \"\"\"\n",
" def __init__(self, dim):\n",
" self.dim = dim\n",
" self.data = np.zeros((1, self.dim))\n",
"\n",
" def forward(self):\n",
" pass\n",
"\n",
" def backward(self):\n",
" pass\n",
"\n",
" def updateWeight(self, alpha):\n",
" pass\n",
"\n",
" \n",
"class NeuroLayer:\n",
" \"\"\"\n",
" Neural netの隠れ層の機能をもつクラス(中間層or出力層)\n",
" コンストラクタの引数:入力データの次元dim(int)、データ入力を受ける層preLayer(Object)\\\n",
" 重み初期値を決める乱数のシード(double)、バイアスの初期値bias(double)\\\n",
" 重み初期値の範囲randA~randB(double)\n",
" \"\"\"\n",
" def __init__(self, dim, preLayer, bias, r_max, r_min):\n",
" self.dim = dim\n",
" self.preLayer = preLayer\n",
" self.data = np.zeros((1, self.dim))\n",
" self.weight = np.random.rand(self.dim, self.preLayer.dim) * (r_max - r_min) - r_max\n",
" self.bias = np.ones((1, self.dim)) * bias\n",
" self.nextLayer = None\n",
" self.preLayer.nextLayer = self\n",
" self.diff = np.zeros((1, self.preLayer.dim))\n",
" self.diffWeight = np.zeros((self.dim, self.preLayer.dim))\n",
" self.diffBias = np.zeros((1, self.dim))\n",
"\n",
" def forward(self):\n",
" temp = np.dot(self.preLayer.data, self.weight.T)\n",
" self.data = temp + self.bias\n",
" \n",
" def backward(self):\n",
" self.diffWeight += np.dot(self.nextLayer.diff.T, self.preLayer.data)\n",
" self.diffBias += self.nextLayer.diff * 1.\n",
" self.diff = np.dot(self.nextLayer.diff, self.weight)\n",
"\n",
" def updateWeight(self, alpha):\n",
" self.bias -= self.diffBias * alpha\n",
" self.weight -= self.diffWeight * alpha\n",
" self.diffBias = np.zeros((1, self.dim))\n",
" self.diffWeight = np.zeros((self.dim, self.preLayer.dim))\n",
"\n",
" \n",
"class ActionLayer:\n",
" \"\"\"\n",
" 活性関数の機能をもつクラス\n",
" コンストラクタの引数:データ入力を受ける層prelayer(object)\n",
" \"\"\"\n",
" def __init__(self, preLayer):\n",
" self.preLayer = preLayer\n",
" self.dim = self.preLayer.dim\n",
" self.data = np.zeros((1, self.preLayer.dim))\n",
" self.nextLayer = None\n",
" self.preLayer.nextLayer = self\n",
" self.diff = np.zeros((1, self.preLayer.dim))\n",
"\n",
" def forward(self):\n",
" self.data = (np.ones(self.dim) / (np.ones(self.dim) + np.exp(-self.preLayer.data)) )\n",
"\n",
" def backward(self):\n",
" self.diff = self.nextLayer.diff * (self.data * (np.ones(self.dim) - self.data) )\n",
"\n",
" def updateWeight(self, alpha):\n",
" pass\n",
" \n",
"\n",
"class ErrorLayer:\n",
" \"\"\"\n",
" 出力層の出力と教師ラベルとの誤差を求める機能をもつクラス\n",
" コンストラクタの引数:入力を受ける層preLayer(Object)\n",
" \"\"\"\n",
" def __init__(self, preLayer):\n",
" self.preLayer = preLayer\n",
" self.dim = self.preLayer.dim\n",
" self.data = 0.0\n",
" self.target = np.zeros((1, self.dim))\n",
" self.diff = np.zeros((1, self.preLayer.dim))\n",
" self.preLayer.nextLayer = self\n",
" self.result = np.zeros((1, self.dim))\n",
"\n",
" def forward(self):\n",
" dataSum = np.power(self.preLayer.data - self.target, 2)\n",
" self.data += dataSum.sum()\n",
" self.result = self.preLayer.data.copy()\n",
" self.result[self.result > 0.5] = 1\n",
" self.result[self.result <= 0.5] = 0\n",
"\n",
" def backward(self):\n",
" self.diff = 2 * (self.preLayer.data - self.target)\n",
"\n",
" def updateWeight(self, alpha):\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## training neural net"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def train_nn(alpha, iteration, batchsize, neuralNetwork,\\\n",
" trainingData, trainingTarget, testData, testTarget):\n",
" \"\"\"\n",
" neural netを学習させる\n",
" 入力:学習率appha(double)、学習epoch(int)、neuralnet(list)、\n",
"  学習用データ(list)、学習ラベル(list)、テストデータ(list)、テストラベル(list)\n",
" 出力:それぞれのepoch終了時でのlossの値をもつlist\n",
" \"\"\"\n",
" start_time = time.clock()\n",
" loss_list = np.zeros(iteration)\n",
"\n",
" # train\n",
" for itr in six.moves.range(iteration):\n",
" perm = np.random.permutation(len(trainingData))\n",
" for i in six.moves.range(0, len(trainingData), batchsize):\n",
" x = trainingData[perm[i: i + batchsize]]\n",
" t = trainingTarget[perm[i: i + batchsize]]\n",
" for (d, t) in zip(x, t): \n",
" neuralNetwork[0].data = np.expand_dims(d, axis=0)\n",
" neuralNetwork[5].target = t\n",
" for layer in neuralNetwork:\n",
" layer.forward()\n",
" for layer in reversed(neuralNetwork):\n",
" layer.backward()\n",
" for layer in neuralNetwork:\n",
" layer.updateWeight(alpha)\n",
" loss_list[itr] = neuralNetwork[5].data / len(trainingData)\n",
" neuralNetwork[5].data = 0\n",
" \n",
" # test\n",
" correct = 0\n",
" for (d, t) in zip(testData, testTarget):\n",
" neuralNetwork[0].data = d\n",
" neuralNetwork[5].target = t\n",
" for layer in neuralNetwork:\n",
" layer.forward()\n",
" if (neuralNetwork[5].result == t).all():\n",
" correct += 1\n",
" \n",
" elapsed_time = time.clock() - start_time\n",
" print(\"経過時間\",elapsed_time)\n",
" print(\"train epoch={}, test accuracy={}%\".format(\\\n",
" iteration, (correct / len(testData) * 100)))\n",
" \n",
" return loss_list, (correct / len(testData) * 100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CSVの読み込みとデータセットの作成"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"def get_dataset(d_dir, N_train):\n",
" \"\"\"\n",
" IrisデータセットのCSVファイルからデータを抽出および整形\n",
" 入力:ファイルディレクトリ(str)、教師ラベル名(list)、学習に使うデータ数(int)\n",
" 出力:学習データ(list)、学習ラベル(list)、テストデータ(list)、テストラベル(list)\n",
" \"\"\"\n",
" csv_data = pd.read_csv(d_dir, header=None)\n",
" input_data = csv_data[[0, 1, 2, 3]]\n",
" input_data = input_data.as_matrix()\n",
" change_target = csv_data[4]\n",
" input_target = np.asarray([([1., 0., 0.]) if (d == \"Iris-setosa\") else (\\\n",
" ([0., 1., 0.]) if (d == \"Iris-versicolor\") else (\\\n",
" ([0., 0., 1.]) if (d == \"Iris-virginica\") else (\\\n",
" ))) for d in change_target])\n",
" \n",
" perm = np.random.permutation(len(input_data))\n",
" input_data = input_data[perm]\n",
" input_target = input_target[perm]\n",
" \n",
" train_d = input_data[: N_train]\n",
" train_t = input_target[: N_train]\n",
" test_d = input_data[N_train:]\n",
" test_t = input_target[N_train:] \n",
" \n",
" return train_d, train_t, test_d, test_t"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 排他的論理和問題にNeural Netを適用"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"経過時間 0.22289544466063868\n",
"train epoch=700, test accuracy=100.0%\n"
]
},
{
"data": {
"image/png": "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\nGYrzAAAAAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x220fe764320>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\"\"\"\n",
"ハイパーパラメータ\n",
"alpha :学習係数\n",
"iteration :学習epoch数\n",
"batchsize :学習時のバッチサイズ\n",
"bias :バイアスの初期値\n",
"hiddenDim :隠れ層の次元数\n",
"randA :重みの初期値を決める乱数の下限\n",
"randB :重みの初期値を決める乱数の上限\n",
"\"\"\"\n",
"\n",
"alpha = 0.7\n",
"iteration = 700\n",
"batchsize = 4\n",
"bias = 0.6\n",
"r_max = -0.5\n",
"r_min = 0.5\n",
"hiddenDim = 5\n",
"train_d = np.asarray([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])\n",
"train_t = np.asarray([[0.0], [1.0], [1.0], [0.0]])\n",
"test_d = np.asarray([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])\n",
"test_t = np.asarray([[0.0], [1.0], [1.0], [0.0]])\n",
"\n",
"inputLayer = InputLayer(len(train_d[0]))\n",
"hiddenLayer = NeuroLayer(hiddenDim, inputLayer, bias, r_max, r_min)\n",
"hiddenActionLayer = ActionLayer(hiddenLayer)\n",
"outputLayer = NeuroLayer(len(train_t[0]), hiddenActionLayer, bias, r_max, r_min)\n",
"outputActionLayer = ActionLayer(outputLayer)\n",
"errorLayer = ErrorLayer(outputActionLayer)\n",
"\n",
"neuralNetwork = [inputLayer, hiddenLayer, hiddenActionLayer,\\\n",
" outputLayer, outputActionLayer, errorLayer]\n",
"\n",
"loss_list, acc = train_nn(alpha, iteration, batchsize, neuralNetwork,\\\n",
" train_d, train_t, test_d, test_t)\n",
"\n",
"# plot loss values on training\n",
"plt.plot(loss_list)\n",
"plt.title('XOR train loss, accuracy={}'.format(acc))\n",
"plt.xlabel('epoch')\n",
"plt.ylabel('loss')\n",
"plt.xlim([0, len(loss_list)-1])\n",
"# plt.savefig(\"xor_loss.png\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CUI Iris datasetにNeural Netを適用"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"経過時間 4.383194472781922\n",
"train epoch=500, test accuracy=96.66666666666667%\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x220fe79b518>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\"\"\"\n",
"ハイパーパラメータ\n",
"alpha :学習係数\n",
"iteration :学習epoch数\n",
"batchsize :学習時のバッチサイズ\n",
"bias :バイアスの初期値\n",
"hiddenDim :隠れ層の次元数\n",
"randA :重みの初期値を決める乱数の下限\n",
"randB :重みの初期値を決める乱数の上限\n",
"N_train :学習に使うサンプル数\n",
"f_name :ファイルのパス\n",
"\"\"\"\n",
"\n",
"alpha = 0.02\n",
"iteration = 500\n",
"batchsize = 20\n",
"bias = 0.9\n",
"hiddenDim = 12\n",
"r_max = -0.3\n",
"r_min = 0.3\n",
"N_train = 120\n",
"f_name = \"./iris.csv\"\n",
"\n",
"train_d, train_t, test_d, test_t = get_dataset(f_name, N_train)\n",
"\n",
"inputLayer = InputLayer(len(train_d[0]))\n",
"hiddenLayer = NeuroLayer(hiddenDim, inputLayer, bias, r_max, r_min)\n",
"hiddenActionLayer = ActionLayer(hiddenLayer)\n",
"outputLayer = NeuroLayer(len(train_t[0]), hiddenActionLayer, bias, r_max, r_min)\n",
"outputActionLayer = ActionLayer(outputLayer)\n",
"errorLayer = ErrorLayer(outputActionLayer)\n",
"\n",
"neuralNetwork = [inputLayer, hiddenLayer, hiddenActionLayer,\\\n",
" outputLayer, outputActionLayer, errorLayer]\n",
"\n",
"loss_list, acc = train_nn(alpha, iteration, batchsize, neuralNetwork,\\\n",
" train_d, train_t, test_d, test_t)\n",
"\n",
"# plot loss value on training\n",
"plt.plot(loss_list)\n",
"plt.title('Iris train loss, accuracy={}'.format(acc))\n",
"plt.xlabel('epoch')\n",
"plt.ylabel('loss')\n",
"plt.xlim([0, len(loss_list)-1])\n",
"# plt.savefig(\"iris_loss.png\")\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"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.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment