Вступ до Deep Q-Learning: давайте грати в Doom

Ця стаття є частиною курсу глибокого підкріплення з Tensorflow? ️. Перевірте програму навчання тут.

Минулого разу ми дізналися про Q-Learning: алгоритм, який створює Q-таблицю, яку агент використовує, щоб знайти найкращі дії для певного стану.

Але, як ми побачимо, створення та оновлення таблиці Q може стати неефективним у великих просторах державного простору.

Ця стаття є третьою частиною серії публікацій у блозі про глибоке підкріплення навчання. Щоб отримати більше інформації та більше ресурсів, перегляньте програму курсу.

Сьогодні ми створимо нейронну мережу Deep Q. Замість використання Q-таблиці ми реалізуємо нейронну мережу, яка приймає стан і апроксимує значення Q для кожної дії на основі цього стану.

Завдяки цій моделі ми зможемо створити агента, який навчиться грати в Doom!

У цій статті ви дізнаєтесь:

  • Що таке глибоке Q-навчання (DQL)?
  • Які найкращі стратегії використовувати з DQL?
  • Як вирішити проблему часового обмеження
  • Чому ми використовуємо перегляд досвіду
  • Яка математика стоїть за DQL
  • Як реалізувати це в Tensorflow

Додавання "глибокого" до Q-Learning

В останній статті ми створили агента, який грає Frozen Lake завдяки алгоритму Q-навчання.

Ми реалізували функцію Q-learning для створення та оновлення Q-таблиці. Подумайте про це як про шпаргалку, яка допоможе нам знайти максимально очікувану майбутню винагороду за дію, враховуючи поточний стан. Це була хороша стратегія - однак, вона не є масштабованою.

Уявіть, що ми будемо робити сьогодні. Ми створимо агента, який навчиться грати в Doom. Дум - це велике середовище з гігантським державним простором (мільйони різних штатів). Створення та оновлення таблиці Q для цього середовища було б зовсім не ефективно.

Найкраща ідея в цьому випадку - створити нейронну мережу, яка буде апроксимувати, за певного стану, різні значення Q для кожної дії.

Як працює Deep Q-Learning?

Це буде архітектура нашого Deep Q Learning:

Це може здатися складним, але я поясню архітектуру поетапно.

Наша нейромережа Deep Q приймає в якості входу стек з чотирьох кадрів. Вони проходять через його мережу і виводять вектор Q-значень для кожної дії, можливої ​​в даному стані. Нам потрібно взяти найбільше Q-значення цього вектора, щоб знайти найкращі дії.

На початку агент робить справді погано. Але з часом він починає асоціювати фрейми (стани) з найкращими діями.

Частина попередньої обробки

Попередня обробка є важливим кроком. Ми хочемо зменшити складність наших штатів, щоб скоротити час обчислень, необхідний для навчання.

По-перше, ми можемо визначити градації сірого в кожному з наших штатів. Колір не додає важливої ​​інформації (у нашому випадку нам просто потрібно знайти ворога і вбити його, а нам не потрібен колір, щоб знайти його). Це важлива економія, оскільки ми зменшуємо три кольорові канали (RGB) до 1 (відтінки сірого).

Потім обрізаємо рамку. У нашому прикладі бачити дах не дуже корисно.

Потім ми зменшуємо розмір кадру і складаємо чотири підкадри разом.

Проблема часового обмеження

Артур Джуліані чудово пояснює цю тему у своїй статті. Він має розумну ідею: використовувати нейронні мережі LSTM для вирішення проблеми.

Однак я вважаю, що для початківців краще використовувати складені рамки.

Перше запитання, яке ви можете задати, - чому ми складаємо кадри разом?

Ми складаємо кадри разом, оскільки це допомагає нам вирішити проблему часового обмеження.

Візьмемо приклад у грі Понг. Коли ви бачите цей кадр:

Чи можете ви сказати мені, куди прямує м'яч?

Ні, тому що одного кадру недостатньо, щоб мати відчуття руху!

Але що, якщо я додаю ще три кадри? Тут ви бачите, що м’яч рухається праворуч.

Це те саме для нашого агента Doom. Якщо ми даємо йому лише один кадр за раз, це не уявляє руху. І як він може прийняти правильне рішення, якщо не може визначити, де і як швидко рухаються предмети?

Використання мереж згортки

Кадри обробляються трьома згорнутими шарами. Ці шари дозволяють використовувати просторові відносини на зображеннях. Але також, оскільки кадри складені разом, ви можете використовувати деякі просторові властивості в цих кадрах.

Якщо ви не знайомі із згорткою, прочитайте цю чудову інтуїтивно зрозумілу статтю Адама Гейтгея.

Кожен рівень згортки буде використовувати ELU як функцію активації. ELU було доведено як хороша функція активації для згорткових шарів.

Ми використовуємо один повністю зв’язаний шар з функцією активації ELU та один вихідний рівень (повністю зв’язаний шар з лінійною функцією активації), який виробляє оцінку Q-значення для кожної дії.

Відтворення досвіду: ефективніше використання спостережуваного досвіду

Повторний досвід допоможе нам вирішити дві речі:

  • Не забувайте про попередній досвід.
  • Reduce correlations between experiences.

I will explain these two concepts.

This part and the illustrations were inspired by the great explanation in the Deep Q Learning chapter in the Deep Learning Foundations Nanodegree by Udacity.

Avoid forgetting previous experiences

We have a big problem: the variability of the weights, because there is high correlation between actions and states.

Remember in the first article (Introduction to Reinforcement Learning), we spoke about the Reinforcement Learning process:

At each time step, we receive a tuple (state, action, reward, new_state). We learn from it (we feed the tuple in our neural network), and then throw this experience.

