# python3 neural_network.py
% matplotlib inline
import numpy as np
import pandas as pd
import scipy.special
import matplotlib.pyplot as plt
class neuralNetwork:
def __init__(self,input_nodes,hidden_nodes,output_nodes,learning_rate):# 初期化
#ノード数と学習率
self.i_nodes=input_nodes
self.h_nodes=hidden_nodes
self.o_nodes=output_nodes
self.lr=learning_rate
#重み
self.w_ih=np.random.normal(0.0,pow(self.h_nodes,-0.5),(self.h_nodes,self.i_nodes))#ノード数の平方根の逆数を範囲とする
self.w_ho=np.random.normal(0.0,pow(self.o_nodes,-0.5),(self.o_nodes,self.h_nodes))
#活性化関数
self.activation_function=lambda x:scipy.special.expit(x)
def train(self,inputs_list,targets_list):# 訓練
#入力リストを行列に変換する 転置
inputs=np.array(inputs_list,ndmin=2).T
targets=np.array(targets_list,ndmin=2).T
#隠れ層への入力信号
hidden_inputs=np.dot(self.w_ih,inputs)
#隠れ層で結合した入力信号を活性化関数に通し、出力信号を作る
hidden_outputs=self.activation_function(hidden_inputs)
#出力層への入力信号
final_inputs=np.dot(self.w_ho,hidden_outputs)
#出力層で結合した入力信号を活性化関数に通し、出力信号を作る
final_outputs=self.activation_function(final_inputs)
#出力層の誤差
output_errors=targets-final_outputs
#隠れ層の誤差は出力層の誤差を重みの割合で分配する
hidden_errors=np.dot(self.w_ho.T,output_errors)
#隠れ層と出力層の重みを更新する
self.w_ho+=self.lr*np.dot((output_errors*final_outputs*(1.0-final_outputs)),np.transpose(hidden_outputs))
#入力層と隠れ層の重みを更新する
self.w_ih+=self.lr*np.dot((hidden_errors*hidden_outputs*(1.0-hidden_outputs)),np.transpose(inputs))
def predict(self,inputs_list):# 予想
#入力リストを行列に変換する 転置
self.inputs=np.array(inputs_list,ndmin=2).T
#隠れ層への入力信号
hidden_inputs=np.dot(self.w_ih,self.inputs)
#隠れ層で結合した入力信号を活性化関数に通し、出力信号を作る
hidden_outputs=self.activation_function(hidden_inputs)
#出力層への入力信号
final_inputs=np.dot(self.w_ho,hidden_outputs)
#出力層で結合した入力信号を活性化関数に通し、出力信号を作る
final_outputs=self.activation_function(final_inputs)
return final_outputs
input_nodes=28*28# 入力層ノード数
hidden_nodes=100 # 隠れ層ノード数
output_nodes=10 # 出力層ノード数
learning_rate=0.3# 学習率
# ニューラルネットワークのインスタンスを作成
n=neuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
# 入力データ MNIST問題
training_data_file = open(r"C:/MyPythonScripts/data/mnist_train.csv", 'r')
training_data_list=training_data_file.readlines()
training_data_file.close
for record in training_data_list:
all_values=record.split(",")
#スケーリング
inputs=(np.asfarray(all_values[1:])/255.0*0.99)+0.01
targets=np.zeros(output_nodes)+0.01
targets[int(all_values[0])]=0.99
n.train(inputs,targets)
pass
# MNISTのデータを読み込む
test_data_file =training_data_file = open(r"C:/MyPythonScripts/data/mnist_test.csv", 'r') # 開く
test_data_list = test_data_file.readlines()#リストを作る
test_data_file.close() #閉じる
# モデルを検証する
# スコア用の空リストを用意しておく
scorecard = []
# テストデータをモデルに順次流し込む
for record in test_data_list:
# 訓練データと同様にcsvをカンマで区切ったリストを作成する
all_values = record.split(',')
# 正解を読み込む(リストの最初に書いてある strの状態なのでintする)
correct_label = int(all_values[0])
# 256のグレイスケールをスケーリングして 0.01から1.00の間に入るようにする
inputs = (np.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
# いよいよ テストデータをpredict()に流し込み、出力を得る
#[[0.00729657],[0.00312938],[0.00761386],[0.00711368],[0.00103126],
# [0.02268093],[0.00364922],[0.99758126],[0.00411096],[0.01630374]]
outputs = n.predict(inputs)
# 出力リストのなかで一番大きい値のインデックス番号抜き出す
label = np.argmax(outputs)
if (label == correct_label):# 予測した数字labelと正解が一致した場合
scorecard.append(1) # スコアカード(リスト)に要素として1をアペンドする
else: # 予測した数字labelと正解が一致しない場合
scorecard.append(0) # スコアカード(リスト)に要素として0をアペンドする
pass
pass
# 正解率を算出する
scorecard_array = np.asarray(scorecard) # asarray はarray(a, copy=False)と同じ
print ("performance = ", scorecard_array.sum() / scorecard_array.size)# 正解要素1を全部足して、要素全体の数で割る
# http://pjreddie.com/media/files/mnist_train.csv
# http://pjreddie.com/media/files/mnist_test.csv
# 数字データを可視化する
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
data_file=open(r"C:/MyPythonScripts/data/mnist_test.csv", 'r')
data_list=data_file.readlines()
data_file.close()
all_values=data_list[1].split(",")
image_array=np.asfarray(all_values[1:]).reshape((28,28))
plt.imshow(image_array,cmap="Greys",interpolation="None")