In [10]:
# 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
    
In [11]:
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
In [12]:
# 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()                     #閉じる
In [37]:
# モデルを検証する

# スコア用の空リストを用意しておく
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
In [16]:
# 正解率を算出する
scorecard_array = np.asarray(scorecard) # asarray はarray(a, copy=False)と同じ
print ("performance = ", scorecard_array.sum() / scorecard_array.size)# 正解要素1を全部足して、要素全体の数で割る
performance =  0.9454
In [38]:
# http://pjreddie.com/media/files/mnist_train.csv
# http://pjreddie.com/media/files/mnist_test.csv
In [47]:
# 数字データを可視化する
%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")
Out[47]:
<matplotlib.image.AxesImage at 0x19b61fcf358>