Tensorflowda Basit Takviyeli Öğrenme: Tablolar ve Sinir Ağları ile Q-Learning

Takviyeli Öğrenme serisindeki bu ders için, Q-Learning algoritmaları adı verilen bir takviyeli öğrenme algoritması ailesi keşfedeceğiz. Bunlar, aşağıdaki derslerde incelenecek politika tabanlı algoritmalardan biraz farklıdır. Karmaşık ve gizemli bir derin sinir ağına başlamak yerine, algoritmanın basit bir arama tablosu versiyonunu uygulayarak başlayacağız ve daha sonra Tensorflow kullanarak bir nöral ağ eşdeğerinin nasıl uygulanacağını göstereceğiz. Temellere geri döneceğimiz göz önüne alındığında, bunu dizinin Bölüm-0’ı olarak düşünmek en iyisi olabilir. Umarım, Q-learning’de gerçekte neler olup bittiğine dair bir sezgiler sunacağız. Böylece, en son teknoloji takviyeli öğrenme ajanlarını oluşturmak için politika gradyanını ve Q-learning yaklaşımlarını nihayetinde birleştirdiğimizde ilerlemeye devam edebiliriz. (Politika ağları ile daha çok ilgileniyorsanız veya Q-learning hakkında zaten bir bilginiz varsa, eğitim dizisine başlamaktan çekinmeyin.)

Bir gözlemi doğrudan bir eylemle eşleştiren işlevleri öğrenmeye çalışan politika eğim yöntemlerinden farklı olarak, Q-learning, belirli bir durumda olmanın değerini öğrenmek ve belirli bir eylemi gerçekleştirmek için çabalar. Her iki yaklaşım da, sonuçta bir duruma göre akıllı eylemler gerçekleştirmemize izin verirken, bu eyleme geçme yolları önemli ölçüde farklılık göstermektedir. Atari Oyunlarını oynayabilecek Derin Q-Ağları hakkında bir şeyler duymuş olabilirsiniz. Bunlar, burada tartışacağımız Q-learning algoritmasının gerçekten daha büyük ve daha karmaşık uygulamalarıdır.

Tablolu Ortamlar için Tablo Biçiminde Yaklaşımlar

Resim: FrozenLake ortamının kuralları.

Bu eğitim için, OpenAI egzersiz salonundan(OpenAI gym) FrozenLake ortamını çözmeye çalışıyoruz. Tanıdık olmayanlar için OpenAI egzersiz salonu, insanların bir dizi sağladıkları oyuncak oyunlarında kendi öğrenme aracılarıyla deney yapmaları için kolay bir yol sağlar. FrozenLake ortamı, her biri başlangıç ​​bloğu, hedef bloğu, güvenli bir donmuş blok veya tehlikeli bir delik olan 4×4 ızgara bloğundan oluşur. Amaç, bir ajanın, bir deliğe geçmeden, başlangıçtan hedefe doğru gitmeyi öğrenmesidir. Herhangi bir zamanda, temsilci yukarı, aşağı, sola veya sağa hareket etmeyi seçebilir. Avcı, ajanı bazen seçmediği bir alana üfleyen bir rüzgârdır. Böylelikle her seferinde mükemmel performans imkansızdır, ancak deliklerden kaçınmayı ve hedefe ulaşmayı öğrenmek kesinlikle mümkündür. Her adımdaki ödül, 1 ödülünü sağlayan hedefin girilmesi haricinde, 0’dır. Böylece, uzun vadeli beklenen ödülleri öğrenen bir algoritmaya ihtiyacımız olacak. Bu, Q-learningi sağlamak için tasarlanmış bir şeydir.

En basit uygulamada, Q-learning, ortamdaki olası her durum (satır) ve eylem (sütun) için bir değer tablosudur. Masanın her hücresinde, belirli bir durumda belirli bir eylemi gerçekleştirmenin ne kadar iyi olduğuna dair bir değer öğreniyoruz. FrozenLake ortamı söz konusu olduğunda, 16 olası duruma (her blok için bir tane) ve 4 olası harekete (dört hareket yönü) sahibiz, bu da bize bir 16×4’lük Q-değerleri tablosu veriyor. Tabloyu, tekdüze (tümü sıfır) olacak şekilde başlatmaya başlıyoruz ve daha sonra çeşitli eylemler için elde ettiğimiz ödülleri gözlemledikçe, tabloyu buna göre güncelliyoruz.

Q-tablomuzda, Bellman denklemi denilen bir şeyi kullanarak, belirli bir eylem için beklenen uzun vadeli ödülün, şu anki eylemin en iyi gelecekteki eyleminden beklenen ödülle birleştirilen mevcut eylemden derhal ödüle eşit olduğu belirtilmektedir. Bu şekilde, gelecekteki eylemler için tablomuzu nasıl güncelleyeceğimizi tahmin ederken kendi Q tablomuzu yeniden kullanırız! Denklem formunda kural şuna benzer:

