Градиенты политики в Keras

Я пытался построить модель, используя "глубокое обучение", где у меня большое количество действий (2908). После некоторого ограниченного успеха с использованием стандартного DQN: (https://www.cs.toronto.edu/~vmnih/docs/dqn.pdf) я решил провести дополнительное исследование, так как считал, что пространство действия слишком велико для выполнения эффективное исследование.

Затем я обнаружил этот документ: https://arxiv.org/pdf/1512.07679.pdf, где они используют модель актер-критик и градиенты политики, что затем привело меня к: https://arxiv.org/pdf/1602.01783.pdf где они используют градиенты политики, чтобы получить гораздо лучшие результаты, чем DQN в целом.

Я нашел несколько сайтов, где они внедрили градиенты политики в Керасе, https://yanpanlau.github.io/2016/10/11/Torcs-Keras.html и https://oshearesearch.com/index.php/2016/06/14/kerlym-a-deep -rengcement-learning-toolbox-in-keras/ однако я запутался, как они реализованы. В первом (и когда я читаю статьи) кажется, что вместо предоставления входной и выходной пары для сети акторов, вы предоставляете градиенты для всех весов, а затем используете сеть для ее обновления, тогда как во втором они просто рассчитывают пару ввода-вывода.

Я только что запутался? Должен ли я просто тренировать сеть, предоставляя пару вход-выход и использовать стандартную "подгонку", или мне нужно сделать что-то особенное? Если это последнее, как мне сделать это с бэкэндом Theano? (в приведенных выше примерах используется TensorFlow).

Ответы

Ответ 1

TL; DR

  1. Узнайте, как реализовать пользовательские функции потерь и градиенты, используя Keras.backend. Он понадобится вам для более продвинутых алгоритмов, и на самом деле это будет намного проще, если вы освоите его.
  2. Одним из примеров использования keras.backend в CartPole может быть https://gist.github.com/kkweon/c8d1caabaf7b43317bc8825c226045d2 (хотя его бэкэнд использует Tensorflow, но он должен быть очень похожим, если не тем же)

проблема

При игре,

агенту нужна политика, которая в основном является функцией, которая отображает состояние в политику, которая является вероятностью для каждого действия. Таким образом, агент выберет действие в соответствии со своей политикой.

т.е. политика = f (состояние)

Когда тренируешься,

Градиент политики не имеет функции потерь. Вместо этого он пытается максимизировать ожидаемый возврат вознаграждений. И нам нужно вычислить градиенты log (action_prob) * преимущество

  1. Преимущество - это функция вознаграждений.
    • преимущество = f (награды)
  2. action_prob - это функция состояний и action_taken. Например, нам нужно знать, какое действие мы предприняли, чтобы мы могли обновить параметры, чтобы увеличить/уменьшить вероятность того, что мы предприняли.
    • action_prob = sum (policy * action_onehot) = f (состояния, action_taken)

Я предполагаю что-то вроде этого

  • полис = [0,1, 0,9]
  • action_onehot = action_taken = [0, 1]
  • тогда action_prob = sum (policy * action_onehot) = 0,9

Резюме

Нам нужны две функции

  • функция обновления: f (состояние, action_taken, награда)
  • выберите функцию действия: f (состояние)

Вы уже знаете, что это нелегко реализовать, как типичные задачи классификации, где вы можете просто model.compile(...) → model.fit(X, y)

Тем не мение,

  • Чтобы полностью использовать Keras, вам должно быть удобно определять пользовательские функции потерь и градиенты. Это в основном тот же подход, что и автор предыдущего.

  • Вы должны прочитать больше документации по функциональному API Keras и keras.backend

Кроме того, существует много видов градиентов политики.

  • Первый называется DDPG, который на самом деле сильно отличается от обычных политических градиентов
  • Последнее, что я вижу, - это традиционный градиент политики REINFORCE (pg.py), основанный на примере градиента политики Kapathy. Но это очень просто, например, он предполагает только одно действие. Вот почему это можно было бы как-то реализовать, используя взамен model.fit(...).

Рекомендации

Ответ 2

Кажущиеся противоречивыми реализации, с которыми вы столкнулись, вероятно, являются допустимыми реализациями. Разница заключается в том, что некоторые реализации вручную применяют градиенты политики, тогда как другие используют рамки авто-дифференциации.

  • В типичном алгоритме градиента политики, таком как REINFORCE, вы действительно рассчитываете градиенты сети политик по вознаграждениям, а затем обновляете веса, используя этот градиент. Это потребует от вас выполнения шагов, описанных Мо К.
  • Однако, если вы работаете с Keras, который использует платформу автодифференцирования (Theano/tenorflow), наиболее удобный подход - предоставить функцию потерь вместо градиента. Цитировать (1):

    "В рамках Autodiff обычно не предоставляют явных оценок градиента в форме, например, (2), но вместо этого следует предоставлять функцию потерь".

  • Некоторые реализации autodiff переопределяют алгоритм градиентов политики таким образом, чтобы он соответствовал контролируемой задаче обучения. Проще говоря, идея состоит в том, чтобы использовать "истинное действие" в качестве "поддельной метки" и построить функцию потерь таким образом, чтобы ее градиент был градиентом политики. Для дискретных пространств действий это делается путем умножения потери softmax-кроссцентропии на будущие вознаграждения.

    Как говорит Карпати (2):

    Градиенты политики в точности совпадают с контролируемым обучением, с двумя небольшими отличиями: 1) у нас нет правильных меток y, поэтому в качестве "поддельной метки" мы заменяем действие, которое мы получили для выборки из политики, когда она увидела x и 2) мы модулируем потери для каждого примера мультипликативно основаны на конечном результате, так как мы хотим увеличить вероятность регистрации действий, которые сработали, и уменьшить ее для действий, которые не сработали.

Слайды из Стэнфорда (3) дают некоторое дополнительное объяснение реализаций градиента политик с помощью авто-разностных платформ, а также псевдокода:

# Given:
# actions - (N*T) x Da tensor of actions
# states - (N*T) x Ds tensor of states
# rew_to_go – (N*T) x 1 tensor of estimated reward to go
# Build the graph:
logits = policy.predictions(states) # This should return (N*T) x Da tensor of action logits 
negative_likelihoods = tf.nn.softmax_cross_entropy_with_logits(labels=actions, logits=logits)
weighted_negative_likelihoods = tf.multiply(negative_likelihoods, rew_to_go)
loss = tf.reduce_mean(weighted_negative_likelihoods)
gradients = loss.gradients(loss, variables)

Рекомендации

  1. https://aleksispi.github.io/assets/pg_autodiff.pdf
  2. http://karpathy.github.io/2016/05/31/rl/
  3. https://web.stanford.edu/class/cs20si/lectures/CS20_intro_to_RL.pdf