【Chainer実践編ラスト】セーブ出来たらいいよね。Serializerで学習結果をセーブ&ロード!

【Chainer実践編ラスト】セーブ出来たらいいよね。Serializerで学習結果をセーブ&ロード!

人生にセーブとロードがあれば、どれだけいいでしょう。
自分なら、ボス戦の前か女性に係わる日の朝は絶対セーブします。

別枠でセーブします。

アイーンです。

 

今日は実践編のラストです。

別ファイルで行った学習の結果をセーブして、別のファイルで使用できるようにしたいと思います。

そのために必要なモジュール、Serializer(シリアライザー)をご紹介します。

 

皆さんも一緒に、PyCharmを起動してプロジェクトを立ち上げてお待ちください。

一応プロジェクトの立ち上げ方から書いときます。

 

File-New Project…

プロジェクト名は何でもいいです。

今回は「classification」としました。

空っぽのプロジェクトが出来たら…

 

プロジェクト名を右クリックしてNewからPython fileを選択です。

 

とりあえずiris_saveと名付けました。

 

Serializerでコードを書き換えて試してみよう。

ここでも、実践編を通してお世話になったアヤメの品種分類データを使います。

サンプルとして、前回のTrainerを使ったコードを載せておきますので

コピーして使ってください。

import chainer
import chainer.links as L
import chainer.functions as F
from chainer import Variable,Chain,optimizers

from chainer.datasets import tuple_dataset
from chainer import training, iterators
from chainer.training import extensions

import numpy as np

from sklearn import datasets

IrisData = datasets.load_iris()
x = IrisData.data.astype(np.float32)
t = IrisData.target
n = t.size

t_matrix = np.zeros(3 * n).reshape(n, 3).astype(np.float32)

for i in range(n):
    t_matrix[i, t[i]] = 1.0

index = np.arange(n)
index_train = index[index % 2 != 0]
index_test = index[index % 2 == 0]

x_train = x[index_train, : ] #入力データ(訓練用)
t_train = t_matrix[index_train, : ] #正解データ(訓練用)
x_test = x[index_test, : ] #入力データ(テスト用)
t_test = t[index_test] #正解データ(テスト用)

train = tuple_dataset.TupleDataset(x_train, t_train)

x_test_v = Variable(x_test)


class IrisLearn(Chain):
    def __init__(self):
        super(IrisLearn, self).__init__(
            l1=L.Linear(4, 6),
            l2=L.Linear(6, 6),
            l3=L.Linear(6, 3),
        )

    def __call__(self, x, t):
        return F.mean_squared_error(self.predict(x), t)

    def predict(self, x):
        h1 = F.sigmoid(self.l1(x))
        h2 = F.sigmoid(self.l2(h1))
        h3 = self.l3(h2)
        return h3

model = IrisLearn()
opt = optimizers.Adam()
opt.setup(model)

train_iter = iterators.SerialIterator(train, 30)
updater = training.StandardUpdater(train_iter, opt)
trainer = training.Trainer(updater, (5000, 'epoch'))
trainer.extend(extensions.ProgressBar())
trainer.run()

model.cleargrads()
y_test_v = model.predict(x_test_v)
y_test = y_test_v.data

correct = 0
count = y_test.shape[0]

for i in range(count):
    maxIndex = np.argmax(y_test[i, :])
    print(y_test[i, :], maxIndex)
    if maxIndex == t_test[i]:
        correct += 1

print("正解数 ", correct, ",問題数 ",count , ", ", correct/ count * 100,"%")

これで、準備完了です。

 

学習済みデータをセーブしてみよう!

ここからコードを少し書き換えます。

 

from chainer import Variable,Chain,optimizersの後に

,serializers

を追加しましょう。

 

そして、trainer.run()から下の部分を全て削除します。

この部分は、学習結果をテストする部分です。

今回はテスト部分を別ファイルで実行するため、この部分を削除し、セーブするためのコードを記述します。

 

serializers.save_npz("iris_savedata.npz",model)

(“ファイル名” , Chainインスタンス)を指定します。

ファイルの名前は何でも結構です。npzという拡張子で保存されます。

ここでは、学習を行った”model”をセーブすることになります。

書き換えが済んだら、コードを実行してください。

 

RunからRunを選択し

iris_save(書き換えたファイル)を選択し実行

 

 

すると…

 

classificationの中にiris_savedata.npzというファイルが出来上がります!

これでセーブは完了です!

 

それではロードに移りましょう。

 

学習済みファイルをロードしてみよう

ここで、新しいPythonファイルを作ります。

 

classificationを右クリックしてNewからPython Fileを選択

先ほどと同じですね。

 

今回はファイル名をiris_loadとして作成しました。

そしてiris_loadに、また最上部のサンプルコードを全部貼り付け…

 

またserializersの追加を忘れずに行い…

 

今度は学習部分を全て削除します。

 

学習済みのデータを使うから、学習させる必要など欠片もありません。

用済みです。

 

そして、代わりにコレを書きます。

 

 

serializers.load_npz("iris_savedata.npz", model)

iris_savedata.npzmodelに読み込みます。

 

これで全て完了です。

実行すると、別ファイルで学習が済んだmodelを使用してテストを実行してくれます。

さぁ結果は??

 

 

減っとるやん

減っとるやんか

 

この正解数の減少は、コードの変更には関係なく

学習結果のブレによるものであることが分かっています。

でもなんか悲しいよね…。

 

さて、これで貴方の肩書に”シリアライザー”が追加されました。

もちろん朝食は”ケロッグ・コーンフロスティ”です。

 

ここまでくれば、Chainer使えますと言っていいと思います。

そろそろ本格的に、面白いことやってみましょうか。

 

それでは。