[Amazon SageMaker] イメージ分類のモデルをNeoで最適化してRaspberryPi Model 4で使用してみました

2020.06.03

1 はじめに

CX事業本部の平内(SIN)です。

Amazon SageMager Neo(以下、Neo)を使用すると、既存のモデルをコンパイル(最適化)し、精度を低下させることなく、他のクラウドやエッジで実行出来るようになります。
参考:Amazon SageMaker Neo モデルを一度トレーニングすれば、最大 2 倍のパフォーマンスでどこでも実行可能

今回は、以前、作成した商品を検出するイメージ分類(SageMakerの組み込みアルゴリズム)のモデルをNeoで最適化し、RaspberryPi(Model 4)にセットアップしたDLR(DeepLarningRuntime)で使用してみました。

作業にあたっては、下記の記事を参考にさせて頂きました。

2 Neoによる最適化

Neoによるコンパイルは、SageMakerコンソールの推論 > コンパイルジョブ から、コンパイルジョブの作成で行います。

「アーティファクトの場所」は、利用する既存のモデルのパスを指定します。 「データ入力設定」及び「機械学習フレームワーク」は、イメージ分類の場合「{"data":[1,3,224,224]}」及び、「MXNet」となります。

出力先とターゲット(rasp3b)を指定します。

ステータスがCOMPLETEDになったら完了です。(数秒で完了します)

3 DLRのセットアップ

  • Python3用にセットアップを行います。
$ python3 --version
Python 3.7.3

https://neo-ai-dlr-release.s3-us-west-2.amazonaws.com/v1.1.0/pi-armv7l-raspbian4.14.71-glibc2_24-libstdcpp3_4/dlr-1.1.0-py2.py3-none-any.whl

  • 取得したURLをrasp3b-wheel-urlのところに指定して実行します。
$ pip3 install rasp3b-wheel-url
  • from dlr import DLRModelがエラーなくインポートできたらセットアップは完了です。
$ python3
Python 3.7.3 (default, Apr  3 2019, 05:39:12)
Type "help", "copyright", "credits" or "license" for more information.
>>> from dlr import DLRModel
>>>


参考:最適化された機械学習推論を AWS マネジメントコンソール を使用して設定する方法

4 モデルの配置

  • Neoで作成したモデルをRaspberryPiに転送します。
$ scp model-rasp3b.tar.gz pi@raspberrypy.local:~

* モデルをmodel-rasp3bに展開します。(ディレクトリ名は任意です)

$ mkdir ./model-rasp3b
$ tar xvfz model-rasp3b.tar.gz -C ./model-rasp3b
$  ls -la ./model-rasp3b
total 380248
drwxr-xr-x 2 pi pi      4096 Jun  3 02:46 .
drwxr-xr-x 7 pi pi      4096 Jun  3 02:45 ..
-rw-r--r-- 1 pi pi    109003 May 27 04:07 compiled_model.json
-rw-r--r-- 1 pi pi 388947330 May 27 04:07 compiled.params
-rwxr-xr-x 1 pi pi    301828 May 27 04:07 compiled.so
-rw-r--r-- 1 pi pi        46 May 25 18:10 model-shapes.json

5 コード

RaspberryPi上で実行しているコードは、以下のとおりです。

DLRModelを、Neoで作成したモデルで初期化して、run()で推論しています。

カメラは撮影時に224*224とし、numpy.ndarrayに変換した後、入力データとしています。

image_classification.py

import numpy as np
from numpy import asarray
from dlr import DLRModel
from PIL import Image
from io import BytesIO
import picamera
import time

CLASSES = ['PORIPPY(GREEN)', 'OREO', 'CUNTRY_MAM', 'PORIPPY(RED)', 'BANANA'
           , 'CHEDDER_CHEESE', 'PRETZEL(YELLOW)', 'FURUGURA(BROWN)', 'NOIR'
           , 'PRIME', 'CRATZ(RED)', 'CRATZ(GREEN)', 'PRETZEL(BLACK)', 'CRATZ(ORANGE)'
           , 'ASPARA', 'FURUGURA(RED)', 'PRETZEL(GREEN)']

# DLR初期化
model_path = './model-rasp3b' # モデルを展開したディレクトリ
dlr_model = DLRModel(model_path, 'cpu')

# Piカメラからの画像取得
camera = picamera.PiCamera()
camera.resolution = (224, 224)
buffer = BytesIO()
camera.capture(buffer, format = "jpeg", resize = (224, 224))
camera.close()

# PIL.Imageへの変換
image = Image.open(buffer)
image.save("test.png","PNG") # 画像保存
image = asarray(image) # PIL.JpegImagePlugin.JpegImageFile => numpy.ndarray
image = image.transpose((2, 0, 1)) # transpose shape (244,244,3)=>(3,244,244)

# 推論
start = time.time() # 時間計測
out = dlr_model.run({'data': image})
processing_time = time.time() - start
print("processing_time {}sec".format(processing_time))

# 表示
prob = np.max(out)
index = np.argmax(out[0])
print("Class: %s, probability: %f" % (CLASSES[index], prob))

6 動作結果

プログラムを実行して動作を確認してみた結果です。推論の処理時間は、2秒弱でした。

$ python3 image_classification.py
processing_time 1.8867785930633545sec
Class: OREO, probability: 0.999899

$ python3 image_classification.py
processing_time 1.894164800643921sec
Class: PRIME, probability: 0.996479

$ python3 image_classification.py
processing_time 1.9166178703308105sec
Class: PRETZEL(GREEN), probability: 0.897241

$ python3 image_classification.py
processing_time 1.9085075855255127sec
Class: NOIR, probability: 0.999804

$ python3 image_classification.py
processing_time 1.9775032997131348sec
Class: BANANA, probability: 1.000000

7 最後に

Neoで最適化したモデルを、RaspberryPi(Model 4)で動作させて見ました。

DLRの利用例は、AWS IoT Greengrass上のものが多く、少し、理解を整理するため、今回は、Greengrassを利用しない環境で試してみました。

DLRのセットアップさえ詰まらなければ、特に問題となるところは無いかもしれません。