SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

Windowsで「nnabla_cli.exe」を使い、学習結果を再利用して推論する。/Neural Network Console応用編

Neural Network Consoleで学習した結果を再利用し、Windows上でEXCELのマクロ(VBA)などから外部プログラムとして呼び出して実行することができます。

今回はその方法についてまとめます。

f:id:arakan_no_boku:20190326212937j:plain

 

Windows版とクラウド版でやり方が違います

 

学習済モデルの再利用は、ニューラルネットワークコンソールのクラウド版とWindows版の両方で可能なので、両方のやり方を併記するようにします。

推論を外部で実行できるプログラムは「nnabla_cli.exe」です。

nnabla_cli.exeは、Neural Network Librariesに含まれています。 

NNC(ニューラルネットワークコンソール)には付属してません。

まだの方は、まず、Neural Network Librariesをインストールする必要があります。

arakan-pgm-ai.hatenablog.com

なお。

今回の説明用のサンプルは、LeNetプロジェクトで、MNISTのフル(0-9)を学習データにしているので、テスト用データもMNISTの手書き数字画像を使います。 

あと、c:\tmpフォルダを作業フォルダにした前提で書いてます。

環境にあわせて、読み替えてください。 

 

クラウド版のやり方

 

クラウドへのログインや学習の実行などは、別記事を参考にしてください。

arakan-pgm-ai.hatenablog.com 

学習済のモデルとパラメータをダウンロードします。 

プロジェクト名をクリックして開き、TRAININGタブを開きます。

f:id:arakan_no_boku:20171110234607j:plain

 

学習結果の右上のあたり(上図の赤枠)に「・・・」というマークがあります。 

こいつをクリックすすると、「Download」というのがでてきます。

f:id:arakan_no_boku:20171110234846j:plain

 

こいつを押すと、「result.nnp」ファイルをダウンロードできます。

nnpファイルというのは、NNablaのC++モジュールで読み込める形式で、pythonモジュールの「net.nntxt」と「parameters.h5」をZIP(くっつけた)感じのものみたいです。

f:id:arakan_no_boku:20171110235148j:plain

 

今回は、ダウンロードしたresult.nnpを作業フォルダ(C:\tmp)にコピーして、結果ファイルもここにアウトプットさせるように します。

そうすると、「nnabla_cli.exe」にあたえるファイルの配置とファイル名情報は以下のようになります。

  • nnpファイル:c:\tmp\result.nnp (クラウドからダウンロードしたもの)
  • 対象データ・セットCSVc:\tmp\mnist_test.csv  
  • 結果出力フォルダ:c:\tmp

 この場合、nnabla_cli.exe の実行時パラメータは以下のようになります。

nnabla_cli forward -c c:\tmp.result.nnp -d c:\tmp\mnist_test.csv -o c:\tmp

 

Windows版の場合

 

Windows版の方では、nnpファイルはできません。 

プロジェクトファイルのあるフォルダに、「プロジェクト名.files」のフォルダ(例えば

LeNet.sdcprjなら、LeNet.filesというフォルダ名になります)ができて、そこに、net.nntxtファイルと、parameters.h5というファイルができますので、それを使います。

 

net.nntxtファイルと、parameters.h5を作業用フォルダにコピーします。 

データ・セット.csvやアウトプットフォルダは同じです。 

なので、今回の例で、Windows版の場合はこんな感じ。 

  • nntxtファイル:c:\tmp\net.nntxt (モデル等が定義されてます)
  • h5ファイル:c:\tmp\parameters.h5 (学習済パラメータが保存されています)
  • 対象データ・セットCSVc:\tmp\mnist_test.csv  
  • 結果出力フォルダ:c:\tmp

この場合、nnabla_cli.exe の実行時パラメータは以下のようになります。

nnabla_cli forward -c c:\tmp\net.nntxt -p c:\tmp\parameters.h5 -d c:\tmp\mnist_test.csv -o c:\tmp

 