Our problem is that we give sequential samples from interactions with the environment to our neural network. And it tends to forget the previous experiences as it overwrites with new experiences.

For instance, if we are in the first level and then the second (which is totally different), our agent can forget how to behave in the first level.

As a consequence, it can be more efficient to make use of previous experience, by learning with it multiple times.

Our solution: create a “replay buffer.” This stores experience tuples while interacting with the environment, and then we sample a small batch of tuple to feed our neural network.

Think of the replay buffer as a folder where every sheet is an experience tuple. You feed it by interacting with the environment. And then you take some random sheet to feed the neural network

This prevents the network from only learning about what it has immediately done.

Reducing correlation between experiences

We have another problem — we know that every action affects the next state. This outputs a sequence of experience tuples which can be highly correlated.

If we train the network in sequential order, we risk our agent being influenced by the effect of this correlation.

By sampling from the replay buffer at random, we can break this correlation. This prevents action values from oscillating or diverging catastrophically.

It will be easier to understand that with an example. Let’s say we play a first-person shooter, where a monster can appear on the left or on the right. The goal of our agent is to shoot the monster. It has two guns and two actions: shoot left or shoot right.

We learn with ordered experience. Say we know that if we shoot a monster, the probability that the next monster comes from the same direction is 70%. In our case, this is the correlation between our experiences tuples.

Let’s begin the training. Our agent sees the monster on the right, and shoots it using the right gun. This is correct!

Then the next monster also comes from the right (with 70% probability), and the agent will shoot with the right gun. Again, this is good!

And so on and on…

The problem is, this approach increases the value of using the right gun through the entire state space.

And if our agent doesn’t see a lot of left examples (since only 30% will probably come from the left), our agent will only finish by choosing right regardless of where the monster comes from. This is not rational at all.

We have two parallel strategies to handle this problem.

First, we must stop learning while interacting with the environment. We should try different things and play a little randomly to explore the state space. We can save these experiences in the replay buffer.

Then, we can recall these experiences and learn from them. After that, go back to play with updated value function.

As a consequence, we will have a better set of examples. We will be able to generalize patterns from across these examples, recalling them in whatever order.

This helps avoid being fixated on one region of the state space. This prevents reinforcing the same action over and over.

This approach can be seen as a form of Supervised Learning.

We’ll see in future articles that we can also use “prioritized experience replay.” This lets us present rare or “important” tuples to the neural network more frequently.

Our Deep Q-Learning algorithm

First a little bit of mathematics:

Remember that we update our Q value for a given state and action using the Bellman equation:

In our case, we want to update our neural nets weights to reduce the error.

The error (or TD error) is calculated by taking the difference between our Q_target (maximum possible value from the next state) and Q_value (our current prediction of the Q-value)

Initialize Doom Environment EInitialize replay Memory M with capacity N (= finite capacity)Initialize the DQN weights wfor episode in max_episode: s = Environment state for steps in max_steps: Choose action a from state s using epsilon greedy. Take action a, get r (reward) and s' (next state) Store experience tuple  in M s = s' (state = new_state) Get random minibatch of exp tuples from M Set Q_target = reward(s,a) + γmaxQ(s') Update w = α(Q_target - Q_value) * ∇w Q_value

There are two processes that are happening in this algorithm:

  • We sample the environment where we perform actions and store the observed experiences tuples in a replay memory.
  • Select the small batch of tuple random and learn from it using a gradient descent update step.

Давайте впровадимо нашу нейромережу Deep Q

Ми зробили відео, де впроваджуємо агент Deep Q-learning з Tensorflow, який вчиться грати в Atari Space Invaders? ️ ?.

Тепер, коли ми знаємо, як це працює, ми поступово впровадимо нашу нейронну мережу Deep Q. Кожен крок і кожна частина коду пояснюються безпосередньо в блокноті Юпітера, зв’язаному нижче.

Ви можете отримати доступ до нього у репозиторії навчального курсу глибокого підкріплення.

Це все! Ви щойно створили агента, який вчиться грати в Doom. Чудово!

Не забудьте реалізувати кожну частину коду самостійно. Насправді важливо спробувати змінити код, який я вам дав. Спробуйте додати епохи, змінити архітектуру, додати фіксовані значення Q, змінити швидкість навчання, використовувати складніше середовище (наприклад, Збір здоров’я) ... тощо. Весело!

У наступній статті я обговорюватиму останні вдосконалення глибокого Q-навчання:

  • Виправлені значення Q
  • Prioritized Experience Replay
  • Double DQN
  • Dueling Networks

But next time we’ll work on Policy Gradients by training an agent that plays Doom, and we’ll try to survive in an hostile environment by collecting health.

If you liked my article, please click the ? below as many time as you liked the article so other people will see this here on Medium. And don’t forget to follow me!

If you have any thoughts, comments, questions, feel free to comment below or send me an email: [email protected], or tweet me @ThomasSimonini.

Keep learning, stay awesome!

Deep Reinforcement Learning Course with Tensorflow ?️

? Syllabus

? Video version

Part 1: An introduction to Reinforcement Learning

Part 2: Diving deeper into Reinforcement Learning with Q-Learning

Part 3: An introduction to Deep Q-Learning: let’s play Doom

Part 3+: Improvements in Deep Q Learning: Dueling Double DQN, Prioritized Experience Replay, and fixed Q-targets

Part 4: An introduction to Policy Gradients with Doom and Cartpole

Part 5: An intro to Advantage Actor Critic methods: let’s play Sonic the Hedgehog!

Part 6: Proximal Policy Optimization (PPO) with Sonic the Hedgehog 2 and 3

Part 7: Curiosity-Driven Learning made easy Part I