要約。 新しい技はすべて、私自身のモーションキャプチャから始まります。スマートフォン2台で撮影し、オープンソースのソフトウェアを使ってGPU上で3Dに再構成します。そこからファイターが使えるようになるまでに、さらに6つの段階を通ります。ファイターの体へのリターゲット、バリエーションの表、技ひとつだけの教師、評価ゲート、生徒への蒸留、そして最終チェックです。段階と段階のあいだでは毎回、私が結果を確認します。どの段階も、数字には表れない形で間違うことがあるからです。この記事の後半はその一例です。ボディへの奥足の膝蹴りは、すべてのテストに合格しました。当たり、倒れず、私の動きにも従っていました。ところが膝を下ろしたあと、ファイターは約0.5秒のあいだ後ろに反り返っていました。報酬はそれを許していましたが、対戦相手は許してくれません。まっすぐな姿勢に戻る参照モーションと、それより後ろに傾いたときだけかかる片側のペナルティを加えたところ、参照を超えた後傾は空中で12.4°から1.3°に、サンドバッグ相手で9.7°から0.9°に減りました。サンドバッグへの膝蹴りはすべて当たり、倒れた回もありません。この修正は生徒への蒸留後も保たれました(1.4°と1.2°)。
説明することから、キャプチャすることへ
始めたころ、私はファイターに、初心者に電話で教えるようなやり方で教えていました。技を言葉で説明し、いくつかの角度から撮った自分の写真を送り、見えたところを直していきます。肘をもっと締めて、もっと伸ばして、腰を回して、という具合です。構えとバランスやジャブはそうやって、シミュレーションの体そのものの上でポーズを設計して作りました。これらについては十分うまくいきました。
大きな動きではうまくいきません。膝蹴りや蹴りは、全身を大きな角度で素早く動かし、しかも出来事の順序が重要です。どちらの足が先に床を離れるか、いつ腰が回るか、バランスを取るために腕がどこへ行くか。それをすべて言葉で説明しても、動くものはできますが、ムエタイらしく見えるものにはなりません。そこでモーションキャプチャに切り替えました。
パイプライン
市販のモーションキャプチャシステムは使っていません。すべてオープンソースで、主にPose2Simを使っています。そのため、重い処理はいちばん安いGPUマシンで動かせます。図1が各段階です。紫の段階は、次の段階が始まる前に私が結果を見て終わります。
- 1
撮影私、スマートフォン2台
床にキャリブレーションボードを置き、それぞれのスマートフォンの位置から一度ずつ撮影します。そのあとボードを片付け、2台のスマートフォンを60〜90°離して置き、動かさずに60 fpsで技を撮影します。
- 2
2DキーポイントGPU
姿勢推定器(かかととつま先付きのRTMPose)が、両方の動画の全フレームで関節を見つけます。30秒のテイクで約2分です。
- 3
同期と三角測量GPU / CPU
2本の動画を音で揃え、2つの視点から各関節を3Dに三角測量し、軌跡を滑らかにします。
- 4
私の骨格に合わせるCPU
私の寸法に合わせた骨格を3Dの点に当てはめ、フレームごとの私の関節角度を求めます。
- 5
リターゲットCPU
私の関節の向きと回転をファイターの体に移し、小さな逆運動学の処理で接地している足を接地したままにします。
私が確認 シミュレーションを私の動画の横に、それぞれのスマートフォンの視点で、1フレームずつ。おかしなところに印を付け、私をそのまま写すか、彼の体でうまく機能するほうを取るかを選びます。
- 6
バリエーションの表CPU
少し高い、低い、左、右の標的に向けて技を解き直し、どこにいても打てるようにします。
私が確認 四隅とその中間。膝がねじれたり足が浮いたりするところです。
- 7
教師レンタルGPU
最新モデルのコピーが、表を相手に、この技だけ(とその構えとバランス)を強化学習で学びます。
私が確認 1日を通して送られてくる短い途中経過のクリップ。
- 8
ゲートCPUマシン
決定論的なテスト:空中とサンドバッグでのヒット、転倒、足、向き、傾き。
私が確認 最終動画をスローで。
- 9
生徒への蒸留レンタルGPU
1体の生徒が、すべての技をそれぞれの教師から学びつつ、古いスキルもすべて保ちます。
私が確認 生徒のゲートと動画。ここで見つかった欠点は教師で直し、もう一度蒸留します。
図1 撮影した技から、生徒の中のスキルへ。ターコイズの段階は人の手を介さずに動き、紫の段階は私の確認で終わります。何かおかしな点が見つかれば、技は1段階(あるいは数段階)前に戻ります。段階2〜3はGPUで、段階7と9はレンタルGPU(vast.aiまたはRunPodのRTX 5090、毎秒約30,000シミュレーションステップ)で動きます。
撮影と再構成
2台のスマートフォンは同じ瞬間を2つの方向から見るので、各関節の奥行きは推測ではなく三角測量で測れます。最初の試みでは1台だけを使い、骨の長さから奥行きを推測していましたが、ある時点で構えの脚を左右逆にしてしまい、しかも画像ベースのチェックはすべて通っていました。三角測量がうまくいくには、それぞれのスマートフォンのレンズと位置が正確に分かっている必要があります。それがカメラキャリブレーションで、大きさの分かっている印刷したボードを床に置いて行います。
姿勢推定器が各フレームで私の関節を見つけます。Pose2Simは2本の動画を揃え、関節を三角測量し、ローパスフィルタで滑らかにし(12 Hz。歩行向けの既定値6 Hzだと蹴りの形が丸まってしまいます)、逆運動学を使って私に合わせた骨格を当てはめます。
どこで間違うか
再構成の質は良いのですが、確認せずに使えるほどではありません。これまでに見た誤りは3種類に分けられます。
- 誤った推定。 床より下にあると判断された足は押し戻され、体が数フレームのあいだ上下に跳ねます。カメラにまっすぐ向いた手足は関節の上につぶれ、カメラに向いた足裏は膝を足の上に引き寄せ、体が横向きになると左右が入れ替わります。後で使う膝蹴りのテイクでは、膝蹴りのあと0.06秒のあいだ、再構成が私の骨盤を26 cm後ろに飛ばし、奥足が跳ねてしまったので、クリップの終わりを差し替える必要がありました。
- 体の違い。 ファイターの脚は、胴体に対する比率で私より約25 %長いです。私の関節の位置をそのまま写すと、肘が頭にめり込み、膝がおかしく曲がります。そのためリターゲットでは向きと回転を写し、何かに触れる必要がある部分だけを固定します。それでも彼の体には私にはない限界があります。私は膝蹴りのあと奥足を腰の約31 cm後ろに着きますが、これは彼の股関節の可動域を超えるので、彼の足は8 cm手前に着きます。
- 見えないものの推定。 前腕のひねり、手首、鎖骨はカメラから見えないので、構えの状態に固定しています。
そこで段階5は確認です。私の動画と、それぞれのスマートフォンの視点で描画したシミュレーションのファイターを並べてスローで見て、違いを指摘します。違いのひとつひとつが選択です。私をもっと正確に写すか、彼の体でよりうまく機能する違いを受け入れるか。修正は、名前の付いた関節にかける、なめらかに変化するオフセットの層に入ります。
バリエーションの表
ファイターは、記録したひとつの位置からだけ打てばいいわけではありません。試合では彼も対戦相手も動いているからです。そこで各技は表になります。同じ打撃を、少し高い、低い、左、右の標的の格子に向けて解き直したものです(蹴りではそれぞれの方向に±10 cm)。学習中、標的は格子の内側のどこにでも置かれ、参照モーションは最も近い項目のあいだで補間されます。
参照が完璧でも、表に悪い項目ができることがあります。ローキックとミドルキックでは、スイッチのホップ中に、足の逆運動学が4フレームのあいだに膝を約40°内側にはじいていました。測定したどの数値もそれを捉えず、私がプレビューで見つけました。そこで段階6も確認です。
教師、ゲート、生徒
教師とは、この技だけを練習する最新モデルのコピーです。各エピソードはこの技のボタン押しで、そのあいだにバランスを試すための押しが入ります。強化学習(PPO)で学び、参照に従うこと、標的に当てること、倒れないことで報酬を得ます。参照をそのまま写すわけではありませんし、写すこともできません。参照には物理が入っていないからです。私のキャプチャは、サンドバッグが押し返してくることも、ファイターの質量の分布が私と違うことも知りません。参照をそのまま写す方策(ポリシー)は倒れてしまうでしょう。学習中、GPUマシンは短いクリップを送ってきて、私は1日を通してそれを見ます。
その後、ゲートが決定論的なテストを行います。空中と重いサンドバッグへの膝蹴りを、それぞれ6つのシードで行い、ヒット、転倒、最後の足の位置、向き、どれだけ傾いたかを見ます。合格した教師は生徒に蒸留されます(方策蒸留。シャドウクローンの記事で説明しています)。生徒はもう一度チェックします。蒸留は2回目の学習であり、その中で何かが変わることがあるからです。
それだけのことをしても、結果が間違っていることがあります。
事例:右の膝蹴り
ボディへの奥足の膝蹴りは、10月23日の私のテイクから来ています。前足が約28 cm踏み込み、奥足が床を離れ、腰が約70°回り、右膝が対戦相手のボディに向かって上と前に突き上がります。インパクトの高さは1.14 mです。膝が下り、奥足は離れた位置より前に着地し、ファイターは構えに戻ります。この技の教師には3回のランがかかりました(作業ログ)。1回目はすべての膝蹴りを当てましたが、0.6 m前に出てサウスポーの構えで終わりました。2回目で足を直し、3回目のkneeR3で構えに戻るステップができるようになりました。kneeR3はゲートに合格しました。空中で5/6、サンドバッグで6/6、足は構えに戻り、転倒なし。そして生徒distill4に入りました。
学習の目的が許していたこと
細部を省くと、教師は各ステップ t で次を最大化します。
rt=wtrackrttrack+whitrthit+wfeetrtfeet+⋯−c1[fall]
参照に従うこと、膝を当てること(標的から5 cm以内で、速く)、参照どおりの位置に足を置くこと、そして倒れないことです。倒れず、姿勢が参照に十分近いかぎり、膝が当たったあとの胴体の形については、これらの項はどれも何も言っていません。
そして実際、十分近かったのです。インパクトのあと、私のキャプチャは少し後ろに傾きます。骨盤が5〜9°後ろ、胸が10〜16°で、構えではそれぞれ0°近くと+1.5°です。kneeR3はその傾きに従い、さらに押し広げて、骨盤を参照より最大約8°後ろに傾けました。胸を参照どおりに保つために腰を約20°反らせていました。腰が前、胸が後ろ。それが反り返りです。そのあと、ときには小さなホップを交えて立て直し、また構えに戻っていました。すべての項が満たされていました。
なぜそれが間違いなのか
私はそれに生徒の動画で気づきました。「膝蹴りのあと、足が地面に戻るとファイターが背中を反らせている」。報酬から見れば、これは完全に良い膝蹴りです。ファイターから見れば、そうではありません。反り返っている0.5秒のあいだ、腰は前に押し出され、肩はその上で後ろに垂れ、足は構えを作るどころか体を受け止めるので精一杯で、ステップもブロックも打ち返すこともできません(図4と図5)。対戦相手が打ってくるのはまさにそのときです。技は膝が当たったときに終わるのではありません。また準備ができたときに終わるのです。
測る
直すには、まずそれを数字にする必要がありました。体の部位の体幹の傾きとは、その部位の「上」の軸 z^ の、床の上で腰が向いている方向 h^ に沿った角度です。
θ=arcsin(z^xy⋅h^),θ>0 forward
これを骨盤と胸について計算します。ゲートの新しい行は、ヒットのあと、どちらかが参照を超えて後ろに傾いた最大値です。
L=t>tupmaxb∈{pelvis,chest}max[θbref(t)−θb(t)]+
ここで [x]+=max(x,0) なので、参照より前に傾くのは0と数えます。tup は後述する直立ウィンドウの開始時刻です。修正後の参照に対して、kneeR3の L は空中で12.4°、サンドバッグで9.7°でした。
修正
変更は2つ。ひとつは目標に、もうひとつは報酬にです。
参照。 キャプチャの7.05秒(腰の突き出しの直後)から7.35秒にかけて、骨盤の傾きと背骨の曲がりを構えのものへなめらかに移し、最後までそのまま保ちます。7.05秒より前の参照は、6.933秒のインパクトも含めて変えていません。学習を始める前に、私がプレビューを承認しました。これは、私を写すことと実際に機能することのあいだのトレードオフのひとつです。膝蹴りのあとの私自身の後傾は小さく、意識せずに立て直せます。しかし彼の体では、方策がそれを自由に誇張できるために、反り返りになってしまいました。
片側だけの報酬項。 ヒットのウィンドウのあと、各ステップで次を与えます。
rtupright=1.5wtexp(−2(5∘)2[θchestref−θchest]+2+[θpelvisref−θpelvis]+2)
ここで wt は、その瞬間に技の項が持つ重みです。これは参照を超えた後傾にかけるガウスカーネルで、参照どおりかそれより前なら1.5、5°後ろで約0.9、10°で約0.2、15°を超えるとほぼ0です。前に傾くのはタダです。ボディへの膝蹴りのあとに前へ傾くのは、ファイターがどのみちやることだからです。
新しい教師kneeR4は、kneeR3からウォームスタートし、レンタルしたRTX 5090 1台で上限の2時間学習しました(207.9 M ステップ、約$1.29)。傾きはほぼすぐに下がり、13 Mステップの時点でサンドバッグの行は9.2°から1.8°になっていました。
結果
図2は、生徒における修正前と修正後の、サンドバッグへの膝蹴り1回のあいだの骨盤と胸の傾きを、ステップごとに示しています。線は6つのシードの中央値、帯はその範囲です。
図2 重いサンドバッグへの奥足の膝蹴り1回のあいだの骨盤と胸の傾き。生徒の修正前(distill4-131.1M、kneeR3の膝蹴り)と修正後(distill7-245.8M、kneeR4の膝蹴り)。時間はボタンを押してからで、毎秒50ステップ。6シードの中央値、帯はその範囲、破線は修正後の参照。どちらもインパクトで大きく後ろに傾いています。これは腰の突き出しで、参照も同じことをしています。違いは着地のあとです。約0.9秒から1.9秒のあいだ、修正前の骨盤は平均で構えより12°後ろ(最悪で20°)にありますが、修正後は5°(最悪で7°)です。構えでは骨盤は約10°前に傾いています。参照は直立ウィンドウのあと0°に保つので、修正後の彼はその2つのあいだで終わります。
空中でも、教師でも、様子は同じです。図3は4つのモデルすべてについて重要な2つの数字を比べたもので、表にゲートの残りがあります。
図3 修正前と修正後。教師(kneeR3-183.5M、kneeR4-183.5M)と生徒(distill4-131.1M、distill7-245.8M)、6シードの中央値。上:ゲートの傾きの行。直立ウィンドウが始まったあと、骨盤または胸が参照を超えて後ろに傾いた最大値。下:直立ウィンドウの終わりから膝蹴りの参照が終わるまで(ボタンを押してから約0.9〜1.9秒)、骨盤が彼自身の構えより平均でどれだけ後ろにあるか。
| モデル | 参照を超えた後傾、空中 / サンドバッグ | ヒット、空中 / サンドバッグ | 転倒 | 最後の足の位置(前足、奥足。構えは0.37、0 m) |
|---|
| kneeR3-183.5M(修正前) | 12.4° / 9.7° | 5/6, 6/6 | 0 | 0.42–0.44, −0.01–0.02 |
| kneeR4-183.5M(修正後) | 1.3° / 0.9° | 0/6, 6/6 | 0 | 0.40–0.41, −0.01 |
| distill4-131.1M(生徒、修正前) | 11.4° / 10.7° | ゲート全体で11/12 | 0 | |
| distill7-245.8M(生徒、修正後) | 1.4° / 1.2° | 2/6, 6/6 | 0 | |
図4 重いサンドバッグに向かう生徒、シード1。右肩の後ろから見ており、カメラは腰と一緒に回るので、背中のラインが真横から見えます。修正前(上、distill4-131.1M)と修正後(下、distill7-245.8M)、ボタンを押してから1.02、1.14、1.26、1.38、1.50秒、奥足が着地した直後です。修正前は、後ろに垂れた胴体の下で腰が前に押し出されています。骨盤は最初の2コマで7°、続いて11°後ろに傾き、4コマ目でようやく構えに戻ります。修正後は骨盤がずっと4〜6°前に傾いたままで、胴体は足の上にまっすぐ積み上がっています。チェックポイントからMuJoCoで描画、決定論的な方策。
私が指摘したのは反り返りでしたが、より気になったのはバランスでした。真後ろから見ると(図5)、修正前の生徒は着地後の時間を、足で体を受け止めることに費やしています。奥足は着地したあと再び浮き上がり、6つのシードで5〜11 cmです。修正後は、足を落ち着かせる際に4〜5 cm上がるだけです。シード1では、両足が同時に0.44秒のあいだ静止時の高さから離れています。倒れないための小さなホップです。修正後はどのシードもそうしません。彼の重心はどちらのモデルでも両足のあいだ、奥足から前足へ約3分の2の位置にあり、倒れそうになったことは一度もありません。倒れはしませんが、構えが整っているわけでもありません。構えが整っていないファイターは戦えません。
図5 同じ膝蹴り、シード1を真後ろから見たもので、カメラはやはり腰と一緒に回ります。修正前(上、distill4-131.1M)と修正後(下、distill7-245.8M)、同じ5つの瞬間です。修正前は着地のあとも体を受け止め続けています。奥足が8 cm、前足が6 cm浮き上がり、0.44秒のあいだ両方同時です。修正後は足を落ち着かせる際に奥足が4 cm上がるだけで、前足は着いたまま、ガードに戻っています。チェックポイントからMuJoCoで描画、決定論的な方策。
修正の代償と、直らなかったこと
- 空中での膝蹴りのヒット。 kneeR4は空中で0/6で、採用されていたkneeR3のスナップショットは5/6でした。修正が一因かもしれませんが、空中の行は修正前から不安定で、kneeR3の後のスナップショットは2/6と0/6でした。空中テストは、標的から5 cm以内を3 m/sで通ったときだけヒットと数えます。これは拳の速さです。参照の膝は1 m/s未満で標的の面を通過するので、私のキャプチャに従う膝蹴りはめったにヒットと数えられません。ボタン押しの4分の3を占め、押しの強さで採点されるサンドバッグでは、すべての膝蹴りが当たっています。
- 腰の上下動。 膝蹴りから戻るとき、腰は今も約4〜5 cm上下し、生徒では修正前と修正後でほぼ同じです。これは指摘した点ではなく、修正の対象でもありません。
- 構えのずれ。 直立ウィンドウは骨盤を参照の構えに持っていきますが、それはベースモデルが実際に立っているガードの構えより約10°まっすぐです。この項は参照を超えて後ろに傾くことだけを罰するので、彼はその2つのあいだで終わります(図2)。よりきれいな修正は、参照の構えをベースモデルから取ることでしょう。
- すべてのスナップショットではない。 修正はkneeR4のスナップショット全体で保たれています(空中で約1〜5°、サンドバッグで0〜1.8°)が、206 Mステップの最後のスナップショットは、あるシードで空中で10.8°傾きました。採用したのは183.5 Mです。
- 小さなサンプル。 1行につき6シード、決定論的です。10°の効果をはっきり見るには十分ですが、1°の差を順位付けするには足りません。
生徒へ
修正は生徒ではなく教師で行いました。生徒の膝蹴りは、写す教師以上には良くならないからです。distill7はdistill4からウォームスタートし、kneeR4を膝蹴りの教師として(新しいアッパーカットの教師2つと一緒に)もう一度蒸留しました。RunPodのRTX 5090で2.5時間です(作業ログ)。生徒とkneeR4の行動の距離(平均二乗誤差)は0.025から0.0027に下がりました。生徒の参照を超えた後傾は11.4° / 10.7°から1.4° / 1.2°になり、教師と同じでした。転倒はなく、サンドバッグへの膝蹴りは6/6、古いスキルはdistill4とほぼ同じ水準です。私はその動画を見て「いいね」と言いました。
コーチとして思うこと
書類の上では、膝蹴りはもう良いものでした。方策は膝の標的へのインパクトを最大化し、倒れれば罰を受け、私の参照に従おうとします。ただし正確にではありません。物理が違うからです。サンドバッグの重さ、反動、私の体と彼の体の違い。もし私を正確に写したら、倒れてしまうでしょう。だから膝蹴りのあとに後ろへよろめき、少し反り返ってから立て直しても、私たちが伝えたすべてに照らせば、まったく問題なかったのです。
でも私が見たとき、目に入ったのはこれだけでした。バランスを崩しているあいだに、彼は打たれる。ジムでは、すぐに立て直せない膝蹴りは、どれだけ強く当たっても悪い膝蹴りです。誰もそれをスコアで数えません。ただ見れば分かるのです。パンチのあとに手を下げるファイターが見れば分かるのと同じです。
だから私は、このパイプラインのどの段階も、数字だけでは信用しません。モーションキャプチャは間違うことがあり、表は膝をねじることがあり、教師はすべての項を満たしながら見た目がおかしいやり方を見つけることがあり、生徒は蒸留の中で何かを失うことがあります。どの場合も、直し方は同じでした。見て、何がおかしいかを平易な言葉で言い、それを学習が測れるものに変え、もう一度確認する。膝蹴りは「方策のすべてに照らせば問題なし」から、リングで見られたらうれしいものになりました。
作業ログ
この記事の元になったランは、次の作業ログにあります。膝蹴りを直した教師と、この記事の図を作った評価・描画用のマシンです(EC2スポット、それぞれ約10分。私の小さな開発サーバーはCPUが制限されているためです)。それ以前の膝蹴りの教師と生徒distill7は、シャドウクローンの記事とそれ自身の作業ログで数えています。コストは各マシンの課金時間に時間単価を掛けたもので、vast.aiの台帳とEC2のスポット価格から出しています。そのため請求額ではなく推定値です。
| 作業ログ | ラン | 時間 | コスト |
|---|
| 評価:奥足の膝蹴りでの傾きを1ステップずつ2026年10月28日 · 上体を立てる修正の前後で、奥足の膝蹴りを通して胴体の傾きを追跡し、記事用の静止画を描画した、EC2 の短時間のマシン4台。 | 0 | 0.4 | $0.11 |
| 教師:上体を立てて着地する奥足の膝蹴り2026年10月26日 · 膝蹴りのあと背中を反らさず、上体を立てて着地させるための、奥足の膝蹴りの教師をもう1つ。 | 1 | 2.1 | $1.29 |
| 合計 | 1 | 2.5 | $1.40 |
|---|