以降は、クラウド版とWindows版で共通です。 

 

どちらも実行すると、以下のようなログを出力しながら、推論を行います。

f:id:arakan_no_boku:20171223093050j:plain

 

output_result.csv

 

推論した結果は、output_result.csv に出力されます。 

内容はこんな感じで、正味の演算結果が出力されてます。

f:id:arakan_no_boku:20171223134340j:plain

ありがちな、「Accuracy 0.99」等の結果表示はありません。 

そうなんです。 

nnabla_cli.exeで推論した場合、その結果をどのように処理するかは、利用者側に委ねられています。 

だから、一致しているかどうかは、MNISTの場合だとoutput.csvを読み込んで、y_0からY_9までの結果のMAXをとって、そのインデックスがy:labelと一致しているかどうかの判断をしてやる必要があります。 

一見、面倒なようですが・・違います。 

あまり、結果出力までガチガチになってたら、他のことに使えません。 

応用性を考えると、こうなっていないと、いけないのです。

 

工夫次第で、応用の可能性が広がります

 

ニューラルネットワークコンソールのWindows版でもクラウド版でもそうです。 

GUIで設計して学習させて、その学習済のモデルとパラメータを保存して、外部に持ち出す。 

そこで、新たなデータに対して、nnabla_cli.exeを動かして推論する。 

あとは、その結果を使って、どう処理するか? 

それだけを考えれば、ディープラーニングを使った簡単な応用機能が実装できてしまうということですものね。 

例えば。 

正常品と不良品の画像を学習させておいて、新たに作った製品の画像で推論して、結果を使って正常品か不良品かを自動分別させるみたいな。 

そういうのを、とりあえずプロトタイプで作ってみて、あれこれ検討するレベルなら、BATファイルと簡単なスクリプトで、1日くらいでできてしまいそうな気もしますね。 

なかなか面白いんじゃないですかね。

 

Accuracyを求める

 

まあ、そういう応用を考えるのは別の機会として、今回は、Accuracy(正確さ)を求める部分だけ、pythonで書くことにします。 

やることは、CSVファイルを読み込んで、行単位でマッチしているかを確認して、最終的に率を計算するだけです。 

ごくシンプルなプログラムなので、全文掲載します。

import csv, os
import numpy as np

total_cnt = 0
match_cnt = 0
csv_filename = "output_result.csv"
csv_obj = open(csv_filename)
reader_obj = csv.reader(csv_obj)
for row in reader_obj:
    if reader_obj.line_num == 1:
        continue # 最初の行をスキップする
    org_label = int(row[1])
    results = np.array(row[2:11],np.float32)
    result_label = int(results.argmax())
    total_cnt += 1
    if (org_label == result_label):
        match_cnt += 1

print("match_cnt={0} : total_cnt={1}".format(match_cnt,total_cnt))
print("Accuracy:{}".format(match_cnt / total_cnt))
csv_obj.close()

 

今回のoutput._resultcsvがこんなCSVデータなので。

x:image,y:label,y'__0,y'__1,y'__2,y'__3,y'__4,y'__5,y'__6,y'__7,y'__8,y'__9
C:\tmp\validation\7\0.png,7,2.92585286843e-06,5.29832504981e-07,1.07607429527e-05,9.61509499575e-07,3.85432130656e-08,6.40837924948e-08,3.93514353048e-11,0.999976873398,4.44045333836e-08,7.8247185229e-06

 

y:labelにあたる2列名(行の配列だと row[1])を、正解として。 

softmaxの出力である、y'_0 から y'_9が3列目から12列目までに収まっているので、pythonのslice機能を使って、row[2:11]で取り出して、numpy配列におさめています。 

ここだけわかれば、後は、argmaxで最大値のインデックスを取り出して、ラベルと比較してマッチしてればカウントしているだけなので、特に悩むこともありません。 

これを、動かすと以下のような出力になります。

f:id:arakan_no_boku:20171223222554j:plain

 まあまあですかね。