研究トップへ
Main Research / 大学院研究

キャラクター性と感情を
分離したモーション生成

「そのキャラクターらしさ」と「感情表現」を独立した潜在軸に分離し、 学習データに存在しない組み合わせのモーションを生成する研究です。 モデルはフルスクラッチ実装で、破綻の原因究明と対策を定量指標で回しながら改良を重ねています。

PyTorchTransformer拡散モデル 潜在空間の分離敵対的学習自己教師あり学習three.js
GOAL
未学習の「キャラ × 感情」組合せでの動作生成
LATENT
z_char (64 次元) × z_emo (64 次元)
SCALE
約 3,000 クリップ / 30 万イテレーション級の学習
STATUS
学会発表を準備中

問題設定

モーションスタイル変換の先行研究では、スタイルは1 つのまとまった属性として扱われます。 ところがキャラクターに動きを与える現場では、指定したいものが少なくとも 2 つあります。

  • キャラクター性:喜んでいても怒っていても「同じキャラクターだ」と分かる、その人固有の動きの癖
  • 感情:誰が演じても「喜んでいる」と伝わる、感情由来の動きの変化

スタイルが 1 軸のままだと、この 2 つを別々に指定できません。 「ゾンビらしさは保ったまま、感情だけ喜びに変える」といった操作ができないため、 スタイルを 2 軸に分解して独立に制御することを研究の主題に置きました。

単調な歩行モーションを、キャラクターの軸と感情の軸の組み合わせで9通りのスタイルに変換した図
同じ「歩く」動作に、キャラクター性(縦)感情(横)を 別々に付与して生成する
研究の動機:ロボットやキャラクターが意図を言葉以外で伝えるには、動作表現の制御が要になります。 「キャラクターの一貫性」と「感情の伝達」は本来別の要求であり、 まとめて扱う限りどちらかが犠牲になるのではないか、という問題意識が出発点です。

データの制約と定式化

この問題には、データ側に厄介な制約があります。入手できるモーションキャプチャデータは キャラクター別のもの感情別のものが別々に存在し、 「このキャラクターがこの感情で動いている」という両方のラベルを同時に持つクリップがほとんど存在しません

そこで、片方の軸しかラベルを持たないクリップに対して、 もう一方の軸には「中立クラス」を割り当てて完全な教師データとして扱う定式化にしました。 キャラクター側は 9 種のキャラクタースタイル+中立、感情側は 6 種の感情+中立で構成しています。

この定式化のもとでは、学習中に一度も見ていない 「キャラも感情も中立でない組み合わせ」を生成することが最終目標になります。 つまり正解データが原理的に存在しない領域での生成が本質的な難所であり、 これが後述する破綻の主因にもなりました。

モデル構成

既存実装の改造ではなく、データローダから学習ループまで PyTorch でフルスクラッチ実装しています。

CONTENT ENC.
動作内容を抽出する Transformer。時間方向の正規化でスタイル成分を落とし、「何をしているか」だけを残す
STYLE ENC.
参照クリップから attention pooling で z_char(64 次元)と z_emo(64 次元)を別々に抽出
DECODER
内容特徴を受け取り、2 つの潜在で変調(AdaLN / ゼロ初期化)しながらモーションを再構成する Transformer
DISENTANGLE
各潜在に対する分類ヘッド(自軸のラベルを当てる)と、勾配反転による交差分類ヘッド(他軸のラベルを当てられないようにする)を併設
LOSSES
再構成、サイクル一貫性(スタイル/内容)、逆サイクル再構成、ルート軌跡アンカー、骨長一貫性、出力空間でのスタイル分類
MANIFOLD
フレーム単位のポーズ識別器(hinge 損失 + R1 正則化)で「未見の組合せでも各フレームは自然な人間の姿勢」を強制

破綻の原因究明と改良の経緯

