* Optimizationクラス [#cbdc0631]

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


** 評価関数 [#b7dd2383]

- 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) を繰り返す
 終了条件(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されることになり結果が一致しなくなる