Обучение с подкреплением 11 - Tensorflow 2.0 Реализация алгоритма REINFORCE

обучение с подкреплением

в предыдущей статьеОбучение с подкреплением - вывод формулы градиента политикиМы получили градиент политики:

θJ(θ)1mi=1mR(тi)  t=0T1θ  log  число Пиθ(atisti)\nabla_\theta J(\theta) \approx \frac{1}{m}\sum_{i=1}^mR(\tau_i)\;\sum_{t=0}^{T-1}\nabla_\theta\;log\;\pi_\theta(a_t^i|s_t^i)

один из нихR(тi)R(\tau_i)представляет собой сумму всех вознаграждений за i-ю траекторию.

Для этой формулы мы получаем его на основе метода выборки MC. Для траекторий, выбранных с помощью MC, систематическая ошибка отсутствует. Однако из-за выборки вознаграждение, получаемое каждой траекторией, очень нестабильно, что приводит к относительно высокой дисперсии. Есть два способа уменьшить дисперсию: 1. Использовать временную причинность. 2. Введите базовый уровень

1. Уменьшите дисперсию

1. Используйте временную причинность

Использование временной причинности может уменьшить количество ненужных терминов.

θEт[R]=Eт[(t=0T1rt)(t=0T1θ  log  число Пиθ(atst))]\nabla_\theta E_\tau[R] = E_\tau \left[\left(\sum_{t=0}^{T-1}r_t\right) \left( \sum_{t=0}^{T-1}\nabla_\theta\;log\;\pi_\theta(a_t|s_t)\right) \right]

Награда за точку в траекторииrt'r_{t'}Это может быть выражено как:

θEт[rt']=Eт[rt't=0t'θ  log  число Пиθ(atst)]\nabla_\theta E_\tau[r_{t'}] = E_\tau\left[r_{t'}\sum_{t=0}^{t'}\nabla_\theta\;log\;\pi_\theta(a_t|s_t)\right]

Затем сложите производные всех точек траектории:

θJ(θ)=θEт~число Пиθ[R]=Eт[t'=0T1rt't=0t'θ  log  число Пиθ(atst)]=Eт[t=0T1θ  log  число Пиθ(atst)t'=tT1rt']=Eт[t=0T1Gtθ  log  число Пиθ(atst)]\begin{align} \nabla_\theta J(\theta) = \nabla_\theta E_{\tau~\pi_\theta}[R] & = E_\tau \left[\sum_{t'=0}^{ T-1}r_{t'} \sum_{t=0}^{t'}\nabla_\theta\;log\;\pi_\theta(a_t|s_t)\right] \\ & = E_\tau\ слева[\sum_{t=0}^{T-1}\nabla_\theta\;log\;\pi_\theta(a_t|s_t) \sum_{\color{red}t'=t}^{T- 1}r_{t'} \right] \\ & = E_\tau \left[\sum_{t=0}^{T-1}G_t\cdot \nabla_\theta\;log\;\pi_\theta( a_t|s_t) \right] \end{aligned}

вGt=t'=tT1rt'G_t = \sum_{t'=t}^{T-1}r_{t'}Представляет собой сумму вознаграждений, полученных за траекторию после t шагов.

Если вышеприведенная формула сложна для понимания, мы можем понять ее так: все мы знаем, что текущий момент не может повлиять на то, что произошло в прошлом, это временная причинность. Аналогично, для траекториисейчасt't'временная стратегия не может повлиятьt't'Награды, заработанные до момента. так в самый разt't'Все награды после этого складываются, иt't'Награды, заработанные до момента, не имеют значения. Следовательно, Оценщик градиента политики может быть выражен следующим образом:

θE[R]1mi=1mt=0T1Gtθ  log  число Пиθ(atisti)\nabla_\theta E[R] \approx \frac{1}{m}\sum_{i=1}^m\sum_{t=0}^{T-1}G_t\cdot \nabla_\theta\;log\;\pi_\theta(a_t^i|s_t^i)

Из вышеперечисленных операций мы получаем очень классический алгоритм REINFORCE в Policy Gradient:

Williams (1992). Simple statistical gradient-following algorithms for connectionist reinforcement learning: introduces REINFORCE algorithm

aps8DH.png

2. Присоединяйтесь к базовой линии

Для выбранной траектории вознаграждениеGtG_tбудет иметь высокую дисперсию, мы можем позволитьGtG_tВычтите значение (Baseline), которое уменьшает дисперсию, и легко доказать, что добавление Baseline уменьшит дисперсию без изменения общего ожидаемого значения, что сделает процесс обучения более стабильным.

θEт~число Пиθ[R]=Eт[t=0T1(Gtb(st))θ  log  число Пиθ(atst)]\nabla_\theta E_{\tau~\pi_\theta}[R] = E_\tau \left[\sum_{t=0}^{T-1}{\color{red}(G_t-b(s_t) )}\cdot \nabla_\theta\;log\;\pi_\theta(a_t|s_t) \right]

Один из способов — использовать ожидание вознаграждения в качестве исходного уровня, т. е. позволитьGtG_tВычтите его среднее значение:

b(st)=E[rt+rt+1++rT1]b(s_t) = E[r_t+r_{t+1}+\ldots+r_{T-1}]

Для базовой линии параметр также можно использовать для подгонки, который выражается какbw(st)b_w(s_t), при оптимизации параметров во время оптимизацииwwиθ\theta.

2. Алгоритм УСИЛЕНИЯ

пример использования кодаCartPole-v1Дискретная среда, сначала давайте посмотрим на общий поток алгоритма.

1. Общий процесс

