Derin Q-Öğrenmeye giriş: haydi Doom oynayalım

Bu makale, Tensorflow® ile Derin Takviye Öğrenme Kursunun bir parçasıdır. Müfredatı buradan kontrol edin.

Geçen sefer, Q-Learning'i öğrendik: bir temsilcinin, belirli bir durumda gerçekleştirecek en iyi eylemi bulmak için kullandığı bir Q-tablosu üreten bir algoritma.

Ancak göreceğimiz gibi, bir Q-tablosunun üretilmesi ve güncellenmesi büyük durum uzay ortamlarında etkisiz hale gelebilir.

Bu makale, Derin Pekiştirmeli Öğrenme ile ilgili bir blog gönderisinin üçüncü bölümüdür. Daha fazla bilgi ve daha fazla kaynak için kursun müfredatına göz atın.

Bugün, bir Derin Q Sinir Ağı oluşturacağız. Bir Q tablosu kullanmak yerine, bir durumu alan ve o duruma bağlı olarak her eylem için Q değerlerini yaklaşık olarak belirleyen bir Sinir Ağı uygulayacağız.

Bu model sayesinde Doom oynamayı öğrenen bir ajan yaratabileceğiz!

Bu yazıda şunları öğreneceksiniz:

  • Derin Q-Öğrenme (DQL) nedir?
  • DQL ile kullanılacak en iyi stratejiler nelerdir?
  • Zamansal sınırlama sorunu nasıl çözülür?
  • Neden deneyim tekrarını kullanıyoruz
  • DQL'in arkasındaki matematik nedir
  • Tensorflow'da nasıl uygulanır?

Q-Learning'e 'Deep' Ekleme

Son makalede, Q-öğrenme algoritması sayesinde Frozen Lake oynayan bir ajan oluşturduk.

Q-tablosu oluşturmak ve güncellemek için Q-öğrenme işlevini uyguladık. Bunu, mevcut durum göz önüne alındığında, bir eylemin beklenen maksimum gelecekteki ödülünü bulmamıza yardımcı olacak bir "kopya kağıdı" olarak düşünün. Bu iyi bir stratejiydi - ancak bu ölçeklenebilir değil.

Bugün ne yapacağımızı hayal edin. Doom oynamayı öğrenen bir ajan yaratacağız. Doom, devasa bir durum alanına (milyonlarca farklı durum) sahip büyük bir ortamdır. Bu ortam için bir Q-tablosu oluşturmak ve güncellemek hiç verimli olmayacaktır.

Bu durumda en iyi fikir, bir durum verildiğinde, her eylem için farklı Q değerlerine yaklaşan bir sinir ağı oluşturmaktır.

Derin Q-Öğrenme nasıl çalışır?

Bu, Derin Q Öğrenmemizin mimarisi olacak:

Bu karmaşık görünebilir, ancak mimariyi adım adım açıklayacağım.

Deep Q Neural Network'ümüz, girdi olarak dört karelik bir yığın alır. Bunlar ağından geçer ve verilen durumda olası her eylem için bir Q-değerleri vektörü verir. En iyi eylemimizi bulmak için bu vektörün en büyük Q değerini almalıyız.

Başlangıçta ajan gerçekten çok kötü yapıyor. Ancak zamanla, çerçeveleri (durumları) yapılacak en iyi eylemlerle ilişkilendirmeye başlar.

Ön işleme bölümü

Ön işleme önemli bir adımdır. Eğitim için gereken hesaplama süresini azaltmak için durumlarımızın karmaşıklığını azaltmak istiyoruz.

İlk olarak, her bir durumumuzu gri tonlamalıyız. Renk önemli bilgiler eklemiyor (bizim durumumuzda, sadece düşmanı bulup öldürmemiz gerekiyor ve onu bulmak için renge ihtiyacımız yok). Üç renk kanalımızı (RGB) 1'e (gri tonlamalı) düşürdüğümüz için bu önemli bir tasarruftur.

