20211202のTensorFlowに関する記事は2件です。

TensorFlow.js + MoveNetでジョジョ立ちの姿勢推定を行う

はじめに TesorFlow.jsとMoveNetを用いて姿勢推定を行う方法について解説します。 以下のツイート画像のようにブラウザ上で姿勢推定ができるようになります。 姿勢推定とは 姿勢推定とは画像や映像中の人物の関節(=キーポイント)を座標データで検出する技術です。 近年ではディープラーニングを用いた姿勢推定が行われています。 TensolFlow.jsとは TensorFlow.jsはブラウザやNode.js上で機会学習モデルのトレーニングやデプロイを行うためのJavaScriptライブラリです。 学習済みモデルが公開されており、それらを利用して物体検出や姿勢推定を行うことができます。 今回はMoveNetという学習済みモデルを利用して姿勢推定を行います。 MoveNetとは MoveNetはTensorFlow公式によって公開されている姿勢推定用のモデルです。 画像や動画を入力として身体の17のキーポイントを高速かつ正確に検出することができます。 LightningとThunderの2種類が用意されています。 前者はレイテンシーが重要なアプリケーションを対象としています。 後者は高精度を必要とするアプリケーションを対象としています。 詳細な仕様はTensolFlowの公式ブログを参照してください。 https://blog.tensorflow.org/2021/05/next-generation-pose-detection-with-movenet-and-tensorflowjs.html MoveNetの導入 今回はCDNを用いてMoveNetを導入します。 html <html> <head> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-core"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-converter"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgl"></script> <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/pose-detection"></script> </head> </html> 姿勢推定の実行 姿勢推定の対象となるimg要素を用意します。 html <html> <body> <img id="img" src="./xxx.png" width="300px" /> </body> <html> 用意したimg要素に対して姿勢推定を実行します。 javascript document.addEventListener('DOMContentLoaded', async() => { // 検出器を生成 const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet) // img要素を取得する const imageElement = document.getElementById('img') // 姿勢推定を実行する const poses = await detector.estimatePoses(imageElement) // 姿勢推定結果を出力する console.log(poses[0].keypoints) }) コンソール上に以下のような姿勢推定結果が出力されました! [ { "y": 107.0774033665657, "x": 170.3357219696045, "score": 0.672927975654602, "name": "nose" }, { "y": 108.07683914899826, "x": 179.52157258987427, "score": 0.5579419136047363, "name": "left_eye" }, { "y": 103.95387262105942, "x": 176.25893354415894, "score": 0.44960924983024597, "name": "right_eye" }, { "y": 127.98979580402374, "x": 193.1210696697235, "score": 0.5600013136863708, "name": "left_ear" }, { "y": 117.00804084539413, "x": 183.74462127685547, "score": 0.38861674070358276, "name": "right_ear" }, { "y": 170.36895751953125, "x": 197.4759578704834, "score": 0.5543217658996582, "name": "left_shoulder" }, { "y": 140.3295934200287, "x": 146.19784355163574, "score": 0.4909017086029053, "name": "right_shoulder" }, { "y": 212.7191960811615, "x": 221.3673233985901, "score": 0.5364058613777161, "name": "left_elbow" }, { "y": 128.0842810869217, "x": 94.87710893154144, "score": 0.7699795365333557, "name": "right_elbow" }, { "y": 234.46808457374573, "x": 183.3907663822174, "score": 0.6135048866271973, "name": "left_wrist" }, { "y": 140.4405564069748, "x": 127.41105258464813, "score": 0.39565128087997437, "name": "right_wrist" }, { "y": 254.5135736465454, "x": 152.78272032737732, "score": 0.4956844747066498, "name": "left_hip" }, { "y": 248.24934601783752, "x": 142.50272512435913, "score": 0.6491193175315857, "name": "right_hip" }, { "y": 315.92750549316406, "x": 125.6029486656189, "score": 0.4037594497203827, "name": "left_knee" }, { "y": 309.03390645980835, "x": 165.5895173549652, "score": 0.5492032766342163, "name": "right_knee" }, { "y": 346.2807238101959, "x": 122.5919097661972, "score": 0.055652350187301636, "name": "left_ankle" }, { "y": 343.7341272830963, "x": 181.74968361854553, "score": 0.08864666521549225, "name": "right_ankle" } ] 姿勢推定の結果はオブジェクトの配列として出力されます。 各オブジェクトは以下ような構成になります。 プロパティ名 値 name 検出部位の名前 x 検出部位のx座標 y 検出部位のy座標 score 検出結果の確からしさ 出力された姿勢推定結果を用いれば、以下のようなことができます。 ・ 姿勢推定結果を表示する ・ 画像中の人物に骨格線を重畳する ・ 特定のポーズをとっているか判断する 今回は姿勢推定結果をテーブルに表示してみようと思います。 姿勢推定結果をテーブルに表示する 結果を表示するためのtable要素を用意します。 html <table> <tr> <th>部位</th> <th>スコア(%)</th> <th>x座標</th> <th>y座標</th> </tr> <tr> <td>鼻</td> <td id="nose-score">-</td> <td id="nose-x">-</td> <td id="nose-y">-</td> </tr> <tr> <td>左目</td> <td id="left-eye-score">-</td> <td id="left-eye-x">-</td> <td id="left-eye-y">-</td> </tr> <tr> <td>右目</td> <td id="right-eye-score">-</td> <td id="right-eye-x">-</td> <td id="right-eye-y">-</td> </tr> <tr> <td>左耳</td> <td id="left-ear-score">-</td> <td id="left-ear-x">-</td> <td id="left-ear-y">-</td> </tr> <tr> <td>右耳</td> <td id="right-ear-score">-</td> <td id="right-ear-x">-</td> <td id="right-ear-y">-</td> </tr> <tr> <td>左肩</td> <td id="left-shoulder-score">-</td> <td id="left-shoulder-x">-</td> <td id="left-shoulder-y">-</td> </tr> <tr> <td>右肩</td> <td id="right-shoulder-score">-</td> <td id="right-shoulder-x">-</td> <td id="right-shoulder-y">-</td> </tr> <tr> <td>左肘</td> <td id="left-elbow-score">-</td> <td id="left-elbow-x">-</td> <td id="left-elbow-y">-</td> </tr> <tr> <td>右肘</td> <td id="right-elbow-score">-</td> <td id="right-elbow-x">-</td> <td id="right-elbow-y">-</td> </tr> <tr> <td>左手首</td> <td id="left-wrist-score">-</td> <td id="left-wrist-x">-</td> <td id="left-wrist-y">-</td> </tr> <tr> <td>右手首</td> <td id="right-wirst-score">-</td> <td id="right-wirst-x">-</td> <td id="right-wirst-y">-</td> </tr> <tr> <td>左腰</td> <td id="left-hip-score">-</td> <td id="left-hip-x">-</td> <td id="left-hip-y">-</td> </tr> <tr> <td>右腰</td> <td id="right-hip-score">-</td> <td id="right-hip-x">-</td> <td id="right-hip-y">-</td> </tr> <tr> <td>左膝</td> <td id="left-knee-score">-</td> <td id="left-knee-x">-</td> <td id="left-knee-y">-</td> </tr> <tr> <td>右膝</td> <td id="right-knee-score">-</td> <td id="right-knee-x">-</td> <td id="right-knee-y">-</td> </tr> <tr> <td>左足首</td> <td id="left-ankle-score">-</td> <td id="left-ankle-x">-</td> <td id="left-ankle-y">-</td> </tr> <tr> <td>右足首</td> <td id="right-ankle-score">-</td> <td id="right-ankle-x">-</td> <td id="right-ankle-y">-</td> </tr> </table> テーブルのスタイルを定義します。 css img { float: left; } table { text-align: center; border-collapse: collapse; } table th, table td { border: solid 1px black; } テーブルに検出結果を描画するための処理を追加します。 javascript const keypointIds = ['nose', 'left-eye', 'right-eye', 'left-ear', 'right-ear', 'left-shoulder', 'right-shoulder', 'left-elbow', 'right-elbow', 'left-wrist', 'right-wirst', 'left-hip', 'right-hip', 'left-knee', 'right-knee', 'left-ankle', 'right-ankle'] keypointIds.forEach(function(item, index){ keypoint = poses[0].keypoints[index] document.getElementById(item + '-score').innerHTML = Math.floor(keypoint.score * 100) document.getElementById(item + '-x').innerHTML = Math.floor(keypoint.x) document.getElementById(item + '-y').innerHTML = Math.floor(keypoint.y) }) 以下のように、姿勢推定結果がテーブルに表示されました! 実装した内容については、CodePen上でも公開しています。 必要に応じてご参照ください! おわりに 最後までご覧いただきありがとうございました! 現在、姿勢推定を用いたジョジョ立ちの検定アプリを開発中です。 Twitterにて開発の進捗を発信していますので、もし良ければフォローお願いいたします! https://twitter.com/koheiyamamoto26 参考サイト TensorFlow.js Next-Generation Pose Detection with MoveNet and TensorFlow.js
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Multi-Car Racing(Gym)の使い方

