MNIST

さいしょにやるプログラミング例は、
たぶん、 print(‘Hello World’)だったりする。

で、機械学習の’Hello World’的なものは、
MNISTという説もある。

MNISTには、機械学習を行うためのプログラミングと、
基本的なデータ・セットがそろっている。

けれど、チュートリアルをやるものの、イマイチどういうふうになっているのか、視覚的に、わからなない。

ここでは、そういうことを、たしかめながら、まとめてみようとおもう。

 

(1)「ゼロから作る Deep Learing」のGit Hub上にあるファイルを使ってみる。

 

まずは、Git Hubからダウンロードしたファイルを、ユーザーのディレクトリに置く。あとは、以下、Anaconda Juputernotebookからの作業となる。

import os
os.chdir('/Users/tsurumakifumiaki/deep-learning-from-scratch-master/dataset')
# カレントディレクトリをdatasetに変更
from mnist import load_mnist 
#mnistからload_mnist関数をインポートする

(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
# load_mnist関数によりデータセットが読み込まれる(引数は読み込みの際の設定)。
# データは(x_train, t_train), (x_test, t_test)に、それぞれ返される。

print(x_train.shape)
(60000,784)
# 訓練データの数字の画像データ、784個の値のリストが60000個ある

print(t_train.shape)
(60000,)
# その画像の数字、、スカラーが60000個ある

print(x_test.shape) 
(10000,784)
# テストデータの数字の画像データ、784個の値のリストが10000個ある

print(t_test.shape)
(10000,)
# その画像の数字、、スカラーが60000個ある

 

では、じっさいの格納されている画像データをみてみよー。

x_train_number =x_train[5323]

x_train_number

5323番目の文字。784個の値が集合している。
0(まっ白)から、784(まっ黒)、そのあいだの灰色の階調を表す数字が並んでいる。



といっても、コンピュータが認識できても、
ひとの視覚では確認できない。確認できるようにしてみよー。

import matplotlib.pyplot as plt

plt.imshow(train_number_image, cmap = plt.cm.binary,
           interpolation='nearest')

画像は、以下のとおり、3であった。

ちなみに、教師データのラベルも3となっている。

t_train_number =t_train[5323]

t_train_number 

3

# ちゃんと3nの「タグ」が貼られている。


(2)推論処理を行う

 

GitHub上の「ゼロから作るDeepLearning」のフォルダーの中に、訓練用のバイアスと重みのデータが入ったファイルが用意されている。

場所:
deep-learning-from-scratch-master/ch03/sample_weight.pkl

まずは、そのファイルを変数 networkに代入する。

import pickle
with open("sample_weight.pkl", 'rb') as f:
network = pickle.load(f)

スケール感を、たしかめてみよう。

まずは重みの数

len(network['W1'])
784

len(network['W2'])
50

len(network['W3'])
100

 

つぎにバイアスの数

len(network['b1'])
50

len(network['b2']
100

len(network['b3'])
10

 

オッケー、では実装してゆこう。

def get_data():
    (x_train, t_train),(x_test,t_test)=\
    load_mnist (normalize=True,flatten=True,one_hot_label=False)
    return x_test,t_tes

def init_network():
    with open("sample_weight.pkl", 'rb') as f:
        network = pickle.load(f)
    return network

import numpy as np

# シグモイド関数の実装
def sigmoid(x):  
    return 1/(1+np.exp(-x))

# ソフトマックス関数の実装
def softmax(a): 
    exp_a = np.exp(a)
    sum_exp_a = np.sum(exp_a)
    y=exp_a / sum_exp_a
    return y

# 各層で、変数network内にある重みとバイアスを加えていく。
# それぞれの値はシグモイド関数、最後はソフマップ関数を通す。

def predict(network,x):
    w1,w2,w3=network['W1'],network['W2'],network['W3']
    b1,b2,b3=network['b1'],network['b2'],network['b3']
    a1=np.dot(x,w1)+b1
    z1=sigmoid(a1)
    a2=np.dot(z1,w2)+b2
    z2=sigmoid(a2)
    a3=np.dot(z2,w3)+b3
    y=softmax(a3)
    return y


# MNISTデータを取得しxとtに返す
x,t = get_data()

# 重みとバイアスのデータを変数networkに代入する
network = init_network()

# for文により、xに格納された画像データを1枚ずつ取り出し、predict関数により、
# ファイルに用意されている重みとバイアスが試される。
accuracy_cnt ==0
for i in range(len(x)):
    y=predict(network, x[i])
    p=np.argmax(y)
    
    if p==t[i]:
        accuracy_cnt += 1

print(str(float(accuracy_cnt)/len(x)))

0.9533

まとめ▼

さいごのコードは、784枚の画像データに重みとバイアスを付けた最大の値(いちばん高い確率の値)が出力されている、たぶん。このへんが、うまく理解できていなかったりする〜

気づいたことを、お気軽に。
公開まで、やや時間がかかりまーす!