手話解読アプリの要素技術(2)

アプリのゴールは、スマホカメラで手話を撮影し、汎用AIを使って手指骨格座標取得し、骨格座標を(オリジナル手話用AIモデル)を使って手話トークンに変換し、解読結果を文字情報や音声情報でリアルタイムにユーザーに返す、こととします。このTopicは、骨格座標データから手話トークンを推定するための(オリジナル手話用AIモデル)を構築する流れを紹介します。

人物画像から骨格座標データを取得する方法はオープンソースでいくつか提供されていますが、このアプリではiOSに標準搭載されているVisionフレームワークを使っています。手指や体骨格の特徴点座標の取得に関しては以下の公式ビデオで紹介されています。

Detect Body and Hand Pose with Vision(WWDC2020)

VisionのHand Poseで、手の関節座標を取得できる。同時にBody Poseで骨格座標を取得することができるので、体骨格に対しての相対的な位置関係も取得できる。数フレーム分のデータを集めれば、手の位置、手の形、手の動きをデータ化することができる、と考えられます。

なお実際にデータを取得するにはノウハウが必要で、公式サイトの情報だけではわかりにくかったため、エンジニア投稿サイトのQiitaに私の解説を投稿していますのでこちらを参照してください。

keypointsMultiArrayから機械学習用データを取得する

Cloud Strageに保存したmp4ファイルからHandPoseを取得する

上記2つのサイトを参考にすると、mp4動画から手の骨格座標をCSVファイルとして保存できますので、ここから一旦iOS(XCode)を離れて、Python(Tensorflow/Keras)系にて「骨格座標データ」⇔「手話トークン」の機械学習を実施して(オリジナル手話用AIモデル)を構築していきます。

from tensorflow.keras import layers, models

model = models.Sequential()
model.add(layers.Dense(1024, activation='relu', input_shape=(420, ), kernel_initializer='random_uniform', name='hidden'))
model.add(layers.Dense(32, activation='softmax' , name='softmax'))
model.summary()

例として、5フレーム分の画像で「手話トークン」を学習させることを考えます。1フレームあたり82のFloat値がデータになりますので(片手21点、両手で42点の座標。X,Y座標があるので82のFloat)、5フレームで420がinputデータとなります。上記の最もシンプルな隠れ層1層の上記のニューラルネットワークでも、val_accは0.85程度には学習は進行しますが、実際にはここからさらに誤差を低減する検討が必要になります。

ここで得られたパラメータは.h5形式で保存できます。これをiOSで使用できるようにするためにはPythonのパッケージである”coremltools”を使ってiOS用に変換することが必要です。

import coremltools as ct

model = (.h5モデル)
class_labels = []
mlmodel = ct.convert(model,
                     classifier_config=ct.ClassifierConfig(class_labels, 
                     predicted_feature_name='subLabels'))
mlmodel.save('iOSmodel.mlmodel')