前回、Sony製の深層学習フレームワーク”NNable”で学習から推論まで実践するチュートリアル記事を書きました↓
【NNabla】実践!Neural Network Librariesで学習から推論まで|はやぶさの技術ノート
最終的に満足するモデルを生成できたので、学習済みモデルの重みを”MyChain.h5”に保存して終了しました。
今回は、この学習済みモデルを使って学習せず、いきなり推論から始める方法を説明します。
nnablaの各モジュールをimportします。
Solvers(最適化アルゴリズム)は推論では使いません。
import nnabla as nn
import nnabla.functions as F
import nnabla.parametric_functions as PF
# import nnabla.solvers as S
その他、今回使用する(定番)モジュールもimportします。
import numpy as np
import matplotlib.pyplot as plt
batch_size = 1
x = nn.Variable((batch_size, 1))
今回の場合、”学習済みモデル”というのは”重み”情報のみを保存したものです。
つまり、ニューラルネットワークの構造(アーキテクチャ)の情報までは保存していません。
そのため、改めて”重み”を格納するためのニューラルネットワークを生成する必要があります。 (なので関数化しておくと便利です)
def MyChain(x):
h1 = F.relu(PF.affine(x, 50, name = "l1"))
h2 = F.relu(PF.affine(h1, 100, name = "l2"))
y = PF.affine(h2, 1, name = "l3")
return y
前回生成した学習済みモデルの”重み”を”MyChain.h5”は、以下のコード1行でロード完了!
nn.load_parameters("MyChain.h5")
y = MyChain(x)
本来はセンサ値を使うが、今回は適当な学習で使用していない未知のデータを生成した
xe = np.array([[0.5], [1.8], [2.3], [3.3], [4.5], [5.4], [6.3], [6.7], [7.4], [8.2]])
y_list = []
for i in xe:
x.d = i
y.forward()
y_list.append(y.d.copy())
推論結果を確認します
print(xe)
y_list
前回と同じ結果を得られました。一応グラフ化までしてみます。
yt = np.reshape(y_list, [10, 1])
# plt.plot(x, y)
plt.plot(xe, yt)
plt.plot(xe, yt, "ro")
plt.title("Predict")
plt.xlabel("input")
plt.ylabel("output")
plt.grid(True)
plt.show()
ばっちりですね!もう少し分かりやすく確認するため、学習で使用したデータ(x=0~9の整数値)でも推論してみます。
yt_list = []
xt_list = []
for i in range(10):
x.d = i
y.forward()
yt_list.append(y.d.copy())
xt_list.append(i)
yt_list = np.reshape(yt_list, [10, 1])
# plt.plot(x, y)
plt.plot(xt_list, yt_list)
plt.plot(xe, yt, "ro")
plt.title("comparison")
plt.xlabel("input")
plt.ylabel("output")
plt.grid(True)
plt.show()
yt_list
青線が学習データ(x=0~9の整数値)の推論結果、赤点が未知のデータに対する推論結果です。
一応、前回作成したグラフ↓と見比べてみます。うん!赤プロットの位置が一致してるのでOK!!
前回、学習済みモデルの”重み”のみをHDF5ファイルで保存しました。
今回は、”*.nnp(Neural Network Librariesモデルファイル)”で保存します。
”*.nnp”なら、”重み”+ネットワーク構造(アーキテクチャ)の情報を保存できるため、
ソースコード上でニューラルネットワークを定義せずに推論が行えるようになります。
つまり、コンパクトなソースコードで推論が行えます。
import nnabla.utils.save
# Save NNP file (used in C++ inference later.).
contents = {
'networks': [
{'name': 'MyChain',
'batch_size': batch_size,
'outputs': {'y': y},
'names': {'x': x}}],
'executors': [
{'name': 'runtime',
'network': 'MyChain',
'data': ['x'],
'output': ['y']}]}
nnabla.utils.save.save('MyChain.nnp', contents)
↑のようにJSONフォーマットでnnpファイルの情報を記述して、
ニューラルネットワークの情報(重み+構造)を”MyChaine.nnp”に保存します。
次回は、nnpファイルで推論するかー
学習にはマシンパワーが必要です。しかし、組込み機器(エッジディバイス)は基本的に低コスト/低消費電力/小型化が求められます。
そのため、組込み機器では”学習済みモデル”を使って推論のみ行うのがスマートだと考えています。