状態:ドラフト(2026-10-13)。 論文の数値は原文を開いて条件とともに確認しました。実際に試したものはノートPCのCPUでのnumpyのサンプル(
code/08_simcc.py、1秒未満)です。TT ScoreがRTMPose・MediaPipeを実際に使った結果は「TT Scoreモデル解剖」第4篇を引用し、ViTPose・RTMOは動かしていません(未実測)。 シリーズ「ビジョンモデルを読む2」第8篇。前篇: 人の姿勢 1RTMPoseのデコーディングコードと私たちの用途についてはTT Score第4篇で詳しく扱ったため、本篇は「なぜそのように学習させるのか」に集中します。
人の姿勢 2:リアルタイム性と精度の間
目次
- 1. 直観:一方は大きくし、一方は削る
- 2. ViTPose:デコーダがほとんど必要ない
- 3. SimCC:座標を2つの分類に
- 4. RTMPose:学習のコツを1つずつ積み重ねる
- 5. RTMO:人物検出器をなくす
- 6. 限界
- 7. 我々のプロジェクトとのつながり
- 参考文献
1. 直観:一方は大きくし、一方は削る
第7篇の終わりの表を見ると、2019〜2020年の強者たちはHRNetのような緻密なネットワークに緻密なデコーディングを乗せた構造でした。その後、道が二手に分かれました。
- 精度側画像分野で巨大化した汎用Transformer(ViT)をそのまま持ち込み、事前学習(第3篇のMAE)に頼れば、姿勢専用の装置がほとんど不要になる(ViTPose)。
- 速度側2Dヒートマップ自体を捨ててより安価な出力を用い、学習のコツを積み重ねて精度を取り戻す(SimCC → RTMPose)。人物検出器までなくす(RTMO)。
2. ViTPose:デコーダがほとんど必要ない
ViTPose(2022)は、普通のViTをバックボーンとして使い(図の1/16解像度の特徴)、その上に非常に単純なデコーダを乗せます。「4倍に拡大(バイシニア補間)→ ReLU → 3×3畳み込み」の1つでヒートマップを出力します。学習は第7篇と同じヒートマップの二乗誤差です。
この単純なデコーダが通用するのかをバックボーンごとに比較した結果が興味深いものです(COCO val)。ResNetバックボーンでは単純なデコーダに変更すると約18ポイント低下したのに対し(ResNet-50 71.8 → 53.1)、ViTバックボーンでは0.3ポイント以内でした(ViT-B 75.8 → 75.5)。 アテンション層がすでに広い文脈を混ぜ合わせているため、デコーダが行うべき仕事がほとんど残らないという意味です(論文)。
精度はバックボーンのサイズに従って向上します。256×192入力でViTPose-Bが75.8、-Lが78.3、-Hが79.1であり、10億パラメータ級のバックボーンでCOCO test-dev 80.9(単一モデル、576×432、外部データ追加)にまで到達しました(論文)。速度も思ったほど悪くありません。ViTPose-Bが秒間944枚、HRNet-W32が916枚でした(データセンター級GPU、バッチ64、論文)。
事前学習データに関する実験もあります。MAEの事前学習をImageNetの代わりにCOCO・AI Challengerの人物切り抜き50万枚で行っても同じ75.8であり、COCOだけでも74.5でした(論文)。姿勢データだけでもかなり通用するという意味であり、第2・3篇の「ラベルのない我々の映像」の話につながります。
ViTPoseは第4篇の蒸留も使用します。大きなモデル(L)を凍結したまま学習可能な「知識トークン」1つだけを学習させ、そのトークンを小さなモデル(B)に組み込みました。トークンのみで+0.2、出力蒸留と合わせると+0.8(75.8 → 76.6)になりました(論文)。
3. SimCC:座標を2つの分類に
考え方
ヒートマップの問題は2つありました(第7篇)。関節ごとに2Dマップを描かなければならないためコストが高く、精度がマップの解像度に縛られます。SimCC(2022)は問いを変えます。「x座標は何番目のマスか」と「y座標は何番目のマスか」を それぞれ分類問題として解きます。
- 画素1つをk個のマスに分割します(分割倍率)。入力幅が192でk=2の場合、xのマスは384個になり、1マスが½画素になります。
- 関節の特徴を展開し、線形層1つでxのロジット384個、yのロジット512個を出力します。
- デコーディングはargmaxを2回行います。
マップを大きくしなくても画素より細かい解像度を得られます。
ラベルと損失
正解のマスだけが1であるワンホットラベルを使用すると、1マス隣も10マス隣も同様に「不正解」になります。SimCCは正解の周囲に確率を分配する ラベル平滑化(label smoothing) を使用し、予測分布と正解分布の間の KLダイバージェンスを損失として用います。平滑化方式の比較(ResNet-50、384×288)において、平滑化なしが71.3、均等に分配が73.0、 ガウス分布が73.4、ラプラス分布が73.0でした(論文)。近いマスほど間違いが少ないとみなすガウス分布が最も優れていました。
実際に試す
code/08_simcc.py の出力です(code/08_simcc.out.txt).
[1] x 정답 101.3px → 칸 202.6/384, 정답 분포의 최대 칸 203, 폭(σ) 6.0칸
[2] τ=1.0: 예측 분포 최댓값 0.012, KL(정답‖예측) 1.420, 디코딩 105.5px
[2] τ=0.1: 예측 분포 최댓값 0.171, KL(정답‖예측) 0.499, 디코딩 105.5px
[2]は温度の役割を示しています。ネットワークが出力するロジットは通常、値の幅が狭いです。そのまま(τ=1)ソフトマックスを適用すると分布が平らになり、正解分布から遠ざかります(KL 1.42)。一方、τ=0.1で割ると尖るため近づきます(KL 0.50)。RTMPoseはこの温度を0.1に設定し、COCO valが72.7になりました(下表のステップ)。そして 温度はargmaxを変更しません(どちらの場合も105.5px)。温度は学習の勾配を変更するためのツマミであり、デコーディング結果を変更するためのツマミではありません。この例の4pxの誤差は意図的に加えたノイズによるものです。
量子化誤差をxの1軸で比較しました(完璧な予測、ランダムな位置2万個)。
| 出力 | マスのサイズ | 平均誤差 |
|---|---|---|
| SimCC k=1 | 1画素 | 0.249px |
| SimCC k=2 | ½画素 | 0.125px |
| SimCC k=3 | ⅓画素 | 0.084px |
| 2Dヒートマップ ¼解像度、argmax | 4画素 | 1.012px |
ロジットにノイズを混ぜると(1千回)、k=1・2・3の平均誤差が2.97・2.54・2.37pxとなり、マスを細かく分割するメリットがノイズに埋もれて小さくなります。SimCCの論文でもkを1〜4でテストし、2〜3が最も良いとしています。細かく分割しすぎると、マスごとの学習信号が薄くなります。
出力サイズ(関節ごとの値の数)は以下の通りです。
2D 히트맵 ¼ 해상도 48×64 = 3,072 → 17관절 52,224
SimCC k=2: 384 + 512 = 896 → 17관절 15,232
低解像度で特に強い
SimCCのメリットは、入力が小さいときに大きくなります(論文、COCO val、HRNet-W48)。
| 入力 | ヒートマップ + ¼マスシフト | SimCC |
|---|---|---|
| 64×64 | 48.5 | 59.7 |
| 128×128 | 68.9 | 72.0 |
| 256×192 | 75.1 | 75.9 |
第7篇の結論と同じです。マスが粗いほどデコーディングの量子化が大きな問題になり、SimCCはその量子化を出力構造からなくします。
4. RTMPose:学習のコツを1つずつ積み重ねる
RTMPose(2023)はトップダウン方式です。人物検出器(RTMDet)がボックスを見つけ、CSPNeXtバックボーン → 大きな畳み込み(7×7) → 関節ごとの特徴 → アテンション層(GAU) → SimCCの2つの分類器により関節を見つけます。この論文の価値は構造よりも、 学習のコツを1つずつ加えながらその効果をすべて記載した表にあります(COCO val、RTMPose-m)。
| ステップ | AP |
|---|---|
| 出発点 | 69.7 |
| バックボーンをヒートマップ(UDP)で先行学習 | 70.3 |
| + 指数移動平均(EMA) | 70.4 |
| + 学習率スケジュール(平坦な後にコサイン) | 70.7 |
| + 2段階の拡張(強く180エポック → 弱く30エポック)など | … |
| + アテンション層(GAU) | 71.9 |
| + 温度 τ=0.1 | 72.7 |
| + x・y個別のσ | 72.8 |
| + 7×7畳み込み | 73.3 |
| + 420エポック | 73.7 |
| + データ追加(AI Challenger) | 75.3 |
ラベルは「ガウス距離で作った分布にソフトマックス」を適用した形であり、予測とラベルの両方に温度を使用します(論文)。強い拡張は、サイズ0.6〜1.4倍、回転80度、一部を消去する(Cutout)を常に行う程度でした。学習データの条件が異なるバージョンが複数あるため(COCOのみ / AI Challenger追加 / 反転テスト含む)、75.8のような数字を引用する際はどのバージョンであるかを合わせる必要があります。
速度(論文、RTMPose-m):デスクトップCPU(ONNX Runtime)で11.06ms、デスクトップ級GPU(TensorRT)で2.29ms、スマホSoCで35fps以上。小さいバージョンのRTMPose-sは、スマホSoCで13.89ms(70fps以上)、72.2 APです。人物検出器を毎フレーム実行するのではなく数フレームごとに実行し、その間は前のフレームの姿勢でボックスを作成します。
5. RTMO:人物検出器をなくす
トップダウンの弱点は、人数に比例する処理時間と、検出器を別途実行する負担です。RTMO(CVPR 2024)は物体検出器(YOLO系)のように画像を格子状に分割し、マスごとに「ここに人はいるか、いるならボックスと関節は何か」を一度に出力します。
関節座標はSimCCのように1D分類で出力しますが、マスを画像全体ではなく そのマスが予測した人物ボックス(1.25倍に拡大)の内部だけに 展開します(動的座標分類器、DCC)。人物が小さくても大きくてもボックス内をx 192マス・y 256マスに分割するため、解像度が人物のサイズに合わせられます。
損失も変更しました。正解分布とのKLの代わりに、「予測位置の周辺のガウス分布から正解が出る尤度」を最大化しつつ、 分布の幅(不確実性)もネットワークが同時に学習する ようにしました(最尤推定、MLE)。同じRTMO-sにおいて、KLが64.4、座標回帰(OKS損失)が65.6、MLEが 67.6 でした(COCO val、論文)。第5篇のSEA-RAFTのように、本来曖昧なケースへのペナルティを軽減する損失が勝った例です。
| 項目 | 値(論文) |
|---|---|
| COCO val(COCOのみ学習) | RTMO-s 67.6 ・ -m 71.2 ・ -l 72.5 |
| アブストラクトの代表的な数値 | RTMO-l val 74.8、データセンター級GPU1枚で141fps(学習データ・ランナーの条件はアブストラクトに記載なし) |
| COCO test-dev | s 66.9 ・ m 70.1 ・ l 71.6(外部データ追加時は 67.7 ・ 71.5 ・ 73.3) |
| CrowdPose(混雑したシーン) | RTMO-l 73.2(CrowdPoseのみ学習) |
| トップダウン(RTMPose)との比較 | 人物が4人前後からRTMOの方が高速(ONNX Runtime)。1人から10人以上に増えても遅延の増加は約0.1ms |
6. 限界
- 精度と速度は依然としてトレードオフです。 ViTPose-Gの80.9とRTMPose-sの72.2の間には9点近い差があります。スマートフォンで動かす必要がある場合は、下位のモデルから選ぶ必要があります。
- COCOは卓球ではありません。 COCOは日常の写真です。卓球のスイングにおける素早い腕、ブレた手首、卓球台に隠れた足はあまり代表されていません。論文のAPが卓球映像の精度を保証するわけではありません(未実測)。
- 2Dの関節だけではラケット面はわかりません。 回転をかけたのか、ラケットの角度はどうだったのかは、手首の点1つでは把握しづらいです。ラケットの5点を別々に探すRacketVisionのような試みが登場した理由はそこにあります(TT Scoreモデル解剖編 第4回)。
7. 我々のプロジェクトとのつながり
- 実測:サーバーではRTMPose、ブラウザではMediaPipe。 TT Scoreコーチングのサーバー分析はRTMDet-m + RTMPose-m(ONNX Runtime)を使用し、サーバーのGPUを共有する場合の処理時間は人物検出が50〜98ms、関節検出が6〜10ms/フレームでした。ブラウザ側のMediaPipeはラップトップのヘッドレスブラウザで12〜15ms/フレームであり、実際のスマートフォンでの実測は行っていません(TT Score第4回)。
- 実測:CPUでは重い。 スコアエンジンの実験で、RTMPose-mをOpenCV DNNによりCPU上で動かした場合、1つのボックス(540×720)あたり74msでした(他の作業とCPUを共有した際の中央値、TT Score第4回)。60fpsのリアルタイム処理において毎フレームに組み込むことができない理由はここにあります。
- RTMOを見る理由。 その実験において、人物検出器RTMDetのONNXファイル内のNMS演算をOpenCV DNNが読み込めず、人物のバウンディングボックスの代わりにボールの周囲のボックスを使用せざるを得ませんでした。検出器が別になっていないRTMOはこの障害を回避し、ダブルスの4人も一度に処理します。まだ検証や測定は行っていません(未実測)。
- 蒸留で育てたモデル。 全身133点を検出するDWPoseは、RTMPoseを第4回の2段階蒸留によって育てたモデルです。手指の関節が必要になった場合の候補となります。
TTの一言。 座標を「何番目のセルか」という分類問題に変更したことで、マップを描いていた3,072セルが896セルに減少しました。そして、温度は正解を変更するのではなく学習方法を変更するためのノブであることも、直接計算して確認できました。
参考文献
- Xu et al., ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation, NeurIPS 2022. https://arxiv.org/abs/2204.12484
- Li et al., SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation, ECCV 2022. https://arxiv.org/abs/2107.03332
- Jiang et al., RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose, arXiv 2023(技術報告書). https://arxiv.org/abs/2303.07399
- Lu et al., RTMO: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation, CVPR 2024. https://arxiv.org/abs/2312.07526
- Yang et al., Effective Whole-body Pose Estimation with Two-stages Distillation(DWPose), ICCV 2023 Workshop. https://arxiv.org/abs/2307.15880
- サンプルコードと出力:
code/08_simcc.py,code/08_simcc.out.txt