はじめに R2D2やGoliraなどの並列分散系強化学習で学習を行いたい時に、環境もそれらに対応をしてほしいです。 しかし、OpenAiのCar Racing環境では、並列化を行うことができません。 そこで、今回は、並列化に対応した「Multi-Car Racing」の使い方について、説明します。 実行環境は、google colab proを使っています。 また、以下のチュートリアルを参考にしました。 自身のgithubは以下の通りです。 感謝 下記コメント欄にあるように、山田@ymd_h 様に助けていただき、コードを大幅に変更いたしました。 import !apt update && apt install xvfb !git clone https://github.com/igilitschenski/multi_car_racing.git !pip install ./multi_car_racing !pip install -U imgaug==0.2.7 gym-notebook-wrapper import gym from gym import wrappers import gym_multi_car_racing import numpy as np import gnwrapper ワラッパークラス class FlatMultiDisplayWrapper(gym.Wrapper): def __init__(self, env, nrows=1, ncols=1, empty_cell=0): super().__init__(env) self.nrows = nrows self.ncols = ncols self.empty_cell = empty_cell def render(self, mode="human", **kwargs): stack_images = super().render(mode, **kwargs) nstack = stack_images.shape[0] frame_shape = stack_images.shape[1:] if len(frame_shape) >= 2: self.flat_shape = list(frame_shape) self.flat_shape[0] = self.flat_shape[0]*self.nrows self.flat_shape[1] = self.flat_shape[1]*self.ncols frame = np.full(self.flat_shape, self.empty_cell, dtype=np.uint8) for i in range(min(nstack, self.nrows*self.ncols)): row = i // self.ncols col = i % self.ncols frame[row*frame_shape[0]:(row+1)*frame_shape[0], col*frame_shape[1]:(col+1)*frame_shape[1]] = stack_images[i] else: # たまに、空の画像を stack した画像が返ってくる。 frame = np.full(self.flat_shape, self.empty_cell, dtype=np.uint8) return frame def step(self, action): obs, rew, done, info = super().step(action) # Reward が gym.Env の仕様を満たしていないので変換する。元の値はinfoに入れておく info["original_reward"] = rew return obs, rew.sum(), done, info 本体 actions = np.array([[ 0, 0, 0], # [0]: straight [ 0, 1, 0], # [1]: acceleration [ 0, 0, 1], # [2]: decelerate [ 1, 0, 0], # [3]: Turn right [-1, 0, 0]]) # [4]: Turn left env = gym.make("MultiCarRacing-v0", num_agents=2, direction='CCW', use_random_direction=True, backwards_flag=True, h_ratio=0.25, use_ego_color=False) env = FlatMultiDisplayWrapper(env, nrows=1, ncols=2) env = gnwrapper.Monitor(env, './', force = True) obs = env.reset() done = False total_reward = 0 while not done: action = np.random.randint(5) action = actions[action] obs, reward, done, info = env.step([action,action]) total_reward += reward print("individual scores:", total_reward) env.display() 環境に対するインプット、アウトプットは、リスト形式で送信する必要があります。 action: [[ 0, 0, 0], [ 0, 0, 1]] reward: [-83.16498316 -62.96296296]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む