SAS Viya:一般物体検出(Object Detection)を試してみた

0

PythonからSAS Viyaの機能を利用するための基本パッケージであるSWATと、よりハイレベルなPython向けAPIパッケージであるDLPyを使用して、Jupyter NotebookからPythonSAS Viyaの機能を使用して一般物体検出(Object Detection)を試してみました。 

今回は、弊社で用意した数枚の画像データを使用して、処理の流れを確認するだけなので、精度に関しては度外視です。 

大まかな処理の流れは以下の通りです。

1.必要なパッケージ(ライブラリ)のインポートとセッションの作成
2.一般物体検出向け学習用データの作成
3.モデル構造の定義
4.モデル生成(学習)
5.物体検出(スコアリング) 

1.必要なパッケージ(ライブラリ)のインポートとセッションの作成

swatdlpyなど、必要なパッケージをインポートします。

from swat import *
import sys
sys.path.append(dlpy_path)
from dlpy.model import *
from dlpy.layers import *
from dlpy.applications import *
from dlpy.utils import *
from dlpy.images import ImageTable
 
from dlpy.splitting import two_way_split
from dlpy.blocks import *
import cv2
import numpy as np
import pandas as pd
import random
import matplotlib.pyplot as plt
from PIL import Image
 
from IPython.display import display

次にSAS ViyaのインメモリーエンジンであるCAS(Cloud Analytic Services)に接続しセッションを作成し、必要なアクションセットをロードし、ライブラリを作成します。

s = CAS(host, port, user, password)
s.loadactionset('image')
s.loadactionset('deepLearn')
s.table.addcaslib(activeonadd=False,datasource={'srctype':'path'},
                  name='dnfs',path=path,subdirectories=True)

2.一般物体検出向け学習用データの作成
DLPyに搭載されているcreate_object_detection_table()メソッドを使用することで、一般物体検出向けに、必要なフォーマットの学習用データを簡単に作成することができます。
create_object_detection_table()メソッドに関しては、こちらのブログも参照ください。

object_detection_targets = create_object_detection_table(s,
data_path = '/opt/sasinside/DemoData/DeepLearning/object_detection_dlpy/trainData/',
coord_type = 'yolo',
output = 'detTbl')

'/opt/sasinside/DemoData/ DeepLearning/object_detection_dlpy/trainData/'ディレクトリ内には、画像データ(.jpg)と注釈(annotation)データ(.xml)が格納されています。
このメソッドを実行するだけで、以下のようなフォーマットの学習用データが出来上がります。簡単ですね!

s.columninfo('dettbl')

idjoin: 画像ごとのユニークID
_image_: 画像データ
_Objectn_: 物体のカテゴリ名
_ Objectn_x: バウンディングボックスのX軸座標
_ Objectn_y: バウンディングボックスのY軸座標
_ Objectn_width: バウンディングボックスのxy座標からの幅
_ Objectn_height: バウンディングボックスのxy座標からの高さ
_ nObjects_: 画像内の物体の数 

作成された学習用のデータに含まれる画像をDLPyに搭載されているdispaly_object_detections()メソッド使用して表示してみましょう。

display_object_detections(s, 'detTbl', 'yolo', max_objects=3, num_plot=6, n_col=3)

3.モデル構造の定義 

入力変数(カラムリスト)とターゲット変数(カラムリスト)を定義します。

targets = ['_nObjects_'];
for i in range(0,3):
    targets.append('_Object%d_'%i)
    for sp in ["x", "y", "width", "height"]:
        targets.append ('_Object%d_%s'%(i, sp))
 
inputVars = []
inputVars.insert(0, '_image_')
print ("targets")
print (targets)
print ("inputVars")
print (inputVars)

 

targets
['_nObjects_', '_Object0_', '_Object0_x', '_Object0_y', '_Object0_width', '_Object0_height', '_Object1_', '_Object1_x', '_Object1_y', '_Object1_width', '_Object1_height', '_Object2_', '_Object2_x', '_Object2_y', '_Object2_width', '_Object2_height']
inputVars
['_image_']

ご覧の通り、2.項で作成したデータセット内の画像データが入力変数で、その他の項目がターゲット変数になります。 

次にアンカーボックスを定義します。

DLPyに搭載されているget_anchors()メソッドを使用し、トレーニングデータセット内の複数のオブジェクトに対する最も代表的な形状(アンカーボックス)を自動的に見つけ出してくれます。

以下の例では、アンカーボックスを3つ生成しています。

dettbl = s.CASTable('detTbl')
anchors = get_anchors(s, data='detTbl',coord_type='yolo', n_anchors=3)
anchors

 

(1.1121093750000002,
 2.3765625,
 0.8246875000000001,
 0.9127083333333335,
 1.3431640624999999,
 2.9927083333333337)

 

