ニューラルネットワークの実装6 ニューラルネットワークの構築

前回の記事では単一のニューロンによる分類問題を取り上げましたね。ここまで到達した時点で相当マニアックな領域になってます。このブログを読んでいるあなたは、データサイエンスの凄腕エンジニアになれると思います。
データサイエンスとは、「膨大なデータを体系的に整理し、問題の答えを正確に予想する」という領域の学問です。もっと違う定義もあるのかもしれませんが、大体こんな解釈でいいと思います^_^。
ところで、だいぶコードを理解するのが難しくなってきたのではないでしょうか^_^;。私も記事で解説するのが大変になってきました。
慣れてくるとアルゴリズムを目で追うのが楽になってくるのですが、慣れないうちは大変かもしれません。目がしょぼしょぼになってしまうのではないでしょうか?
エンジニアと呼ばれる人たちはコードだけをみて「どんな処理を行うのか」を頭の中で組み立てています。一万行にもなってくると、相当大変になります。でも慣れてくればそんなに難しいと感じなくなってくるはずです。
「コードなんて見るのも嫌」なんて思わないでください。やっていることは無茶苦茶難しいわけではありません。
一つ一つを確実に理解しながら進んでください。
今回の記事で実装するニューラルネットワークはこんな感じです↓。Python でコードを実装するときは必ずこの図を意識してください。

一つ一つの丸は全てニューロンです。ニューロンとはこんな感じ↓のものです。

いきなりこんな図が出てきて、めまいがするかもしれません。ですが、コードを実装してみたらなんとなくわかってきたのではないでしょうか。
今日も精一杯丁寧に解説します^o^。
まずは貼り付け用のコードを載せます。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
iris = datasets.load_iris()
iris_data = iris.data
sl_data = iris_data[:100, 0] # SetosaとVersicolor、Sepal length
sw_data = iris_data[:100, 1] # SetosaとVersicolor、Sepal width
# 平均値を0に
sl_ave = np.average(sl_data) # 平均値
sl_data -= sl_ave # 平均値を引く
sw_ave = np.average(sw_data)
sw_data -= sw_ave
# 入力をリストに格納
input_data = []
for i in range(100): # iには0から99までが入る
input_data.append([sl_data[i], sw_data[i]])
# シグモイド関数
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
# ニューロン
class Neuron:
def __init__(self): # 初期設定
self.input_sum = 0.0
self.output = 0.0
def set_input(self, inp):
self.input_sum += inp
def get_output(self):
self.output = sigmoid(self.input_sum)
return self.output
def reset(self):
self.input_sum = 0
self.output = 0
# ニューラルネットワーク
class NeuralNetwork:
def __init__(self): # 初期設定
# 重み
self.w_im = [[4.0, 4.0], [4.0, 4.0]] # 入力:2 ニューロン数:2
self.w_mo = [[1.0, -1.0]] # 入力:2 ニューロン数:1
# バイアス
self.b_m = [2.0, -2.0] # ニューロン数:2
self.b_o = [-0.5] # ニューロン数:1
# 各層の宣言
self.input_layer = [0.0, 0.0]
self.middle_layer = [Neuron(), Neuron()]
self.output_layer = [Neuron()]
def commit(self, input_data): # 実行
# 各層のリセット
self.input_layer[0] = input_data[0] # 入力層は値を受け取るのみ
self.input_layer[1] = input_data[1]
self.middle_layer[0].reset()
self.middle_layer[1].reset()
self.output_layer[0].reset()
# 入力層→中間層
self.middle_layer[0].set_input(self.input_layer[0] * self.w_im[0][0])
self.middle_layer[0].set_input(self.input_layer[1] * self.w_im[0][1])
self.middle_layer[0].set_input(self.b_m[0])
self.middle_layer[1].set_input(self.input_layer[0] * self.w_im[1][0])
self.middle_layer[1].set_input(self.input_layer[1] * self.w_im[1][1])
self.middle_layer[1].set_input(self.b_m[1])
# 中間層→出力層
self.output_layer[0].set_input(self.middle_layer[0].get_output() * self.w_mo[0][0])
self.output_layer[0].set_input(self.middle_layer[1].get_output() * self.w_mo[0][1])
self.output_layer[0].set_input(self.b_o[0])
return self.output_layer[0].get_output()
# ニューラルネットワークのインスタンス
neural_network = NeuralNetwork()
# 実行
st_predicted = [[], []] # Setosa
vc_predicted = [[], []] # Versicolor
for data in input_data:
if neural_network.commit(data) < 0.5:
st_predicted[0].append(data[0]+sl_ave)
st_predicted[1].append(data[1]+sw_ave)
else:
vc_predicted[0].append(data[0]+sl_ave)
vc_predicted[1].append(data[1]+sw_ave)
# 分類結果をグラフ表示
plt.scatter(st_predicted[0], st_predicted[1], label="Setosa")
plt.scatter(vc_predicted[0], vc_predicted[1], label="Versicolor")
plt.legend()
plt.xlabel("Sepal length (cm)")
plt.ylabel("Sepal width (cm)")
plt.title("Predicted")
plt.show()
すいません、コードが長くなりました。次のページから解説をします。
1
2
コメント