この研究でいちばん時間を使ったのは、モデルを増やすことではなく 「なぜ壊れているのか」を切り分ける作業でした。実際の経緯を順に記します。

  1. ISSUE 01 — 転送経路が発散

    再構成は成功しているのに、組み合わせを変えると出力が飛ぶ

    再構成誤差も潜在の分類精度も良好(分類精度 1.00、交差分類は偶然一致水準)なのに、 参照を差し替えた生成結果はルート軌跡が毎フレーム数 m 飛び、関節位置も人体から外れました。

    原因は明快で、転送経路の出力には直接の再構成型損失が一つも掛かっていなかったためです。 正解が存在しない組み合わせなので、素朴には損失を書けません。

  2. FIX 01

    正解がない出力を、間接的に拘束する

    逆サイクル再構成(生成結果から元のスタイルへ戻したら元クリップに一致すること)、 ②ルート軌跡アンカー、③骨長一貫性を追加。 骨長は最初は重みが弱く、生成結果の骨が実データの約 4 倍に伸びてしまったため、 正規化前の実スケールで測る損失に組み替えました。

  3. ISSUE 02 — 姿勢が大破する

    「全身が折れたように見える」を数値にする

    見た目の破綻は主観では議論できないため、実データ分布からの逸脱を測る指標を自作しました (生成した各フレームの姿勢が、実データの姿勢集合からどれだけ離れているか)。 結果、実データ同士 4.5cm・再構成 6.7cm に対し、 転送出力は実在する組み合わせでも 17〜20cm 外れていることが判明しました。

  4. DIAGNOSIS — 決定的な切り分け

    参照クリップを「自分自身」にするか「同ラベルの別クリップ」にするかで結果が変わる

    参照に入力自身を使うと誤差 1.3cm(再構成と同等)。ところが 同じラベルの別クリップから潜在を取ると 14.3cm に崩壊しました。 つまり問題はデコーダでも分離でもなく、潜在のクラス内ばらつき—— クリップ固有の情報が z に混入し、デコーダがそれに過敏になっていたことでした。

    潜在の統計を測ると、クラス内分散がクラス間分散を上回っていました(分散比 1.32)。 分類精度 1.00 は「軸が分離できている」ことしか保証せず、 「同じクラスの潜在が互換であること」はどの損失も拘束していなかったのです。

  5. FIX 02

    同ラベルの潜在を入れ替えても復元できるように学習する

    同ラベル入替え教師(同じラベルの別クリップから取った潜在で元クリップを復元させる)と クラス内の潜在引き寄せを追加。結果、入替え時の誤差は 14.3cm → 0.52cm、 潜在の分散比は 1.32 → 0.022 まで下がり、潜在がほぼクラス埋め込みに収束しました。

  6. ISSUE 03 — 敵対ヘッドの発散

    潜在を急に動かす損失と勾配反転の併用で学習が壊れる

    入替え教師を入れた直後、勾配反転側の損失が 2.5 → 169 に発散しました。 潜在空間の再編成に敵対ヘッドが追従できず、 「自信を持って誤分類させて損失を稼ぐ」退化解に落ちていました。 損失に上限を設けて超過時は勾配を止め、重みを下げることで安定させました。

  7. FIX 03

    未見の組み合わせに「人間の姿勢らしさ」を課す

    残っていた「ねじれ」に対し、軌跡を除いた姿勢のみを見る フレーム単位のポーズ識別器を追加。実データ分布からの逸脱は 20.6cm → 16.1cm に改善し、生成結果の構造は目視でも大きく安定しました。

  8. REMAINING — 現在取り組んでいる課題

    スタイルの効きが弱く、時間方向の特徴が転送されない

    構造が安定した一方で、出力が動作内容側に強く引っ張られ、 腕の振りや前傾といったスタイル表現が十分に出ません。 また「ロボットらしいカクカクした動き」のような時間方向のテクスチャが転送されない—— これは時間方向にプーリングした 64 次元の潜在では時間構造を原理的に持てないためです。

定量評価

主観評価に頼らないため、評価スクリプトも自作しました。以下は改良前後の主要指標です。

