【解決済】TMPose2Scratchがうまく動かない時の回避法

# AIをScratchで簡単に楽しむ
　オライリーから2022年夏にむけて「[Scratchであそぶ機械学習 (石原淳也さん他)](https://www.oreilly.co.jp/books/9784873119960/)」という素晴らしい本が出版されました。お子さんの夏休み自由研究に頭を悩ませている親御さんにとって神のような存在ですね。我が家も早速お世話になっています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/ddda5b1c-da65-4a7a-28d7-6aea775262aa.png" width="400px">

## この記事は何？
~~本書籍は大変すばらしいのですが、一番初めの章の「**ポーズ認識がうまく動かない**」ことがあります(2022/7/31時点)。~~
**→ 石原さんが早速改修してくださいました。感謝。**

----
本記事はもう役割を終えていますが、上記書籍の紹介記事にもなっているので、残しておきます。

この記事はこの問題を回避するHackです。
参考にしていただき、夏休み自由研究を楽しんでいただければ幸いです。

## 結論

### →　tmpose2scratchを一度ロードさせてから、Scratchページをリロードします
これでうまく動きます。

#### ＜書籍「[Scratchであそぶ機械学習](https://www.oreilly.co.jp/books/9784873119960/)」の場合＞
Scratch3を拡張した「Stretch３」というサイトになっていますので、上を以下のように読み替えてください。

### → オライリーページにある[1-1_posereaction.sb3](https://www.oreilly.co.jp/pub/9784873119960/1-1_posereaction.sb3)を一度ロードさせてから、[Stretch3ページ](https://stretch3.github.io/)をリロードします

##### 細かい手順
###### （1） オライリーのページからプロジェクトファイル[1-1_posereaction.sb3](https://www.oreilly.co.jp/pub/9784873119960/1-1_posereaction.sb3)をダウンロード。
###### （2） 一度Chromeブラウザを終了させます。※ページを閉じるのではなくプログラムを終了させてください。
###### （3） ブラウザを起動し、書籍のお薦めどおり「ゲストモード」で[Stretch3ページ](https://stretch3.github.io/)を開きます。
###### （4） 1-1_posereaction.sb3をstretch3へ読み込む → **【注意】 ここではまだ正しく動きません**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/7c8f97c9-421b-d805-1d4c-b3b2796cb882.png" width="600px">

　※ カメラ使用の確認ダイアログが出たら「許可する」をクリックしてください
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/fdad7d1c-7d21-5f64-be8f-59e31de388ac.png" width="300px">

　※ 動作確認のため、tmpose2scratch機能拡張ブロックにある「ポーズラベル」にチェック✅を入れるとわかりやすいです
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/dcdf9db5-3e5d-cccb-ad9a-9ea596625782.png" width="500px">

###### （5） Stretchページをリロードする 
###### （6） もう一度、1-1_posereaction.sb3を読み込む → **ここから正しく動きだします**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/bc927c96-7658-638a-33b8-22f8caa1137e.png" width="500px">

###### (7) 確認のため、「ポーズラベル」に再度チェック✅を入れる
###### (8) カメラプレビュー画面左上の🚩をクリックします
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/e6f06adf-c5c2-9459-c559-45b48c6eda5b.png" width="500px">

###### (9) **３０〜４０秒経つとカメラプレビューが一瞬止まり**、AIモデルがロードされます。
その後、**カメラプレビュー画面に🟢や❌が表示**されるようになります。**ポーズラベル**も表示されるようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/21cbbf68-4c88-0a79-a852-aee73cf5dea7.png" width="700px">

### めでたし めでたし




# 技術的な解説
ここからは、興味がある方のための説明です。読み飛ばしてもらっても大丈夫です。

### TMPoses2Scratchについて
[TMPose2Scatch](https://github.com/champierre/tmpose2scratch)は、2020年１０月に公開された、[TeachableMachine with Google](https://teachablemachine.withgoogle.com/)で作成したポーズ認識のためのAIモデルをScratchで使えるようにした素晴らしい拡張機能です。

- AIモデルのURLを記載するだけで、ポーズ認識が書ける
- 認識結果のラベル名を使って、認識時のコールバックを簡潔に記載できる

なお、コントリビュータの石原さんらは、TMPose2Scrath以外にもたくさんの貢献をしてくださっています。
本当に感謝、感謝です。
→ https://github.com/champierre

##### <tmpose2scrachのリポジトリREADME.mdから引用>
![tmpose2scrachのリポジトリREADME.mdから引用](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111758/0967d009-23b7-7234-ad6d-e37949b9e384.png)


### 何が起きていたか？
Chrome DevToolで内部動作を確認したところ、書籍上記の章で使われている「**TMPose2Scatch**」というscratch機能拡張(JavaScriptライブラリ)の**初回ロードでのみうまく動いていない**ようでした。

この機能拡張が内部で使っているJavaScriptモジュールの読み込みの順序関係が原因のように思われたため、**ページリロードによるキャッシュ更新を試したところ**幸いなことにうまく行きました。


#### 経緯
　プルリクエストの履歴などを拝見すると、2022年になってベースとなるtensorflow.jsのバージョンアップが影響し、正しく動作するバージョンを指定することが必要になったようです→[Fix classifcation error reported #2#3](https://github.com/champierre/tmpose2scratch/pull/3)。tensorflowとｔｍposeというモジュールを明示的に読み込ませるように改修されています。
　本記事にある「動かない」パターンは、①ブラウザのキャッシュがクリアされていて、②初めてプロジェクトを読み込むケースでのみ発生する、**稀なケース**です。ただ、書籍を手にとって初めて試す方にとっては必ず通るケースでもあります。

#### 推測： なぜリロードでうまくいく？
　ScratchはNode.jsで作られたWebアプリケーションです。TMPose2ScratchをはじめとするScratch機能拡張はJSモジュールとして作成されています。Scratch画面からこれらの機能拡張を読み込むと、そのJSモジュールがブラウザにダウンロード・キャッシュされ、使用が可能になる仕組みです。
 　Node.jsでは複数のJSモジュールが依存関係にある場合、自動的で読み込み順を制御してくれる仕組みになっており、ほぼ問題は起きません。
　ただ今回、上記の経緯から独自にモジュール読み込みを指定するよう変更をおこなっており、このケースでは利用するJSモジュールがブラウザに先にキャッシュされるよう読み出し順を制御する必要があります。初回がうまくいかないのは利用側モジュールの後に利用側モジュールがキャッシュされたためです。リロードすると二つともキャッシュ済みになっているので、うまく動作したと考えられます。

## まとめ
この夏、この本を手にとってワクワクしている子供や親御さんたちが困ったりしないようにとの思いから、記事を書きました。じきにコードが修正されて、この記事の内容が役目を終えることを祈念しております。

最後に、STEM教育のために素晴らしい貢献をしてくださっている　石原さんやオライリー社に改めて感謝を申し上げます。
本当にありがとうございます。