[Python] AI 10 Chainer + MNISTによる深層学習 Flaskベースアプリの導入

[macOS Catalina 10.15.7]

教本では次はRaspberry PiにFlaskベースの画像認識アプリを導入するといった内容になっています。

Raspberry PiがなくてもDockerを使えばMacにアプリを導入できるとのことでしたが、私の環境では不可でした。macOSでは使えないapt-getコマンドでライブラリを導入する必要が生じたためです。

今はPython3.9.5を使っているのですが、エラーメッセージによると何故かpython3.5のライブラリを探しているようです。pip.confの設定を変えて無理やり下記のパスにOpenCVを入れたものの、エラーは変わらずでした。

手元にRaspberry Piがないので次に進むことにします。

2021/10/5追記:apt-getコマンドはDockerコンテナのDebian環境で使うことが分かりました。仮想環境について理解できていませんでした。次回記事に詳細を記しています。

Traceback (most recent call last):
File "app.py", line 10, in <module>
   import cv2
File "/usr/local/lib/python3.5/site-packages/cv2/__init__.py", line 5, in <module>
   from .cv2 import *
ImportError: libGL.so.1: cannot open shared object file: No such file or directory
apt-get install libgl1-mesa-dev

[Python] AI 09 Chainer + MNISTによる深層学習 学習済モデルの使用

作成した学習モデルを使って検証を実施しました。

教本ではGoogle Colaboratoryに学習モデルを保存して使っていますが、私の場合はJupyter Notebookではなくpyenv環境のPythonなので、ローカルに学習モデルファイルを置いています。

検証用関数 testEpochを引数なしにするなど少し書き換えました。

import chainer
import chainer.links as L
import chainer.functions as F
from chainer import iterators
import numpy as np
from chainer.dataset import concat_examples
from chainer import serializers

class MLP(chainer.Chain):
    def __init__(self, number_hidden_units=1000, number_out_units=10):
        super(MLP, self).__init__()

        with self.init_scope():
            self.layer1=L.Linear(None, number_hidden_units)
            self.layer2=L.Linear(number_hidden_units, number_hidden_units)
            self.layer3=L.Linear(number_hidden_units, number_out_units)

    def __call__(self, input_data):
        result1 = F.relu(self.layer1(input_data))
        result2 = F.relu(self.layer2(result1))
        return self.layer3(result2)

def testEpoch():
    # 検証用誤差と精度
    test_losses = list()
    test_accuracies = list()
    i = 1
    while True:
        test_dataset = test_iterator.next()
        test_data, test_teacher_labels = concat_examples(test_dataset)

        # 検証データをモデルに渡す
        prediction_test = model(test_data)

        # 検証データに対して得られた予測値と正解を比較し損失を算出する
        loss_test = F.softmax_cross_entropy(prediction_test, test_teacher_labels)
        test_losses.append(loss_test.data)

        # 精度を計算する
        accuracy = F.accuracy(prediction_test, test_teacher_labels)
        test_accuracies.append(accuracy.data)

        print(f'{i}回目 検証損失:{np.mean(test_losses):.4f} 検証精度:{np.mean(test_accuracies):.2f}')

        if test_iterator.is_new_epoch:
            loss_and_acciracy = [np.mean(test_losses),np.mean(test_accuracies)]
            test_iterator.reset()
            print(loss_and_acciracy)
            print('\n', end='')
            break

        i = i + 1
    return loss_and_acciracy

train_data, test_data = chainer.datasets.get_mnist(withlabel=True, ndim=1)

model = MLP()
serializers.load_npz('chainer-mnist.model', model)

BATCH_SIZE = 100
test_iterator = iterators.SerialIterator(test_data, BATCH_SIZE,
repeat=False, shuffle=False)

loss_and_acciracy = testEpoch()
print(f'検証損失&検証精度 loss_and_acciracy {loss_and_acciracy}')

# 5000番目のデータを検証する
data_location = [5000]
predict_data, predict_lable = test_data[data_location]

plt.imshow(predict_data.reshape(28, 28), cmap='gray')
plt.show()
print(f'検証画像:{predict_lable[0]}')

predict_data = predict_data[None, ...]
predict = model(predict_data)
result= predict.array
print(result)

probable_label = result.argmax(axis=1)
print(f'予測結果:{probable_label[0]}')
--------------------------------------------------

出力(後半のみ)
--------------------------------------------------
検証損失&検証精度 loss_and_acciracy [0.25712144, 0.9276001]
検証画像:3
[[ 0.28669706 -2.4434075  -0.32302654  5.68949    -0.95883775  4.6307244
  -3.47152    -3.0863516   1.5918074  -1.1413323 ]]
予測結果:3