catch-img

CONEXIOBlackBearで機械学習モデルを動かす

こんにちは。コネクシオIoTブログ 技術記事担当のHです。

さて、今回はCONEXIOBlackBearで機械学習モデルを動かす話をいたします。

CONEXIOBlackBear は、画像認識・予知保全・AIによるリアルタイム検知などの用途で活用できるエッジコンピューティングゲートウェイです。これらの用途においてはすでに活用されており、また、今後も拡大が見込まれる技術の1つとして画像認識の機械学習モデルがありますが、私自身はまだCONEXIOBlackBear上で動かしたことがありません。

そこで、本記事では、CONEXIOBlackBear上で画像認識の機械学習モデルを動かし、USBカメラにて撮影した画像をリアルタイムに認識させてみたいと思います。


0. 実施環境

  • CONEXIOBlackBear OSバージョン 1.1.5
  • Python3.5
  • tensorflow 2.0.0(keras 2.2.4)
  • USB接続のWebカメラ


1. 学習データとモデルの作成

1.1 学習データ

ここでは、CIFAR-10というデータセットを用います。

CIFAR-10は、10種類に分類した学習用5万枚、テスト用1万枚からなる合計6万枚の画像データセットです。詳細はリンク先をご覧ください。


1.2 モデル

ニューラルネットワークを記述するためのPythonライブラリkerasにサンプルとして含まれているcifar10_cnn.pyを用います。したがって、kerasによって記述されたモデルになります。

このサンプルは、https://github.com/keras-team/keras/tree/2.2.4をダウンロードして展開したものの中のexamplesというフォルダに入っています。

モデルの構造は、cifar10_cnn.pyの名前からわかる通り、畳み込みニューラルネットワーク(Convolutional Neural Network、CNN)です。

入力画像は32*32ピクセルのカラー画像(RGB)です。

層構成は、以下のようになっています。

①畳み込み層(32*32*3入力、32チャネル出力)

②畳み込み層(32チャネル出力)

③MaxPooling層(サイズ2*2)

④畳み込み層(64チャネル出力)

⑤畳み込み層(64チャネル出力)

⑥MaxPooling層(サイズ2*2)

⑦全結合層(512ユニット)

⑧全結合層(10ユニット=分類の数)

畳み込み層のフィルタサイズは3*3です。活性化関数は、最終出力以外はReLUで、最終出力は、多クラス分類なのでsoftmax関数です。MaxPooling層の後ろと全結合層の間にDropout層があります。


1.3 学習

学習は、cifar10_cnn.pyで実行可能ですので、自分でコーディングせずそのまま動かします。学習回数は50epochとしました。この回数だと精度が75%程度だとサンプルのソースコード内に注意書きがありますが、今回はサンプルの動作確認ですので、精度にこだわらず、50エポックでよしとします。実際にやってみたところ79%となり、やはり注意書きの通りといったところです。

学習は、膨大な計算が必要なため、一般にエッジデバイスではなく、計算リソースの豊富な環境で行うことが一般的です。そのため、CONEXIOBlackBearではなく、手元のPCにて行いました。所要時間はおよそ1.5hでした。

  • MacBook Pro
  • Windows10(bootcamp)
  • Python3.7
  • tensorflow 2.0.0(keras 2.2.4)



2. CONEXIOBlackBear上で動作させる

2.1 準備

kerasのモデルを動かすためには、kerasと、今回バックエンドとして使用しているtensorflowのインストールが必要です。

kerasは、後述のtensorflowに同梱されていますので、別途インストールしてはいません。

tensorflowは、CONEXIOBlackBearで動かすには、CONEXIOBlackBear用にビルドしたバージョンが必要ですので、当社でビルドしたものを使用してインストールします。

※なお、当社でビルドしたtensorflowは、CONEXIOBlackBearのユーザー様へご提供可能ですので、お問い合わせください。


2.2 コーディング

CONEXIOBlackBearで実行するコードは以下です。約5秒ごとにカメラで撮影した画像をCNNモデルに入力して推論を行います。画像のサイズは、モデルの入力サイズに合わせてリサイズしています。

学習モデルのデータは、1.3で出力されたkeras_cifar10_trained_model.h5というファイルを用いるので、PCからCONEXIOBlackBear上に配置しておきます。

# coding: utf-8

import cv2
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import load_img, img_to_array
import time
import numpy as np

# モデルへの入力画像サイズ
input_image_shape = (32, 32, 3)

# カメラ
capture = cv2.VideoCapture(2, cv2.CAP_V4L)

label_names = [
    "airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"
]

def capture_image():
    """
    カメラ読み取り
    """
    # 読み取り
    ret, frame = capture.read()
    cv2.imwrite("test.jpg", frame) # 保存(デバッグ用)

    return frame

def convert_shape(frame):
    """
    画像形状の変換
    """
    data = np.array(frame)
    # リサイズ
    data = cv2.resize(data, (32, 32))
    cv2.imwrite("data.jpg", data) # 保存(デバッグ用)
    # 正規化
    data = data.astype("float32") / 255.0
    # 入力形式に変換
    input_array = data.reshape((1, ) + input_image_shape)

    return input_array

# モデルのロード
model = load_model("keras_cifar10_trained_model.h5", compile=False)

# 推論繰り返し
while True:

    # 画像の取り込み
    frame = capture_image()

    # 形状の変換
    input_array = convert_shape(frame)

    # 推論
    t0 = time.time()
    pred = model.predict(input_array)
    t1 = time.time()

    # 表示
    label = label_names[pred.argmax()]
    socre = pred.max()
    print("elapsed_time: {:.3} sec".format(t1 - t0))
    print("scores: %s" % pred)
    print("result: label={}, score={:.3}".format(label, socre))

    time.sleep(5)

capture.release()


2.3 動作させた結果

実際の景色を撮影しながら動作させることが難しかったので、PCの画面に表示した写真をWebカメラで撮影しました。精度は学習回数の関係上それほど高くないですが、以下の例ではautomobileが正しく判別されています。

推論1回の所要時間は、50~60msecでした。今回のモデルの規模であれば、推論は十分短い時間で実行できました。このように学習済みモデルをCONEXIOBlackBearにデプロイすれば、画像認識のアプリケーションが十分実現できそうです。また、アプリケーション次第ですが、もっと複雑なモデルでも十分リアルタイムに実行できそうです。

結果

elapsed_time: 0.0548 sec
scores: [[1.1939509e-03 8.6154062e-01 2.2574966e-06 8.3335271e-06 1.5354365e-06
  2.4803043e-07 3.4322095e-06 3.7648991e-07 3.1799115e-02 1.0545027e-01]]
result: label=automobile, score=0.862


元画像(https://www.pakutaso.com/ より)


モデルへの入力画像(PC画面に画像を映し、USBカメラで撮って32*32リサイズ)

※サイズが小さいのでぼやけて見える。


まとめ

以上のように、CONEXIOBlackBearで機械学習モデルを動かせました。学習済みモデルであれば十分短時間で実行可能ということがわかりました。

以前、greengrassでアプリケーションをデプロイという記事を書きました。今回のような機械学習モデルを豊富なリソースがあるクラウド側で開発して、同様の方法でエッジ側にデプロイすれば、まさに本格的なエッジコンピューティングになると思います。今後の記事で、トライしてみたいと思います。