Optimizationクラス

使い方

  • 教師データ(物体の位置とキャラクタのポーズ)を与えると、パラメータを最適化してくれる。
  • 1. __init__に書いてある変数(計算回数、教師データのファイル名など)をセット
  • 2. start()を呼ぶと計算開始
  • 実際の計算(CMA)は別クラス(Cmaesクラス)が担当する。

評価関数

  • Evalクラスによって与える
  • シミュレーションを行って、その結果にしたがって評価値を決める。
  • ObjectFunction関数が目的関数
    • paramを受け取って、シミュレーションを回し、評価値をreturnする。
  • 1. 受け取ったパラメータをSpringhead SceneやScript paramsにセット
  • 2. LoadState(spbのrestoreを使う)して状態を初期状態(Optimizationクラスが作られた時にSaveStateされてる)に初期化
  • 3. 教師データに示されたエリアごとにエリアのステップ数回シミュレーションしながら教師データとの比較を行って誤差値を作り、総和をとる。
    • 誤差値を作る作業は個別の関数が担当
      StepErroDirectionTarget:オブジェクトが指定された時。頭の姿勢の差分を見る
      StepErrorBIas:視線方向が指定された時。全身の関節角の差分を見る
      StepErrorDirectionNone : 何も見てはいけない。視線に偏差があるとマイナス
  • 4. 得られた総和を評価値として返す
  • 教師データ
    • 物体の教師データ: オブジェクト名/座標 が並んでいる
    • 興味の教師データ: Evalクラスのtestcode関数に直書き(何ステップから何ステップにどれを見ていた(または視線方向))
      • app0128_01.txt(ステップごとに注意対象の物体が書いてある)をもとに手書きした
    • 視線の教師データ: train0128_01.txtなど 何ステップ目/視線方向を示すベクトル   → self.DirectionAreaDataにロードされるので、それをtestcode内で使う
  • 最適化プロセス
    • Optimizationクラスのstart()内で、barecmaes2ファイルのfmin関数を呼び出すことで開始。
    • fminは
      • 1. 目的関数
      • 2. 探索出発点となる初期パラメータ
      • 3. 個体をバラ撒く範囲を決めるパラメータ
      • 4. 探索回数
      • 5. 評価値がいくつ以下になったら停止するかの閾値
      • 6. mode(0以下のパラメータを個体として生成しない、1以下を(以下同様)、など個体生成にまつわるモード)   :本当は 次元数個のrangeのリストを渡すのがよいだろう
    • を受取り、
      • 1. 最適パラメータ
      • 2. 最適パラメータ時の評価値
      • 3. なぜ終了したか(計算回数が指定回数を超えた、評価値が指定値以下になった、平均値が全く動かなかった): 文字列=>対応する値(計算回数、評価値、など) のハッシュで返る。
    • などを(リストで)返す。
  • fmin関数の中身
    • Cmaesクラスを作って動かす。
      終了条件(stop)になるまで 個体生成(ask) ・ 評価(目的関数をcall) ・ 共分散行列と平均値の更新(tell) を繰り返す
  • Cmaesクラスの中身は、基本的には文献通り。
    • 個体数は文字列で数式指定できる。Nは次元数。ただしあまり使ってない。
    • askの中で個体生成している。
      個体をrangeで切るのに、range内に収まるまで繰り返し生成となっている。効率悪いのでなんとかしたい。
  • 行列ライブラリは使っておらず、行列は二重配列で表現している。
    • 固有値分解を行う関数 eig だけは必要で、どこかから取ってきた。
  • やってほしいと思ってること
    • 評価関数の汎化 : Stepを回すのは共通化して、Errorの計算のみif分岐したほうがいいのではないか。
    • 教師データの与え方をもっと洗練する。Blenderのキーフレームとか使いたい
    • creature ruleで使うパラメータ変数を spb.parameter というファイルに置かないといけない。creature handlerに持たせる(sprスレッドから見える必要あり)など検討すべき
    • CMA計算中は完全に固まってしまう。途中の状況を確認したい。別スレッドを建てるか、Spr.pydに放り込んでしまう(C++化)のも手かも。
  • 注意
    • IK enableとかをscript内に書いてはダメ。1~2ステップ目からenableされることになり結果が一致しなくなる