Denklem 1. Q(s,a) = r + γ(max(Q(s’,a’))

Bu, belirli bir durum (lar) ve aksiyon (a) için Q-değerinin, şimdiki ödülü (r) artı bir sonraki hal (ler) için kendi masamıza göre beklenen en yüksek indirilmiş (γ) geleceğin ödülünü temsil etmesi gerektiğini söyler. Sonuç olarak, indirim değişkeni, gelecekteki muhtemel ödüllerin mevcut ödülle karşılaştırılmasının ne kadar önemli olduğuna karar vermemize izin verir. Bu şekilde güncellenerek, tablo belirli bir durumda belirli bir eylem için beklenen gelecekteki ödülün doğru ölçümlerini yavaş yavaş elde etmeye başlar. Aşağıda FrozenLake ortamında uygulanan Q-Tablo algoritmasının bir Python adımı verilmiştir:

Q-Tablo Öğrenimi

In [ ]:
import gym
import numpy as np

Ortamı yükle

In [ ]:
env = gym.make('FrozenLake-v0')

Q-Tablo öğrenme algoritmasını uygular

In [ ]:
# Tüm sıfırları içeren tabloyu başlat.
Q = np.zeros([env.observation_space.n,env.action_space.n])
# Öğrenme parametrelerini ayarla.
lr = .8
y = .95
num_episodes = 2000
# Bölüm başına toplam ödüller ve adımlar içerecek listeleri oluşturun.
#jList = []
rList = []
for i in range(num_episodes):
    # Çevreyi sıfırla ve ilk yeni gözlemi al.
    s = env.reset()
    rAll = 0
    d = False
    j = 0
    # Q-Tablo öğrenme algoritması
    while j < 99:
        j+=1
        # Q tablosundan seçilecek (gürültü ile) bir eylem seçin.
        a = np.argmax(Q[s,:] + np.random.randn(1,env.action_space.n)*(1./(i+1)))
        # Yeni durumu al ve çevreden ödüllendir.
        s1,r,d,_ = env.step(a)
        # Q-Tablosunu yeni bilgilerle güncelleyin.
        Q[s,a] = Q[s,a] + lr*(r + y*np.max(Q[s1,:]) - Q[s,a])
        rAll += r
        s = s1
        if d == True:
            break
    #jList.append(j)
    rList.append(rAll)
In [ ]:
print ("Zamanla skor: " +  str(sum(rList)/num_episodes))
In [ ]:
print ("Q-Tablosu Final Değerleri")
print (Q)

 

Sinir Ağlarıyla Q-Learning

Şimdi, şöyle düşünebilirsiniz: tablolar harika, ama gerçekten ölçeklemiyorlar, değil mi? Basit bir ızgara dünyası için 16×4 tabloya sahip olmak kolay olsa da, herhangi bir modern oyunda veya gerçek dünyadaki olası durumların sayısı neredeyse sonsuzdur. En ilginç problemler için tablolar işe yaramıyor. Bunun yerine durmumuzun bir tanımını yapmanın ve bir tablo olmayan eylemler için Q-değerleri üretmenin bir yoluna ihtiyacımız var: yani sinir ağlarının devreye girdiği yer. Bir fonksiyon parametresi olarak hareket ederek, bir vektör olarak temsil edilebilecek herhangi bir sayıda olası durumu alabilir ve bunları Q değerleri ile eşleştirmeyi öğrenebiliriz.

FrozenLake örneğinde, tek-sıcak bir vektörde (1×16) kodlanan durumu alan ve her eylem için bir tane olmak üzere 4 tane Q-değerinin bir vektörünü üreten bir tek-katmanlı ağ kullanacağız. Böyle basit bir ağ, eski hücreler olarak hizmet eden ağ ağırlıkları ile birlikte, yüceltilmiş bir tablo gibi davranır. Temel fark, katmanlar, aktivasyon fonksiyonları ve farklı giriş tipleri ile Tensorflow ağını kolayca genişletebilmemiz, buna karşın normal bir tablo ile imkansız. Güncelleme yöntemi de biraz farklı. Tablomuzu doğrudan güncellemek yerine, bir ağ ile geri yayılım ve bir kayıp fonksiyonu(loss function) kullanacağız. Kayıp fonksiyonumuz kareler kaybı olacak, mevcut tahmin edilen Q-değerleri ve hedef değer arasındaki fark hesaplanır ve alçalmalar ağ üzerinden geçirilir. Bu durumda, seçilen eylem için Q-hedefimiz, yukarıdaki 1. denklemde hesaplanan Q-değerine eşdeğerdir.

Eq2. Loss = ∑(Q-target – Q)²

Aşağıda, basit Q-Ağımızı uygulamak için Tensorflow örneği yer almaktadır:

Q-Network Öğrenimi

In [1]:
import gym
import numpy as np
import random
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline

Çevreyi(ortamı) yükle

In [2]:
env = gym.make('FrozenLake-v0')
INFO:gym.envs.registration:Making new env: FrozenLake-v0
[2016-08-25 11:47:05,546] Making new env: FrozenLake-v0

Q-Network Yaklaşımı

Ağın kendisini uygulamak

In [381]:
tf.reset_default_graph()
In [382]:
# Bu çizgiler, eylemleri seçmek için kullanılan ağın ileriye dönük bölümünü oluşturur.
inputs1 = tf.placeholder(shape=[1,16],dtype=tf.float32)
W = tf.Variable(tf.random_uniform([16,4],0,0.01))
Qout = tf.matmul(inputs1,W)
predict = tf.argmax(Qout,1)

# Aşağıda hedef ve tahmini Q-değerleri arasındaki kareler toplamı alınarak kayıp elde edilir.
nextQ = tf.placeholder(shape=[1,4],dtype=tf.float32)
loss = tf.reduce_sum(tf.square(nextQ - Qout))
trainer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
updateModel = trainer.minimize(loss)

Ağın eğitimi

In [383]:
init = tf.initialize_all_variables()

# Öğrenme parametrelerini ayarlayın.
y = .99
e = 0.1
num_episodes = 2000
# Bölüm başına toplam ödülleri ve adımları içerecek listeleri oluşturun.
jList = []
rList = []
with tf.Session() as sess:
    sess.run(init)
    for i in range(num_episodes):
        # Çevreyi sıfırla ve ilk yeni gözlemi al.
        s = env.reset()
        rAll = 0
        d = False
        j = 0
        # Q-Ağı
        while j < 99:
            j+=1
            # Q-ağından açgözlülükle(rastgele hareket etme şansıyla) bir eylem seçin.
            a,allQ = sess.run([predict,Qout],feed_dict={inputs1:np.identity(16)[s:s+1]})
            if np.random.rand(1) < e:
                a[0] = env.action_space.sample()
            # Yeni durumu al ve çevreden ödüllendir.
            s1,r,d,_ = env.step(a[0])
            # Yeni durumu ağımız üzerinden besleyerek Q-değerlerini elde edin.
            Q1 = sess.run(Qout,feed_dict={inputs1:np.identity(16)[s1:s1+1]})
            # MaxQ'yü elde edin ve seçilen eylem için hedef değerimizi ayarlayın.
            maxQ1 = np.max(Q1)
            targetQ = allQ
            targetQ[0,a[0]] = r + y*maxQ1
            # Hedef ve öngörülen Q-değerlerini kullanarak ağınızı eğitin.
            _,W1 = sess.run([updateModel,W],feed_dict={inputs1:np.identity(16)[s:s+1],nextQ:targetQ})
            rAll += r
            s = s1
            if d == True:
                # Modeli eğitirken rastgele hareket etme şansını azaltın.
                e = 1./((i/50) + 10)
                break
        jList.append(j)
        rList.append(rAll)
print ("Başarılı bölümlerin yüzdesi: " + str(sum(rList)/num_episodes) + "%")
Başarılı bölümlerin yüzdesi: 0.352%

Ağ performansı ile ilgili bazı istatistikler

Ağın, 750 bölüm işareti etrafında sürekli olarak hedefe ulaştığını görebiliyoruz.

In [384]:
plt.plot(rList)
Out[384]:
[<matplotlib.lines.Line2D at 0x11a81e610>]

Ayrıca, çevre boyunca 750 işaretin etrafında da şanstan daha uzun bir sürede ilerlemeye başlar.

In [385]:
plt.plot(jList)
Out[385]:
[<matplotlib.lines.Line2D at 0x119bd5dd0>]
qlearn
Ağ, FrozenLake problemini çözmeyi öğrenirken, bunun Q-Tablosu kadar verimli bir şekilde yapılmadığı ortaya çıkıyor. Nöral ağlar daha fazla esnekliğe izin verirken, Q-Learning söz konusu olduğunda stabilite maliyetinde bunu yaparlar. Daha fazla performans ve daha sağlam bir öğrenime olanak tanıyan basit Q-Network’ümüze birçok olası uzantı vardır. Özellikle iki hileci, Deneyimi Yeniden Oynat(Experience Replay) ve Donma Hedef Ağları(Freezing Target Network) olarak adlandırılır. Bu iyileştirmeler ve diğer ince ayarlamalar, Atari’nin Deep Q-Networks adlı oyununu almanın anahtarıydı ve gelecekte bu eklemeleri keşfedeceğiz. Q-Learning’in arkasındaki teori hakkında daha fazla bilgi için, bkz. Tambet Matiisen. Bu eğitimin, basit Q-Learning algoritmalarını nasıl uygulayacağını merak edenler için yararlı olduğunu umuyorum!
Kaynak: https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part-0-q-learning-with-tables-and-neural-networks-d195264329d0

 

 

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s