強化學習隨機策略之高斯似然數原理與代碼實現
一、原理介紹
使用隨機策略有兩個關鍵點
- 從策略當中進行採樣,獲得動作 (Action)
- 計算特定動作的似然數
什麼是多元高斯分佈?
在多元高斯分佈中,當協方差矩陣 只有在對角元素非零,而其餘元素爲 0 時,成爲對角高斯分佈。
多元高斯分佈(Multivariate Gaussian Distribution)是一元高斯分佈的在向量形式上的推廣,其中向量 的均值爲 ,協方差矩陣爲 ,概率密度函數表示爲
例如二元高斯多元分佈可以如圖所示
.
對於一對隨機變量 和 ,它們的協方差矩陣寫作
對於多個變量的問題,用協方差矩陣 來表示各個變量之間的相關性,有
對角多元高斯分佈
特殊地,當 N 個隨機變量 爲各自獨立的高斯隨機變量時,協方差矩陣爲對角陣,即
對角高斯策略 Diagonal Gaussian Policies
由於標準差的公式 可知 始終大於等於 0 ,對標準差取 log
對數,可以將標準差映射到 ,這樣更有利於神經網絡的訓練。
-
採樣:假設已知動作(Action) 的均值 和標準差 ,引入服從 分佈的噪聲 ,下一步的動作採樣表示爲
其中 表示兩個向量之間的內積。 -
似然數:當均值爲 ,標準差爲 的 維的動作 的似然數表示爲
二、代碼實現
要求
- 輸入: 樣本
x
,對角高斯分佈的均值和標準差 - 輸出:樣本
x
的似然數
import tensorflow as tf
import numpy as np
EPS = 1e-8
根據上一節,似然數公式,理解公式後就很容易寫出代碼
# my solution
def my_gaussian_likelihood(x, mu, log_std):
"""
Args:
x: Tensor with shape [batch, dim]
mu: Tensor with shape [batch, dim]
log_std: Tensor with shape [batch, dim] or [dim]
Returns:
Tensor with shape [batch]
"""
#######################
# #
# YOUR CODE HERE #
# #
#######################
std = tf.exp(log_std)
ans = ((x - mu) / std)**2 + 2 * log_std + np.log(2 * np.pi)
ans = -0.5 * ans
# https://www.tensorflow.org/api_docs/python/tf/math/reduce_sum
sum_ans = tf.reduce_sum(ans, axis=1)
return sum_ans
# standard solution
# 代碼來自 spinup/exercises/problem_set_1_solutions/exercise1_2_soln.py
def ans_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)
if __name__ == '__main__':
"""
Run this file to verify your solution.
"""
sess = tf.Session()
dim = 10
x = tf.placeholder(tf.float32, shape=(None, dim))
mu = tf.placeholder(tf.float32, shape=(None, dim))
log_std = tf.placeholder(tf.float32, shape=(dim,))
your_gaussian_likelihood = my_gaussian_likelihood(x, mu, log_std)
true_gaussian_likelihood = ans_gaussian_likelihood(x, mu, log_std)
batch_size = 32
feed_dict = {x: np.random.rand(batch_size, dim),
mu: np.random.rand(batch_size, dim),
log_std: np.random.rand(dim)}
your_result, true_result = sess.run([your_gaussian_likelihood, true_gaussian_likelihood],
feed_dict=feed_dict)
correct = np.allclose(your_result, true_result)
print("Your answer is", correct)
Your answer is True