ryuprogrammer / CheatingJanken

CoreMLを用いた後出しジャンケンゲームアプリ
1 stars 0 forks source link

#3 モデルを実装 #6

Closed ryuprogrammer closed 1 year ago

ryuprogrammer commented 1 year ago

関連Isuue番号

close #3

追加・変更の概要

CreateMLで作成したモデルを追加してCoreMLTestViewで実際に画像認識ができるか確認しました。

変更の目的

本来はGameViewでCoreMLを使用しますが、CoreMLのコードを初めて書くので理解しやすくするために一旦新しい別のViewを作成しました。

タスクの進捗状況

issueに記載

変更内容

CoreMLTestViewを追加しました。

影響範囲

一時的に新しくViewを作成したので他への影響はありません。

操作方法

・CoreMLTestViewの操作方法

→NextボタンとBuckボタンで画像が切り替わります。 →推測する画像が決定したらClassifierボタンを押すと画像の上に結果が表示されます。

・モデルのLivePreviewの確認方法 モデルのpreviewの確認方法は以下の画像の通りです。 HandPoseClassifier2とImageClassifier2の2つのモデルのLive Previewで両者の精度をご確認していただきたいです。 スクリーンショット 2023-03-26 17 48 53(3)

テストしたこと

・previewで画像認識ができるか→できない。 ・simulatorで画像認識ができるか→できない。 ・実機で画像認識ができるか→できる。(モデルが適切でないため正確な結果は出力されないが、一応可能)

相談事項

相談の概要:HandPoseClassifier2のモデルの利用方法

いくつか問題があり本来使用したいモデルが使用できなかったので、使いやすく変更したモデルを利用しました。以下の2つは同じ画像でトレーニングしましたが、精度が全く違います。 ・本来使用したいモデル(HandPoseClassifer2)→精度9割以上 ・使いやすく変更したモデル(ImageClassifer2)→精度4割程度 二つの違いはCreateMLでモデルを作成するときのテンプレート(添付画像)の違いによるものです。HandPoseClassifer2では添付画像の右の丸(HandPoseClassification)を、ImageClassifier2では添付画像の左の丸(Image Classification)を選択してモデルを作成しました。

スクリーンショット 2023-03-26 17 54 37(3)

こちらの記事を参考にしたのですが、記事ではCreateMLの選択画面でImage Classification(添付画像の左の丸)を選択しておりました。そのため、モデルにInputする画像が以下の通りにすればうまくいきます。

スクリーンショット 2023-03-26 18 19 47(3)

CoreMLTestViewでも以下のように画像のサイズの指定をします。

https://github.com/CodeCandySchool/CheatingJanken_ryu/blob/cbf4854bddac9fb8eb3994495f91fc354a9d6e57/CheatingJanken/CheatingJanken/View/CoreMLTestView.swift#L95

しかし、今回はHandPoseClassificationを使用したいのでモデルにinputする画像サイズが以下のように指定されています。

スクリーンショット 2023-03-26 18 22 42(3)

このinput方法がわからないです。 Inputの形式が「MultiArray (Float32 1 × 3 × 21)」となっていますが、こちらは画像ではなく映像でないとinputできないモデルなのでしょうか。ご教授お願い致します。

mustacheyork commented 1 year ago

@ryuprogrammer 拝見しました!

Inputの形式が「MultiArray (Float32 1 × 3 × 21)」となっていますが、こちらは画像ではなく映像でないとinputできないモデルなのでしょうか。ご教授お願い致します。

基本的に動画を学習させるのであっても、動画をフレーム(画像)に分解して学習をさせます。 なので、動画でないとinputできないということは無いと思います。 この入力形状を持つモデルを使用する場合、アプリケーションで画像を適切な形状に前処理し、MLMultiArray オブジェクトに変換してモデルに渡す必要があります。

上記が公式ドキュメントのMLMultiArrayの引用です。

Each dimension in a multiarray is typically significant or meaningful. For example, a model could have an input that accepts images as a multiarray of pixels with three dimensions, C x H x W. The first dimension, C, represents the number of color channels, and the second and third dimensions, H and W, represent the image’s height and width, respectively. The number of dimensions and size of each dimension define the multiarray’s shape. マルチアレイの各次元は、通常、重要または意味を持つ。例えば、あるモデルでは、画像をC×H×Wの3次元の画素のマルチアレイとして受け付ける入力があります。1次元目のCはカラーチャンネル数を表し、2次元目と3次元目のHとWは、それぞれ画像の高さと幅を表します。次元の数と各次元の大きさがマルチアレイの形状を決定する。

下記の資料が参考になるかなと思います。 https://machinethink.net/blog/coreml-image-mlmultiarray/

ただ、モデルの作成も精度の高い画像が必要なので、データの正規化が必要だと思うので試行錯誤の時間が必要かなと思います。 時間がないので、まずは既に公開されているアセットを利用してモデルを作成するか、学習済みのモデルでアプリが実現できるのかを検証するのはいかがでしょうか?

ryuprogrammer commented 1 year ago

相談内容

概要:カメラの映像からHandGestureを判別できない。

先日のメンタリング時は、カメラの映像がViewに表示されませんでしたが、その後表示されるようになりました。 しかし、今度はカメラの映像からHandGestureが判別されません。

以下のようにカメラの映像からフレーム毎にHandGestureを判別しています。 https://github.com/CodeCandySchool/CheatingJanken_ryu/blob/f610599de4b57a6559bd68bdd32a574d9b165830/CheatingJanken/CheatingJanken/View/HandGestureTestView.swift#L113-L116

上記のコードで、デバックエリアにcurrentGesture.rawValueを出力していますがずっと「???」と出力されてしまいます。

よってHandGestureDetectorクラスのprocessObservationsメソッドに問題があると思い、processObservationsメソッド内のif文が実行されているかチェックするために、以下のようにelseでcurrentGestureを.testにしましたが、案の定実行されていません。 https://github.com/CodeCandySchool/CheatingJanken_ryu/blob/03182e0abd2a80234bd2c19c03678872cb9801dc/CheatingJanken/CheatingJanken/View/HandGestureTestView.swift#L156-L164

こちらのif文が実行されていないのはなぜでしょうか。ご教授いただけませんでしょうか。

一応、if文の下に以下のようにprint文を書いて手が検出されているかチェックしましたが、カメラの映像から手の検出はできています。(実機テストでカメラに手を写すとデバックエリアにプリント文が表示されます。) https://github.com/CodeCandySchool/CheatingJanken_ryu/blob/03182e0abd2a80234bd2c19c03678872cb9801dc/CheatingJanken/CheatingJanken/View/HandGestureTestView.swift#L165

ryuprogrammer commented 1 year ago

相談内容

概要:currentGestureが変化してもViewが更新されない。

昨日から少し進み、カメラの映像からHandGesture(グーチョキパー)の正確な判定に成功して、デバックエリアでの出力まではできました。しかし、@PublishedでcurrentGestuerを監視しているのですが、currencGestureが更新してもViewに正しく表示されません。解決方法をご教授いただけませんでしょうか。

mustacheyork commented 1 year ago

@ryuprogrammer じゃんけんの判定はある程度できるようになってきているので、一旦、こちらのプルリクをマージしましょう 👍