指標改良前改良後打った対策
同ラベル参照での復元誤差 14.3 cm0.52 cm 同ラベル入替え教師
潜在のクラス内 / クラス間分散比 1.320.022 クラス内引き寄せ
実データ分布からの逸脱(未見組合せ) 20.6 cm16.1 cm ポーズ識別器
骨長のばらつき(変動係数) 8.9 %0.0 % 骨長損失+推論時の階層リスケール
ルート軌跡のドリフト 0.039 m/f0.010 m/f 軌跡の再構成拘束
目標スタイルへの分類一致率 0.981.00 出力空間のスタイル分類

最後の指標が示すとおりスタイル転送自体は機能している一方、 実データ分布からの逸脱は実データ同士の 4.5cm にはまだ届いていません。 未見の組み合わせ領域が残った課題であることを、この指標で明確に切り分けられています。

アーキテクチャの改良

「スタイルの効きが弱い」「時間方向の特徴が入らない」という課題に対しては、 損失の調整ではなく構造側で解く方針で新しいモデルを実装しました。

  • 身体部位ごとのトークン化:全身をひとまとめに扱わず、体幹・両腕・両脚・ルートに分けた「部位 × フレーム」の格子として扱う
  • 部位別のスタイル注入:各部位のトークンが自部位のスタイルトークンのみを参照する cross-attention により、フレームごと・部位ごとにキャラ性と感情の配合が変わる局所的な注入を実現
  • 部位ドロップアウトによる自己教師:学習中に内容側の部位をランダムに欠落させ、欠けた部位はスタイル参照から復元せざるを得ない状況を作ることで、スタイル主導の生成を直接学習させる
  • 速度情報の明示入力:フレーム間差分をスタイルエンコーダに与え、「カクカク感」のような高周波の時間構造を捉えられるようにする
  • 推論時のスタイル主導指定:「腕だけスタイル主導」といった部位単位の制御をノブとして用意(腕を指定すると腕が 7cm 変化し脚は 0.19cm しか動かない、という局所性を確認済み)
実装上の落とし穴:部位 × フレームの格子はトークン数が数倍になるため、 注意機構の呼び出しで注意行列を実体化させる設定が残っていただけで VRAM が 30GB に膨張し、 共有メモリへの退避で学習速度が 100 分の 1 になりました。 設定の修正と、勾配チェックポイントとバッチサイズの実測比較で解決しています。

応用:言語指示からのリアルタイム生成

生成モデルを研究の中で閉じさせず、使える形にして初めて分かる課題を拾うため、 言語指示からモーションを出すリアルタイム版も実装しました。

  • 大規模なモーションデータセットから動作内容を検索できるライブラリを構築(約 6,000 窓)。多言語埋め込みを使い、日本語の指示から英語ラベルの動作を検索できる
  • 学習済みモデルの潜在をクラス平均としてスタイルパレット化し、推論時は内容エンコーダとデコーダの 2 回のフォワードだけで済ませる
  • 実測でサーバ内 25〜45ms、ブラウザ体感で平均 230ms 程度。「悲しそうにギターを弾いて」のような指示が動きになる
  • この応用は対話アバター(AvatarChat)へ組み込み、言葉と動きのトーンを揃える形で利用している
応用してから分かったこと:体感品質を決めたのは生成モデルの精度よりも 応答が返るまでの待ち時間でした。研究の評価指標だけを見ていると気づけない観点で、 「使う形にしてから評価する」ことの価値を実感しています。

この研究で身についたこと

  • 指標がなければ改善は空回りする:「見た目が変」を数値化する指標を作った時点で、原因の切り分けが一気に進んだ
  • 高い精度は目的の達成を意味しない:潜在分類精度 1.00 は「分離」しか保証せず、本当に必要だった「同クラス潜在の互換性」は別の損失でしか担保できなかった
  • 敵対的学習は他の損失との相互作用で壊れる:潜在空間を急に動かす損失と併用すると退化解に落ちる、という具体的な挙動を経験した
  • 損失で殴る前に構造を疑う:時間構造が入らない問題は損失調整では解けず、表現の持ち方(トークン化の粒度)を変える必要があった