Эта статья взята из: [блог InTheWorld] (Добро пожаловать, чтобы оставить сообщение и обменяться)
Метод градиента политики — очень важный метод обучения с подкреплением. В отличие от оптимальных алгоритмов, основанных на ценности, алгоритм градиента политики больше фокусируется на долгосрочной отдаче алгоритма. Градиент политики находит оптимальную политику в соответствии с направлением градиента целевой функции. В алгоритме градиента политики обучение не выполняется до конца всего раунда, поэтому алгоритм градиента политики лучше понимает глобальный процесс. Дэвид Сильвер из DeepMind прокомментировал методы, основанные на политике, в своей лекции о глубоком обучении:
Преимущества метода обучения с подкреплением на основе политик:
- хорошая сходимость
– Эффективен в многомерных и непрерывных задачах
- Может изучать случайные стратегии
Его недостатки:
– Легко попасть в локальный оптимум
– Оценка стратегии относительно неэффективна
основная теория
Теоретически градиенты политики на самом деле более простой способ понять, в конце концов, мы все слишком хорошо знакомы с градиентным спуском. Ключом к пониманию градиентов политики является понимание целевой функции. Как упоминалось ранее, цель обучения с подкреплением состоит в том, чтобы найти политический процесс, который максимизирует ожидаемую отдачу от этого процесса. Наша целевая функция:
Дж ( θ ) знак равно ∫ Икс ∼ п θ ( Икс ) п θ ( Икс ) р ( Икс ) г Икс J(\theta) = \int_{x \sim p_{_\theta}(x)}^{} p_{_\theta}(x)\,r(x) \,dx J(θ)=∫x ∼pθ(x)pθ(x)r(x)dxв Икс xx — поведение (может быть вектором), п θ ( Икс ) p_{_\theta}(x) pθ(x) — вероятность выбора действия. Дж ( θ ) J(\theta)J(θ) — ожидаемая доходность за весь раунд. С точки зрения алгоритма градиента политики, цель алгоритма состоит в том, чтобы максимизировать ожидаемое значение доходности. Процесс нахождения максимума фактически достигается вычислением градиента.
Производная функция целевой функции выглядит следующим образом:
∇ θ Дж ( θ ) знак равно ∫ Икс ∼ п θ ( Икс ) ∇ θ п θ ( Икс ) р ( Икс ) г Икс \nabla_{\theta} J(\theta) = \int_{x \sim p_{_\theta}(x)}^{} \nabla_{_\theta} p_{_\theta}(x)\,r (x) \,dx ∇θJ(θ)=∫x∼pθ(x)∇θpθ(x)r(x)dx знак равно ∫ Икс ∼ п θ ( Икс ) п θ ( Икс ) ∇ θ п θ ( Икс ) п θ ( Икс ) р ( Икс ) г Икс = \int_{x \sim p_{_\theta}(x)}^{} p_{_\theta}(x)\,\frac{\nabla_{_\theta} p_{_\theta}(x) }{p_{_\theta}(x)}\,r(x) \,dx =∫x∼pθ(x)pθ(x)pθ(x)∇θpθ (х)r(х)dx знак равно ∫ Икс ∼ п θ ( Икс ) п θ ( Икс ) ∇ θ л о г п θ ( Икс ) р ( Икс ) г Икс = \int_{x \sim p_{_\theta}(x)}^{} p_{_\theta}(x)\,\nabla_{_\theta}log\,{p_{_\theta}(x )}\,r(x) \,dx =∫x∼pθ(x)pθ(x)∇θlogpθ(x)r(x)dx знак равно Е Икс ∼ п θ ( Икс ) [ ∇ θ л о г п θ ( Икс ) р ( Икс ) ] = E_{x \sim p_{_\theta}(x)}^{} [\nabla_{_\theta}log\,{p_{_\theta}(x)}\,r(x)] =Ex ∼pθ(x)[∇θlogpθ(x)r(x)]При выводе приведенной выше формулы используется непрерывная функция, фактически она в основном применима в дискретном случае. В приведенном выше разделе логарифмической вероятности можно продолжить анализ следующим образом:
∇ θ л о г п θ ( Икс ) знак равно ∑ т знак равно 0 Т ∇ θ л о г п θ ( а т ∣ с т ) \nabla_{_\theta} log\,{p_{_\theta}(x)} = \sum_{t=0}^{T} \nabla_{_\theta} log\,p _{_\theta} (a_{t}|s_{t}) ∇θlogpθ(x)=t=0∑T∇θlogpθ(при∣st)Таким образом, формула для окончательного градиента стоимости полиса выглядит следующим образом:
∇ θ Дж ( θ ) знак равно ∑ я знак равно 1 Н [ ∑ т знак равно 0 Т ∇ θ л о г п θ ( а я , т ∣ с я , т ) ( ∑ т знак равно 0 Т р ( с я , т , а я , т ) ) ] \nabla_{\theta} J(\theta) = \sum_{i=1}^{N}[ \sum_{t=0}^{T} \nabla_{_\theta} log\,p _{_\ тета}(a_{i,t}|s_{i,t}) \ (\sum_{t=0}^{T}r(s_{i,t}, a_{i,t}))] ∇θ J(θ)=i=1∑N[t=0∑T∇θlogpθ(ai,t∣si,t) (t=0∑Trr(si,t ,ай,т)))]Эта формула на самом деле проблематична. ∑ т знак равно 0 Т р ( с я , т , а я , т ) \sum_{t^{}=0}^{T}r(s_{i,t}, a_{i,t})∑t=0Trr(si,t,ai,t)Эта часть in Anytime будет умножаться на формулу градиента. Однако действие определенного шага должно влиять только на последующий процесс, поэтому приведенную выше формулу можно изменить в следующем виде:
∇ θ Дж ( θ ) знак равно ∑ я знак равно 1 Н [ ∑ т знак равно 0 Т ∇ θ л о г п θ ( а я , т ∣ с я , т ) ( ∑ т ‘ знак равно т Т р ( с я , т ‘ , а я , т ‘ ) ) ] \nabla_{\theta} J(\theta) = \sum_{i=1}^{N}[ \sum_{t=0}^{T} \nabla_{_\theta} log\,p _{_\ тета}(a_{i,t}|s_{i,t}) \ (\sum_{t^{'}=t}^{T}r(s_{i,t^{'}}, a_{i ,t^{'}}))] ∇θJ(θ)=i=1∑N[t=0∑T∇θlogpθ(ai,t∣si,t) ( t'=t∑Trr(si,t',ai,t'))]С более детальной точки зрения, приведенная выше формула все еще проблематична. Суммирование многих частей вознаграждения может привести к увеличению вознаграждения за все действия. Это ослабляет истинное значение вознаграждения. Следовательно, в технической реализации часть вознаграждения по-прежнему будет подвергаться обработке средней смены или даже обработке стандартизации.
Реализация TensorFlow
Хотя градиент политики редко используется сам по себе, его полезно понимать в сочетании с реализацией кода. Я все еще смотрю на реализацию Чжоу Мофаня, это чтение кода.
import numpy as np
import tensorflow as tf
np.random.seed(1)
tf.set_random_seed(1)
class PolicyGradient:
def __init__(self,
n_actions,
n_features,
learning_rate=0.01,
reward_decay=0.95,
output_graph=False):
self.n_actions = n_actions
self.n_features = n_features
self.lr = learning_rate
self.gamma = reward_decay
self.ep_obs, self.ep_as, self.ep_rs = [], [], []
self._build_net()
self.sess = tf.Session()
if output_graph:
tf.summary.FileWriter("logs/", self.sess.graph)
self.sess.run(tf.global_variables_initializer())
def _build_net(self):
with tf.name_scope('inputs'):
self.tf_obs = tf.placeholder(tf.float32, [None, self.n_features], name="observations")
self.tf_acts = tf.placeholder(tf.int32, [None, ], name="actions_num")
self.tf_vt = tf.placeholder(tf.float32, [None, ], name="actions_value")
layer = tf.layers.dense(
inputs=self.tf_obs,
units=10,
activation=tf.nn.tanh,
kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
bias_initializer=tf.constant_initializer(0.1),
name='fc1'
)
all_act = tf.layers.dense(
inputs=layer,
units=self.n_actions,
activation=None,
kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.3),
bias_initializer=tf.constant_initializer(0.1),
name='fc2'
)
self.all_act_prob = tf.nn.softmax(all_act, name='act_prob')
with tf.name_scope('loss'):
neg_log_prob = tf.reduce_sum(-tf.log(self.all_act_prob) * tf.one_hot(self.tf_acts, self.n_actions), axis=1)
loss = tf.reduce_sum(neg_log_prob * self.tf_vt)
with tf.name_scope('train'):
self.train_op = tf.train.AdamOptimizer(self.lr).minimize(loss)
def choose_action(self, observation):
prob_weights = self.sess.run(self.all_act_prob, feed_dict={self.tf_obs: observation[np.newaxis, :]})
action = np.random.choice(range(prob_weights.shape[1]), p=prob_weights.ravel())
return action
def store_transition(self, s, a, r):
self.ep_obs.append(s)
self.ep_as.append(a)
self.ep_rs.append(r)
def learn(self):
discounted_ep_rs_norm = self._discount_and_norm_rewards()
self.sess.run(self.train_op, feed_dict={
self.tf_obs: np.vstack(self.ep_obs),
self.tf_acts: np.array(self.ep_as),
self.tf_vt: discounted_ep_rs_norm,
})
self.ep_obs, self.ep_as, self.ep_rs = [], [], []
return discounted_ep_rs_norm
def _discount_and_norm_rewards(self):
discounted_ep_rs = np.zeros_like(self.ep_rs)
running_add = 0
for t in reversed(range(0, len(self.ep_rs))):
running_add = running_add * self.gamma + self.ep_rs[t]
discounted_ep_rs[t] = running_add
discounted_ep_rs -= np.mean(discounted_ep_rs)
discounted_ep_rs /= np.std(discounted_ep_rs)
return discounted_ep_rs
Сначала посмотрите на функцию _discount_and_norm_rewards, которая содержит логику обработки данных, означает обработку смены и нормализацию. А данные вознаграждения рассчитываются в обратном порядке, то есть вычисляется возвращаемое значение от t до T.
Построенная сеть TensorFlow также относительно проста, всего с двумя полносвязными слоями. Используйте softmax для расчета вероятности каждого действия, затем выберите значение вероятности в соответствии с фактическим поведением, затем возьмите логарифм и, наконец, умножьте данные в части вознаграждения. Градиент в формуле градиента фактически отражается в процессе обучения нейронной сети.
После этого буду изучать DDPG и Actor Critic в сочетании с Baseline (здесь сначала будет вырыта яма).