いよいよ、モデル構造を定義します。
DLPyに搭載のTiny_YoloV2()メソッドを使用し、必要なパラメータを指定して、Object DetectionのためのTiny YoloV2モデル、つまりYOLOV2の非常に小さなモデル構造が生成されます。

model = Tiny_YoloV2(s, 
                    n_classes=3,
                    width=416, height=416,
                    predictions_per_grid=3, 
                    anchors = anchors,
                    coord_type='yolo',
                    max_label_per_image = 3,
                    class_scale=1.0, 
                    coord_scale=1.0, 
                    prediction_not_a_object_scale=1, 
                    object_scale=5,
                    detection_threshold=0.2, 
                    iou_threshold=0.2)

生成されたモデル構造をビジュアライズしてみましょう。
DLPyに搭載のplot.network()メソッドを使用し、モデルのネットワーク構造をグラフィカルなネットワーク図として可視化することができます。

model.plot_network()

4.モデル生成(学習)

まず、事前に学習済みのweightをロードします。

s.table.loadtable(casout={'name':'jersey_ball_obj_det_initweights','replace':True}, caslib='dnfs',path="jersey_ball_obj_det_initweights.sashdat");

最適化パラメータを設定し、モデルを生成(学習)します。
今回は、精度は度外視なので、最短で処理が完了するようにミニバッチサイズ=1、エポック=1、としています。

solver = MomentumSolver(learning_rate=0.001, clip_grad_max = 100, clip_grad_min = -100)
optimizer = Optimizer(algorithm=solver, mini_batch_size=1, log_level=2, max_epochs=1, reg_l2=0.0005)
data_specs = [DataSpec(type_='IMAGE', layer='Input1', data=inputVars),
              DataSpec(type_='OBJECTDETECTION', layer='Detection1', data=targets)]
model.model_weights = s.CASTable('jersey_ball_obj_det_initweights')
model.fit(data='dettbl', optimizer=optimizer, force_equal_padding = True, record_seed = 13309,data_specs=data_specs,
          seed=13309, n_threads=5)

 

NOTE: Training based on existing weights.
NOTE:  The Synchronous mode is enabled.
NOTE:  The total number of parameters is 11026320.
NOTE:  The approximate memory cost is 1134.00 MB.
NOTE:  Loading weights cost       0.97 (s).
NOTE:  Initializing each layer cost       0.47 (s).
NOTE:  The total number of threads on each worker is 5.
NOTE:  The total mini-batch size per thread on each worker is 1.
NOTE:  The maximum mini-batch size across all workers for the synchronous mode is 5.
NOTE:  Epoch           Learning Rate     Loss    Fit Error      Time (s)
NOTE:          0           0.001       2.1314      0.356         1.39
NOTE:  The optimization reached the maximum number of epochs.
NOTE:  The total time is       1.39 (s).

 

5.物体検出(スコアリング)
生成されたモデルに当てはめるテストデータをロードします。今回はトレーニング用と同じ画像をテスト用として使用し、サイズを調整します。

test = ImageTable.load_files(s, '/opt/sasinside/DemoData/DeepLearning/object_detection_dlpy/trainData/', casout={'name':'test'})
test.resize(height=416, width=416, inplace=True)

テスト用の画像データを表示してみます。

test.show(ncol=3)

モデルにテストデータを当てはめて、予測(スコアリング)を実行します。

model.predict(data=test,layer_out='predict_res_tbl')

最後に、物体検出の結果を表示してみましょう。

display_object_detections(conn=s, 
                          coord_type='yolo', 
                          max_objects=3, 
                          table=model.valid_res_tbl, 
                          num_plot=5,
                          n_col=3)

精度は度外視とは言え、「ボール」はだいたい認識できているようです。
DLPyパッケージを使用することで、より簡潔なコーディングで、一般物体検出(Object Detection)が実施可能であることを感じ取ってもらえたでしょうか!?

※上記コードを実際に実行している動画は、オープン・AIプラットフォーム「SAS Viya特設サイト」で公開しています。

※物体検出の仕組みについては、「ディープ・ラーニングにおける物体検出」 もご参照ください。

Share

About Author

Makoto Unemi (畝見 真)

ビジネスディベロップメントグループ

データ分析によりビジネス価値を創造する「ビジネス・アナリティクス」を日本市場に浸透させる活動に長年従事し、金融・製造・通信業を中心に数多くのアナリティクス・プロジェクトの提案に参画。 現在はAIプラットフォームなど新たなテクノロジーの活用に特化した提案を担当している。 ディープラーニングや機械学習などのAIテクノロジーや大規模分析基盤アーキテクチャについての豊富な知見、経験を持つ。 新たなテクノロジーでも分かりやすく解説するプレゼンテーションには定評があり、満足度の高い講演を年間、数多く行っている。

Leave A Reply

Back to Top