DQN с воспроизведением опыта

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

Timothée Carayol

Principal Machine Learning Engineer, Komment

Введение в воспроизведение опыта

 

  • Базовый агент DQN учится только на последнем опыте
    • Последовательные обновления сильно коррелированы
    • Агент «забывает» предыдущий опыт
  • Решение: воспроизведение опыта
    • Опыт сохраняется в буфере
    • На каждом шаге агент учится на случайной выборке из прошлого опыта

 

Аэрофотоснимок живой изгороди-лабиринта

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

Двусторонняя очередь

 

from collections import deque

# Instantiate with limited capacity buffer = deque([1,2,3,4], maxlen=7)
# Extend to the right side buffer.extend([5,6,7,8])
  • При превышении ёмкости старые элементы удаляются

Дек ёмкостью семь элементов, содержащий четыре элемента с метками от одного до четырёх.

Дек ёмкостью семь элементов с четырьмя элементами от одного до четырёх. Справа видны ещё четыре элемента с метками от пяти до восьми.

Дек ёмкостью семь элементов, содержащий семь элементов с метками от одного до семи. Справа виден ещё один элемент с меткой 8.

Дек ёмкостью семь элементов, содержащий семь элементов с метками от двух до восьми. Слева виден элемент с меткой 1.

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

Реализация буфера воспроизведения

import random

class ReplayBuffer:
def __init__(self, capacity):
self.memory = deque([], maxlen=capacity)
def push(self, state, action, reward, next_state, done):
experience_tuple = (state, action, reward, next_state, done)
self.memory.append(experience_tuple)
def __len__(self): return len(self.memory)
...
  • Буфер воспроизведения: deque с ограниченной ёмкостью
  • .push():
    • Опыт в виде кортежа перехода
    • Добавление опыта в буфер
    • При заполнении: самый старый опыт удаляется
Глубокое обучение с подкреплением на Python

Реализация буфера воспроизведения

...
def sample(self, batch_size):

batch = random.sample(self.memory, batch_size)
states, actions, rewards, next_states, dones = ( zip(*batch))
states_tensor = torch.tensor( states, dtype=torch.float32) ... # repeat identically for # rewards, next_states, dones
actions_tensor = torch.tensor( actions, dtype=torch.long).unsqueeze(1)
return states_tensor, actions_tensor, rewards_tensor, next_states_tensor, dones_tensor

 

  • Случайная выборка из прошлого опыта
  • batch: из списка кортежей переходов...
  • ...в кортеж списков...
  • ...в кортеж тензоров PyTorch
Глубокое обучение с подкреплением на Python

Интеграция воспроизведения опыта в DQN

  1. До цикла обучения: replay_buffer = ReplayBuffer(10000)

  2. В цикле обучения, после выбора действия:

replay_buffer.push((state, action, 
                    reward, next_state, done))

if len(replay_buffer) >= batch_size:
states, actions, rewards, next_states, dones = ( replay_buffer.sample(batch_size))
q_values = ( q_network(states).gather(1, actions).squeeze(1))
next_states_q_values = q_network(next_states).amax(1)
target_q_values = ( rewards + gamma * next_states_q_values * (1-dones))
loss = nn.MSELoss()(target_q_values, q_values)
  • Инициализация буфера воспроизведения
  • Добавление последнего перехода в буфер

Если длина буфера $\geq$ batch_size:

  • Случайная выборка из буфера и вычисление функции потерь
  • Вычисление потерь концептуально не изменяется
  • Среднеквадратичная ошибка Беллмана на пакете из буфера воспроизведения
    • Обучение становится более стабильным и эффективным
Глубокое обучение с подкреплением на Python

Давайте потренируемся!

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

Preparing Video For Download...