SIGMA-SE Math & Tech Library

SIGMA-SE Math & Tech Library


数学と情報技術をテーマに、書籍や教材だけではつかみにくい考え方を具体例とともに簡潔にわかりやすく伝える解説サイトです。
技術の歴史や背景、関連知識の整理、学習のための覚書や要約記事も掲載しています。

Python - ニューラルネットワーク:6/14 MNIST推論処理の実装

概要

MNISTデータを使い、学習済みの重みパラメータによるニューラルネットワークの推論処理を整理する。

推論とは、入力データをネットワークに通し、最終的な出力から予測結果を得る処理となる。

ここでは、入力層、中間層、出力層の計算を関数化し、手書き数字画像に対する予測の流れを確認する。

この記事の構成

概念の説明と実装サンプル

推論処理の実行準備

推論処理のニューロン構成と関数定義

  • ネットワーク構成と関数
    • ニューロン構成について
      入力層:784個(画像データ28 x 28 = 784(px))
      隠れ層1:50(任意の値)
      隠れ層2:100(任意の値)
      出力層:10(数字0~9の10クラス)

    • 実装サンプル(関数定義)
      以下、ch03/neuralnet_mnist.py内の3つの関数定義。

      import sys, os
      sys.path.append(os.pardir) # 親ディレクトリのファイルをインポートするための設定
      import numpy as np
      import pickle
      from dataset.mnist import load_mnist
      from common.functions import sigmoid, softmax
      
      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_test
      
      def init_network():
          with open("sample_weight.pkl", 'rb') as f:
              network = pickle.load(f)
          return 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
      

      init_network()では、pickleファイルとなるsample_weight.pklを読み込んでいる。

      ※ pickleファイルには、重みとバイアスのパラメータがdictionary型で保存されている。信頼できないpickleは任意のコードを実行する危険があるため、配布元を確認したファイルだけを読み込む。
      ※ predict(network, x)のsigmoid, softmaxについては、下記を参考。
      Python - ニューラルネットワーク: ニューラルネットワークの活性化関数と実装サンプル
      Python - ニューラルネットワーク: 活性化関数の実装サンプルまとめ(ステップ、シグモイド、ReLU、恒等関数、ソフトマックス関数)

推論処理の実行

  • 推論処理と認識精度
    • ch03/neuralnet_mnist.py内の実行処理

      x, t = get_data()    # … 1.
      network = init_network()    # … 2.
      
      accuracy_cnt = 0
      for i in range(len(x)):    # … 3.
          y = predict(network, x[i])    # … 4.
          p= np.argmax(y)    # … 5.
          if p == t[i]:    # … 6.
              accuracy_cnt += 1    # … 7.
      
      print("Accuracy:" + str(float(accuracy_cnt) / len(x)))    # … 8.
      
    • 実行処理の解説

      1. get_data()でMNISTデータセットを取得。
      2. init_network()でpickleファイルを読み込む。
      3. \(x\)のテスト画像データ10,000枚をfor文でループ。
      4. 1枚の画像データに対してpredict(network, x[i])を実行し、下記のNumPy配列のように数字0~9それぞれの確率を出力。
        ※ 0である確率:20%、1である確率:10%、2である確率:4%、… 9である確率:5%
        [ 0.2, 0.1, 0.04 , … , 0.05  ]    # 0 ~ 9 それぞれの確率 (20%, 10%, 4%,  … , 5%)
        
      5. 「4.」の結果であるNumPy配列\(y\)に対して、最も確率が高い要素のインデックスを取得。
      6. 推論処理出した「5.」の予測結果が正解ラベル\(t\)と一致しているかチェック。
      7. 一致していれば、正解数を加算。
      8. 最後に正解率を出力。
    • 実行結果
      実際に上記を対話モードで実行するとAccuracy:0.9352が出力される。

      $ cd gitlocalrep
      $ cd deep-learning-from-scratch/ch03
      $ source /var/www/vops/bin/activate
      $ python neuralnet_mnist.py
      Accuracy:0.9352
      

      上記実装サンプルでは、93%程度の精度だったが、実際のニューラルネットワークでは、さらにニューラルネットワークの構造や「4.」の関数predict内の処理にあたる学習方法を工夫し、99%以上の精度を出していく。

まとめ

  • 推論は学習済みの重みを使って予測を得る処理であり、学習のように重みを更新しない。
  • 各層では、行列積、バイアス加算、活性化関数の適用を順に行う。
  • 入力、重み、バイアスのshapeが一致しないと行列計算でエラーになるため、各層の次元を確認。
  • 出力値の中で最大となる位置をargmaxで求め、予測クラスとして扱う。

参考文献

この記事を共有
Xで共有 Facebookで共有 LINEで共有



Copyright SIGMA-SE All Rights Reserved.
s-hama@sigma-se.jp