Diagonal Gaussian Likelihoodを実装せよ
よし
1 2 3 4 5 |
Args: x: Tensor with shape [batch, dim] mu: Tensor with shape [batch, dim] log_std: Tensor with shape [batch, dim] or [dim] |
だから、
ここをみると、
xはaction、muはmean μ、log_stdは標準偏差のログやって理解できる。
1 2 3 4 |
feed_dict = {x: np.random.rand(batch_size, dim), mu: np.random.rand(batch_size, dim), log_std: np.random.rand(dim)} |
で作ってるから、x
とmu
は0.0以上、1.0未満の乱数のbatch_size x dim
の配列となる。
でもそれで、[batch, dim]
ってわかりにくくないか…
そんなん誤解する。
log_std
は1次元。
んで、πをどうするかムズ…
πはpolicy。
“The policy is trying to maximize reward.”
だから、aの一番大きい値にしてみる。
それと、logの底は10だと思うので
1 2 3 4 |
log_10 σ = 〇 やから σ = ◯^10 |
これで、標準偏差でるのではないかな。
とまぁ計算方法をみたが、なぜDiagonal Gaussian Likelihood
を求めたいのだろうか。
The two most common kinds of stochastic policies in deep RL are categorical policies and diagonal Gaussian policies.
それは、policyの確率として表される。
Categorical policies can be used in discrete action spaces, while diagonal Gaussian policies are used in continuous action spaces.
連続的なaction spacesの時は、diagonal Gaussian policiesが適用される。
つまりは、行動の種類(x)と、報酬の平均値(mu)、標準偏差のログ(log_std)からpolicyの確率(パラメーター化されたpolicy)として扱うためのdiagonal Gaussian policiesをここでは計算する。
実装
そこで、考えたのがこれ。
1 2 3 4 5 6 7 8 |
def gaussian_likelihood(x, mu, log_std): gl = 0 for a, u, log_sigma in zip(x, mu, log_std): sigma = log_sigma ** 10 gl += (a - u) ** 2 / sigma ** 2 gl = -1/2 * (gl + np.shape(x)[0] * np.log(2 * np.max())) return gl |
ただ、そもそも、tensorをloopできないという。
"Tensor objects are only iterable when eager execution is "
めちゃくちゃ検討違いなことをやってそうなので答えを…見るか!
解答
1 2 3 4 5 6 |
EPS=1e-8 def gaussian_likelihood(x, mu, log_std): pre_sum = -0.5 * (((x-mu)/(tf.exp(log_std)+EPS))**2 + 2*log_std + np.log(2*np.pi)) return tf.reduce_sum(pre_sum, axis=1) |
まず、大前提の参照するべき式は合っていた(当然か)。
しかし、tensorflowの計算方法がダメダメだった。
もうtensorのまま計算できるんだ。便利なんだ。
まぁ、-0.5
だろうが、-1/2
だろうがそこはどうでもいいだろう。
log_stdの解釈は合っていただが、標準偏差(std)にするときに(tf.exp(log_std)+EPS))
…
あれ?こうすればいいんだっけ?
そうか、ここのlogはlnなのか…自然対数なのか…
だから、
1 2 3 4 |
log_e σ = 〇 だから σ = ◯^e |
だっ
しかしこのEPSというめっちゃ小さい数は何だ?
これはオーバーフロー対策なんだな。
たぶん、演算の後ろの桁が答えになるんではないだろうか?
なので、小数点以下8桁で終わらす!
その他は、だいたい合っていたが大きな勘違いを2つしていた。
- πはリアルπだった。policyではなく。
- Σの計算方法が間違っていた(ヤバイ)。式全体を足すのか…これガチか…Σ()内だけではないのか…ガチか…
次回はちゃんとtensorで計算しよう。
debug方法
pythonのコンソールから
1 2 3 4 5 6 7 8 9 10 |
# Initialize session import tensorflow as tf sess = tf.InteractiveSession() # Some tensor we want to print the value of a = tf.constant([1.0, 3.0]) a.eval() #=> array([1., 3.], dtype=float32) |
こういう感じにevalを使えばよいらしい。