MediaPipe でクラス分類モデルを学習し、ハンドサイン推論アプリをつくった

1. はじめに
本アプリは、カメラに手をかざすだけでハンドサインを認識し、「5本指ワーク(ファイブフィンガー)」を一人でも行えるアプリです。
たとえば「今日の気分」や「進捗の自己評価」を、手の形で簡単に表現できます ✋☺️
5本指(ファイブフィンガー)とは?
「5本指(ファイブフィンガー)」とは、1〜5 の指の本数で意思表示を行う簡易的な評価・投票手法です。
☝️(イチ) が最低、🖐️ (ゴ)が最高を表し、0〜5 段階で表すパターンもあります。
会議やチームの振り返りで「今日の進捗度合いは?」「このアイデアどう思う?」などを視覚で共有できるのが特徴です。
使用技術
| 分類 | 技術 |
|---|---|
| モデル検出 | MediaPipe |
| モデル学習 | Python, PyTorch, ONNX |
| 推論環境 | onnxruntime-web, mediapipe |
| フロントエンド | React, TypeScript, Vite, Chakra UI |
2. MediaPipe とは?
MediaPipe は、Google が開発したマルチモーダルな機械学習パイプラインライブラリです。
本プロジェクトでは 手の検出と 21 個のランドマーク座標(指関節点) の取得に使用しています。
ハンドランドマークモデルは、約 3 万枚の画像を使ってトレーニングされており、非常に高精度です。

Google より抜粋
3. 全体アーキテクチャ
構成図

カメラ入力 → MediaPipe で手検出 → 座標正規化 → モデル推論(ONNX) → 推論結果表示(ブラウザ上)
4. ハンドサインデータの収集
MediaPipe を使って、さまざまなハンドサイン(👍「Good Job」、☝️「1」、✌️「2」など)を収集しました。
MediaPipe は手の各関節を 21 点の XYZ 座標で出力します。
よって 1 サンプルは 63 次元(21 点 × 3 軸) のベクトルデータになります。
サンプル数は約 1000 件で、いろんな角度から収集しました。

収集スクリプトは GitHub 上で公開しています。興味のある方はぜひご覧ください。
5. モデル設計
ハンドサインの識別には、多層パーセプトロン(MLP) を採用しました。
入力が数値ベクトルであり、画像のような空間構造を持たないため、 MLPでも十分に精度の高いモデルが作れます。
class MLP(nn.Module):
def __init__(self, n_cls):
super().__init__()
self.net = nn.Sequential(
nn.Linear(63, 128), nn.ReLU(), nn.Dropout(0.2),
nn.Linear(128, 64), nn.ReLU(), nn.Dropout(0.2),
nn.Linear(64, n_cls)
)
150 エポックで学習を行ったところ、精度 99% に到達しました。
以下は損失関数の推移です。

最終損失は 0.0335。MLP でも十分に高い性能を発揮できました。
補足:
本モデルは ONNX 形式に変換してブラウザで推論できるようにしています。
PyTorch → ONNX → onnxruntime-web の流れです。
6. 推論処理(ブラウザ)
ブラウザ上では、映像・手の描画・推論結果の表示をそれぞれ別のタグで重ね合わせています。
-
videoタグ:カメラ映像を表示 -
canvasタグ:MediaPipe が検出した手のランドマーク(関節点)を描画 -
divタグ:推論結果のテキストを表示
これらの要素はすべて、CSS の position: absolute; を用いて同じ位置に重ねることで、
リアルタイム映像上に手のポイントとラベルが同時に表示されるようにしています。

ブラウザ上での推論の流れ
推論はすべて ブラウザ内(ローカル環境)で完結します。
処理の流れは以下の通りです。
- カメラ映像から MediaPipe が手を検出
- 21 個のランドマーク座標(XYZ)を取得 → 63 次元ベクトル化
- 各座標値を正規化し、Tensor 型へ変換
- ONNX モデルに入力し、推論を実行
- Softmax 関数でクラスごとの確率分布を算出
- 最も確率の高いハンドサイン名をブラウザ上に表示
データを正規化する理由
MediaPipe が出力する座標値は、撮影距離や手の大きさ、カメラ解像度などによってスケールが異なります。
そのまま学習・推論に使用すると、入力データの分布が不均一になり、モデルの精度が下がる原因になります。
そのため、座標値を
- 手の重心を基準に位置を平行移動
- 左右を反転
- 手の大きさでスケーリング(0〜1 の範囲に正規化)
することで、環境差に影響されにくい安定した特徴量に変換しています。
Softmax を使う理由
Softmax 関数は、モデルの出力(生のスコア)を 確率分布に変換するために使用します。
これにより、各クラス(ハンドサイン)の信頼度を「確率」として扱うことができます。
たとえば、
Good 👍:0.92
One ☝️:0.06
Peace ✌️:0.02
のように確率的に可視化することで、最も確率の高いラベルを選ぶことができます。
7. おわりに
MediaPipe でクラス分類モデルを学習し、ハンドサイン推論アプリをつくりました。
既存の MediaPipe モデルを使って自分専用のハンドサインモデルを作るという、機械学習重ね掛けが面白かったです。
Discussion