Ardından çerçeveyi kırpıyoruz. Örneğimizde çatıyı görmek pek kullanışlı değil.

Ardından çerçevenin boyutunu küçültür ve dört alt çerçeveyi bir araya toparız.

Zamansal sınırlama sorunu

Arthur Juliani makalesinde bu konu hakkında harika bir açıklama yapıyor. Zekice bir fikri var: sorunu çözmek için LSTM sinir ağlarını kullanmak.

Ancak, yeni başlayanlar için yığılmış çerçeveler kullanmanın daha iyi olduğunu düşünüyorum.

Sorabileceğiniz ilk soru, neden çerçeveleri bir araya getirdiğimizdir?

Çerçeveleri bir arada istifliyoruz çünkü geçici sınırlama sorununu halletmemize yardımcı oluyor.

Pong oyununda bir örnek alalım. Bu çerçeveyi gördüğünüzde:

Bana topun nereye gittiğini söyleyebilir misin?

Hayır, çünkü bir kare hareket hissine sahip olmak için yeterli değildir!

Peki ya üç çerçeve daha eklersem? Burada topun sağa gittiğini görebilirsiniz.

Doom ajanımız için de aynı şey. Ona her seferinde sadece bir kare verirsek, hareket hakkında hiçbir fikri yoktur. Ve nesnelerin nerede ve ne kadar hızlı hareket ettiğini belirleyemiyorsa, nasıl doğru bir karar verebilir?

Evrişim ağlarını kullanma

Çerçeveler üç evrişim katmanı tarafından işlenir. Bu katmanlar, görüntülerdeki uzamsal ilişkilerden yararlanmanıza izin verir. Ama aynı zamanda, çerçeveler üst üste yığıldığı için, bu çerçeveler boyunca bazı uzamsal özelliklerden yararlanabilirsiniz.

Evrişime aşina değilseniz, lütfen Adam Geitgey'in bu mükemmel sezgisel makalesini okuyun.

Her evrişim katmanı ELU'yu bir aktivasyon işlevi olarak kullanacaktır. ELU'nun evrişim katmanları için iyi bir aktivasyon işlevi olduğu kanıtlanmıştır.

ELU aktivasyon fonksiyonuna sahip tamamen bağlantılı bir katman ve her eylem için Q-değeri tahminini üreten bir çıktı katmanı (doğrusal aktivasyon fonksiyonuna sahip tamamen bağlantılı bir katman) kullanıyoruz.

Deneyim Tekrarı: gözlemlenen deneyimin daha verimli kullanılması

Deneyim tekrarı iki şeyi halletmemize yardımcı olacaktır:

  • Önceki deneyimleri unutmaktan kaçının.
  • 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 Sinir Ağımızı uygulayalım

Atari Space Invaders? ️? Oynamayı öğrenen Tensorflow ile bir Deep Q-öğrenme ajanı uyguladığımız bir video yaptık.

Artık nasıl çalıştığını bildiğimize göre, Derin Q Sinir Ağımızı adım adım uygulayacağız. Kodun her adımı ve her bölümü, aşağıda bağlantısı verilen Jupyter not defterinde doğrudan açıklanmıştır.

Buna Derin Takviye Öğrenme Kursu deposunda erişebilirsiniz.

Bu kadar! Doom oynamayı öğrenen bir ajan yarattınız. Harika!

Kodun her bir parçasını kendiniz uygulamayı unutmayın. Size verdiğim kodu değiştirmeye çalışmak gerçekten önemli. Dönemler eklemeye, mimariyi değiştirmeye, sabit Q değerleri eklemeye, öğrenme oranını değiştirmeye, daha sert bir ortam kullanmaya çalışın (Sağlık Toplama gibi)… vb. Eğlenin!

Bir sonraki makalede, Derin Q-öğrenmedeki son gelişmeleri tartışacağım:

  • Sabit Q değerleri
  • 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