MkItYs

MkItYs > 音楽・漫画・VR・自律制御 > 

images

ヒトの歩く姿勢に近づける#1(創発手法):Unity (ML-Agents (Walker)), PPO, VRM (VRoid)

images

観察の対象や報酬の内容を変えることで、キャラクタの動きを変えていきます。

関連


物理ベースのキャラを、強化学習で自律的に歩かせる:Unity (ML-Agents (Walker)), UnityChan, VRM (VRoid) , DAZ

創発手法


別記の模倣学習(逆強化学習)との対比から「創発的」な手法とも言われていますが、ようは観察の対象や報酬の内容を変えることで、キャラクタの動きを変えることですーー強化学習ほんらいの調整のしかたですね。

歩行の調整でいえば……極端な例を挙げると、次のように<気をつけ>の姿勢になれば報酬が大きくなるようする、といったやり方です:[※1][※2]

    public override void CollectObservations(VectorSensor sensor)

        sensor.AddObservation(hips.up.y); // MOD
        sensor.AddObservation(chest.up.y); // MOD
        sensor.AddObservation(spine.up.y); // MOD
        sensor.AddObservation(head.up.y); // MOD
        sensor.AddObservation(thighL.up.y); // MOD
        sensor.AddObservation(shinL.up.y); // MOD
        sensor.AddObservation(thighR.up.y); // MOD
        sensor.AddObservation(shinR.up.y); // MOD
        sensor.AddObservation(armL.right.y); // MOD
        sensor.AddObservation(forearmL.right.y); // MOD
        sensor.AddObservation(-armR.right.y); // MOD
        sensor.AddObservation(-forearmR.right.y); // MOD

    void FixedUpdate()

        AddReward(hips.up.y); // MOD
        AddReward(chest.up.y); // MOD
        AddReward(spine.up.y); // MOD
        AddReward(head.up.y); // MOD
        AddReward(thighL.up.y); // MOD
        AddReward(shinL.up.y); // MOD
        AddReward(thighR.up.y); // MOD
        AddReward(shinR.up.y); // MOD
        AddReward(armL.right.y); // MOD
        AddReward(forearmL.right.y); // MOD
        AddReward(-armR.right.y); // MOD
        AddReward(-forearmR.right.y); // MOD

報酬の追加とともに、(元のスクリプトにはボーンとワールド座標との比較がないので)観察の対象も加えています(float 型を12コ)。また、その分を加算した値を、次の項目にも設定する必要があります(float 型の観察の場合は、観察1コにつき1コの加算になります):

BehaviorParameters > (VectorObservation) > SpaceSize

とはいえこれは、あまりにあからさま過ぎて(状態(独立変数)と報酬(従属変数)が完全に対応しているので)、あくまで様子をみるための試験的な設定ですが。[※3][※4][※5]

ちなみに上記のスクリプトだと、こんな感じになります:


※1
ヒトの歩行の自然な動きは、重力に抗しつつ、できるだけ筋力に負担をかけない姿勢です。じっさい立っているとき、もっとも体に負担のかからない形は、直立(<気をつけ>)の姿勢ですーーこれをキチンを記述するなら、各関節(ジョイント)にかかるトルクを計算し、その総量がもっとも小さくなるように報酬を与える、ということになるでしょうか。
※2
学習するときの最初の姿勢が<中腰>になるのは、それが各関節の中間値を合わせたものだからですーー各関節(ジョイント)に対するXYZの各回転には、最初、可動範囲の中間値が入ります(Unity で、アニメーションクリップがないとき、アニメーション・コントロールが表示する姿勢と同じですね)。
※3
このような設定はほぼルールベースと言ってよく、また汎用性も犠牲にしていますーーワールド座標を基準にしているので傾斜には対応できず、すべてのボーンの向きがワールド座標と一致しているモデル(VRM 、など)にしか使えません(たとえばUnityChan / SD_UnityChanの場合、各ボーン向きはワールド座標と違います)。
※4
報酬は正規形(0〜1の範囲)が望ましいのですが、Unity の方向をあらわす構造体も単位ベクトル(0〜1の範囲)です。なので、そのまま正規形になっている、というのが利点といえば利点でしょうか。
※5
いずれにしても、状態と報酬の関係でエージェント(=キャラクタ)に分かるのは、ただ<数値の増減だけ>です。状態がどのような由来からくるのかも、どのように行動すれば報酬の数値が上がるのかも、エージェントには分かりません。あくまで試行錯誤を重ねるなかで、<状態と報酬の関係を知っていく>ことになります(報酬と相関する数値が、観察の対象にないと、エージェントは学習できません)。