Во-первых, мы строим модель сети политик и инициализируем параметрыθ\theta, а затем используйте эту модель для выборки и сбора данных, а затем используйте собранные данные для обновления параметров сети.θ\theta, затем у нас есть новая сеть политик, а затем используем новую сеть политик для взаимодействия со средой для сбора новых данных, обновления сети политик и повторения, пока не будет обучена хорошая модель. Обратите внимание, что данные, собираемые каждый раз, могут быть использованы только один раз и должны быть удалены, поскольку каждое обновлениеθ\thetaПозже сеть политик изменится, поэтому данные, собранные старой сетью, нельзя будет использовать для отслеживания параметров новой сети.

aKwSbR.png

Конкретный процесс выглядит следующим образом: в процессе взаимодействия со средой мы сохраняем соответствующие данные каждого шага для расчетаGtG_tнаграда.

for episode in range(TRAIN_EPISODES):
    state = env.reset()
    episode_reward = 0
    for step in range(MAX_STEPS):  # in one episode
        if RENDER: env.render()
            action = agent.get_action(state)
            next_state, reward, done, _ = env.step(action)
            agent.store_transition(state, action, reward)
            state = next_state
            episode_reward += reward
            if done:break
                agent.learn()

2. Рассчитайте вознаграждение

    def _discount_and_norm_rewards(self):
        # discount episode rewards
        discounted_reward_buffer = np.zeros_like(self.reward_buffer)
        running_add = 0
        for t in reversed(range(0, len(self.reward_buffer))):
            running_add = running_add * self.gamma + self.reward_buffer[t]
            discounted_reward_buffer[t] = running_add

        # normalize episode rewards
        discounted_reward_buffer -= np.mean(discounted_reward_buffer)
        discounted_reward_buffer /= np.std(discounted_reward_buffer)
        return discounted_reward_buffer

Функция разделена на две части, одна часть вычисляет значение G, а другая часть нормализует значение G. рассчитано здесьdiscounted_reward_bufferЭто награда, которую можно получить за каждый шаг до конца эпизода, что является формулой в формулеGtG_t. Обратите внимание, что счет идет в обратном порядке от последнего состояния, а награда за каждый шаг добавляется в список. Затем нормализуйте рассчитанные данные списка вознаграждений, и эффект обучения будет лучше.

3. Обновление градиента

Мы знаем, что каждый раз, когда мы собираем данные для обновления параметров сетиθ\theta, то как обновляются параметры сети?

Мы можем думать об этом как о процессе классификации обучения с учителем, как показано на рисунке ниже, для входных данных среды в сеть политик конечный выход сети — это три действия: влево, вправо и огонь. Справа находится этикетка. Функция потерь представляет собой перекрестную энтропию между выходным действием и меткой.Целью минимизации является ее перекрестная энтропия, а затем с новыми параметрами сети увеличить вероятность того, какое действие произойдет, или уменьшить вероятность того, какое действие произойдет.

H=i=13y^ilog  yiMaximize:log  yi=logP("left"s)H = - \sum_{i=1}^{3}\hat{y}_i log\;y_i \\ Maximize: log\;y_i = logP("left"|s) \\
θθ+нlogP("left"s)\theta \leftarrow \theta + \eta\nabla logP("left"|s)

aKsob4.png

Каждый шаг данных, которые мы собираемstate, action, вы можете поставитьstateВ качестве обучающих данных положимactionВоспринимайте это как ярлык. Затем минимизируйте его кросс-энтропию, как показано в коде ниже. В алгоритме REINFORCE рассчитанная перекрестная энтропия умножается наGtG_tТо есть в кодеdiscounted_reward, то есть параметры обновляются в соответствии сGtG_tнастроить, еслиGtG_tотносительно высока, то вероятность возникновения соответствующего действия будет значительно увеличена.GtG_tЕсли это отрицательное число, то вероятность действия будет соответственно уменьшена, что является градиентным спуском с весом. Для этого процессаtensorlayerвстроенная функцияcross_entropy_reward_loss, вы можете напрямую реализовать описанный выше процесс, см. раздел комментариев к коду.

def learn(self): 
    discounted_reward = self._discount_and_norm_rewards()
    with tf.GradientTape() as tape:
        _logits = self.model(np.vstack(self.state_buffer))
        neg_log_prob = tf.nn.sparse_softmax_cross_entropy_with_logits(
            logits=_logits, labels=np.array(self.action_buffer))
        loss = tf.reduce_mean(neg_log_prob * discounted_reward)
        # loss = tl.rein.cross_entropy_reward_loss(
        #     logits=_logits, actions=np.array(self.action_buffer), rewards=discounted_reward)
    grad = tape.gradient(loss, self.model.trainable_weights)
    self.optimizer.apply_gradients(zip(grad, self.model.trainable_weights))

Для понимания этой части вы можете непосредственно увидетьВидео учителя Ли Хунъи, очень доходчиво объяснил. Полный код REINFORCE:Алгоритм УСИЛЕНИЯ, Я надеюсь, что смогу дать вам звезду по желанию, спасибо, мистер Кангуань. . .

3. Неадекватность REINFORCE

Градиенты политик открывают нам окно для решения проблем обучения с подкреплением, но приведенный выше алгоритм градиента политик Монте-Карло не идеален. Поскольку для получения данных используется выборка MC, нам нужно дождаться конца каждого эпизода, чтобы выполнить итерацию алгоритма.Поскольку MC относительно медленный, можем ли мы использовать TD? Конечно, это возможно, что и представляет собой алгоритм Актера-Критика, который мы представим в следующей статье.