Flappy Bird Eğitimi: Takviye Edici Öğrenme Eğitimi
Yayınlanan: 2022-03-11Klasik programlamada, yazılım talimatları programcılar tarafından açıkça yapılır ve verilerden hiçbir şey öğrenilmez. Buna karşılık, makine öğrenimi, bilgisayarların açıkça programlanmadan öğrenmesini ve verilerden bilgi çıkarmasını sağlamak için istatistiksel yöntemler kullanan bir bilgisayar bilimi alanıdır.
Bu pekiştirmeli öğrenme eğitiminde, pekiştirmeli öğrenme sinir ağına Flappy Bird'ün nasıl oynanacağını öğretmek için PyTorch'u nasıl kullanabileceğimizi göstereceğim. Ama önce, birkaç yapı taşını ele almamız gerekecek.
Makine öğrenmesi algoritmaları kabaca iki kısma ayrılabilir: Geleneksel öğrenme algoritmaları ve derin öğrenme algoritmaları. Geleneksel öğrenme algoritmaları, genellikle derin öğrenme algoritmalarından çok daha az öğrenilebilir parametreye sahiptir ve çok daha az öğrenme kapasitesine sahiptir.
Ayrıca, geleneksel öğrenme algoritmaları özellik çıkarımı yapamaz: Yapay zeka uzmanlarının, daha sonra öğrenme algoritmasına gönderilen iyi bir veri gösterimi bulması gerekir. Geleneksel makine öğrenimi tekniklerine örnek olarak SVM, rastgele orman, karar ağacı ve $k$-ortalamalar dahildir, oysa derin öğrenmedeki merkezi algoritma derin sinir ağıdır .
Derin bir sinir ağına girdi ham görüntüler olabilir ve bir yapay zeka uzmanının herhangi bir veri temsili bulması gerekmez; sinir ağı eğitim süreci sırasında en iyi temsili bulur.
Çok uzun zamandır birçok derin öğrenme tekniği biliniyor, ancak donanımdaki son gelişmeler derin öğrenme araştırma ve geliştirmesini hızla artırdı. Nvidia, GPU'ları hızlı derin öğrenme deneylerini mümkün kıldığı için alanın genişlemesinden sorumludur.
Öğrenilebilir Parametreler ve Hiperparametreler
Makine öğrenmesi algoritmaları, eğitim sürecinde ayarlanan öğrenilebilir parametreler ve eğitim sürecinden önce ayarlanan öğrenilemeyen parametrelerden oluşur. Öğrenmeden önce ayarlanan parametrelere hiperparametreler denir.
Izgara arama , optimal hiperparametreleri bulmak için yaygın bir yöntemdir. Bu bir kaba kuvvet yöntemidir: Tanımlanmış bir aralıkta tüm olası hiperparametre kombinasyonlarını denemek ve önceden tanımlanmış bir metriği en üst düzeye çıkaran kombinasyonu seçmek anlamına gelir.
Denetimli, Denetimsiz ve Takviyeli Öğrenme Algoritmaları
Öğrenme algoritmalarını sınıflandırmanın bir yolu, denetimli ve denetimsiz algoritmalar arasında bir çizgi çizmektir. (Ama bu o kadar basit değil: Takviyeli öğrenme, bu iki türün arasında bir yerdedir.)
Denetimli öğrenme hakkında konuştuğumuzda $ (x_i, y_i) $ çiftlerine bakarız. $ x_i $ algoritmanın girdisidir ve $ y_i $ çıktıdır. Görevimiz $ x_i $ ile $ y_i $ arasında doğru eşleştirmeyi yapacak bir fonksiyon bulmaktır.
Öğrenilebilir parametreleri $ x_i $ ile $ y_i $ arasında eşleyen bir fonksiyon tanımlayacak şekilde ayarlamak için, bir kayıp fonksiyonu ve bir optimize edici tanımlanmalıdır. Optimize edici, kayıp işlevini en aza indirir. Kayıp fonksiyonuna bir örnek, ortalama kare hatasıdır (MSE):
\[MSE = \sum_{i=1}^{n} (y_i - \widehat{y_i} )^2\]Burada $ y_i $ bir kesinlik etiketidir ve $ \widehat{y_i} $ tahmin edilen bir etikettir. Derin öğrenmede çok popüler olan bir optimize edici, stokastik gradyan inişidir . Stokastik gradyan iniş yöntemini geliştirmeye çalışan birçok varyasyon vardır: Adam, Adadelta, Adagrad, vb.
Denetimsiz algoritmalar, açıkça etiketler sağlanmadan verilerdeki yapıyı bulmaya çalışır. $k$-means, verilerde optimal kümeleri bulmaya çalışan denetimsiz algoritmaların örneklerinden biridir. Aşağıda 300 veri noktasına sahip bir resim bulunmaktadır. $k$-algoritmaların verideki yapıyı bulduğu ve her veri noktasına bir küme etiketi atadığı anlamına gelir. Her kümenin kendi rengi vardır.
Takviyeli öğrenme, ödülleri kullanır: Seyrek, zaman gecikmeli etiketler. Bir etmen, yeni bir gözlem ve ödül alabileceği çevreyi değiştiren bir eylemde bulunur. Gözlem, bir ajanın çevreden algıladığı uyarandır. Aracının gördüğü, duyduğu, kokladığı vb. olabilir.
Bir eylemde bulunduğunda temsilciye bir ödül verilir. Temsilciye eylemin ne kadar iyi olduğunu söyler. Bir temsilci, gözlemleri ve ödülleri algılayarak, çevrede en iyi şekilde nasıl davranacağını öğrenir. Buna aşağıda daha ayrıntılı olarak gireceğim.
Aktif, Pasif ve Ters Pekiştirmeli Öğrenme
Bu tekniğe birkaç farklı yaklaşım vardır. Her şeyden önce, burada kullandığımız aktif pekiştirmeli öğrenme var. Buna karşılık, ödüllerin yalnızca başka bir gözlem türü olduğu ve kararların bunun yerine sabit bir politikaya göre alındığı pasif pekiştirmeli öğrenme vardır.
Son olarak, ters pekiştirmeli öğrenme, eylemlerin geçmişi ve çeşitli durumlardaki ödülleri verilen bir ödül işlevini yeniden yapılandırmaya çalışır.
Genelleme, Fazla Uydurma ve Eksik Uydurma
Herhangi bir sabit parametre ve hiperparametre örneğine model denir. Makine öğrenimi deneyleri genellikle iki bölümden oluşur: Eğitim ve test.
Eğitim süreci sırasında, eğitim verileri kullanılarak öğrenilebilir parametreler ayarlanır. Test sürecinde, öğrenilebilir parametreler dondurulur ve görev, modelin daha önce görülmemiş veriler üzerinde ne kadar iyi tahminler yaptığını kontrol etmektir. Genelleme, bir öğrenme makinesinin, bir öğrenme veri kümesini deneyimledikten sonra yeni, görünmeyen bir örnek veya görev üzerinde doğru şekilde performans gösterme yeteneğidir.
Bir model verilere göre çok basitse, eğitim verisine uyamayacak ve hem eğitim veri kümesinde hem de test veri kümesinde kötü performans gösterecektir. Bu durumda modelin yetersiz kaldığını söylüyoruz.
Bir makine öğrenimi modeli, bir eğitim veri kümesinde iyi performans gösteriyorsa, ancak bir test veri kümesinde kötü performans gösteriyorsa, bunun aşırı uygun olduğunu söyleriz . Fazla uydurma, bir modelin verilere göre çok karmaşık olduğu durumdur. Eğitim verilerine mükemmel bir şekilde uyabilir, ancak eğitim veri kümesine o kadar çok uyarlanmıştır ki, test verilerinde düşük performans gösterir - yani, basitçe genelleme yapmaz.
Aşağıda, genel veriler ve tahmin işlevi arasındaki dengeli bir durumla karşılaştırıldığında eksik ve fazla uydurmayı gösteren bir resim bulunmaktadır.
ölçeklenebilirlik
Veriler, makine öğrenimi modelleri oluşturmada çok önemlidir. Genellikle geleneksel öğrenme algoritmaları çok fazla veri gerektirmez. Ancak sınırlı kapasiteleri nedeniyle performans da sınırlıdır. Aşağıda, geleneksel makine öğrenimi algoritmalarına kıyasla derin öğrenme yöntemlerinin ne kadar iyi ölçeklendiğini gösteren bir grafik bulunmaktadır.
Nöral ağlar
Yapay sinir ağları birden çok katmandan oluşur. Aşağıdaki görüntü, dört katmanlı basit bir sinir ağını göstermektedir. İlk katman girdi katmanı, son katman ise çıktı katmanıdır. Giriş ve çıkış katmanları arasındaki iki katman gizli katmanlardır.
Bir sinir ağının birden fazla gizli katmanı varsa, buna derin sinir ağı diyoruz. $ X $ girdi seti sinir ağına verilir ve $ y $ çıktısı elde edilir. Öğrenme, bir kayıp fonksiyonu ve bir optimize ediciyi birleştiren bir geri yayılım algoritması kullanılarak yapılır.
Geri yayılım iki bölümden oluşur: ileri geçiş ve geri geçiş. İleri geçişte, giriş verileri sinir ağının girişine konur ve çıkış elde edilir. Yer gerçeği ile tahmin arasındaki kayıp hesaplanır ve daha sonra geriye doğru geçişte, sinir ağlarının parametreleri kayba göre ayarlanır.
Evrişimsel Sinir Ağı
Bir sinir ağı varyasyonu, evrişimli sinir ağıdır . Öncelikle bilgisayarla görme görevleri için kullanılır.
Evrişimli sinir ağlarındaki en önemli katman, evrişimsel katmandır (dolayısıyla adı). Parametreleri, çekirdek olarak da adlandırılan öğrenilebilir filtrelerden yapılmıştır. Evrişimsel katmanlar, sonucu bir sonraki katmana ileterek girdiye bir evrişim işlemi uygular. Evrişim işlemi, bir tür buluşsal yöntem işlevi görerek ve sinir ağının eğitilmesini kolaylaştırarak öğrenilebilir parametrelerin sayısını azaltır.
Aşağıda, bir evrişim katmanındaki bir evrişimsel çekirdeğin nasıl çalıştığı anlatılmaktadır. Çekirdek görüntüye uygulanır ve kıvrımlı bir özellik elde edilir.
ReLU katmanları, sinir ağındaki doğrusal olmayan durumları tanıtmak için kullanılır. Doğrusal olmayanlar önemlidir çünkü onlarla sadece doğrusal olanları değil, her türlü fonksiyonu modelleyebiliriz, bu da sinir ağını evrensel bir fonksiyon tahmincisi haline getirir. Bu, bir ReLU işlevinin şu şekilde tanımlanmasını sağlar:
\[ReLU = \max(0, x)\]ReLU, sinir ağlarında doğrusal olmayanları tanıtmak için kullanılan sözde aktivasyon fonksiyonlarının örneklerinden biridir. Diğer aktivasyon fonksiyonlarının örnekleri arasında sigmoid ve hiper-tanjant fonksiyonları yer alır. ReLU, diğer aktivasyon fonksiyonlarına kıyasla sinir ağı trenini daha verimli hale getirdiği gösterildiği için en popüler aktivasyon fonksiyonudur.
Aşağıda bir ReLU fonksiyonunun grafiği verilmiştir.
Gördüğünüz gibi, bu ReLU işlevi, negatif değerleri sıfıra değiştirir. Bu, kaybolan gradyan sorununu önlemeye yardımcı olur. Bir eğim kaybolursa, sinir ağının ağırlığının ayarlanmasında büyük bir etkisi olmayacaktır.
Bir evrişimsel sinir ağı, birden çok katmandan oluşur: Evrişimsel katmanlar, ReLU katmanları ve tamamen bağlı katmanlar. Tam bağlantılı katmanlar, bu bölümün başındaki görüntüdeki iki gizli katmanda görüldüğü gibi, bir katmandaki her nöronu başka bir katmandaki her nörona bağlar. Son tam olarak bağlı katman, önceki katmandan gelen çıktıları, bu durumda, number_of_actions
eşler.
Uygulamalar
Derin öğrenme başarılıdır ve bilgisayarla görme, konuşma tanıma ve pekiştirmeli öğrenme dahil olmak üzere çeşitli makine öğrenimi alt alanlarında klasik makine öğrenimi algoritmalarından daha iyi performans gösterir. Bu derin öğrenme alanları, çeşitli gerçek dünya alanlarında uygulanmaktadır: Finans, tıp, eğlence vb.
Pekiştirmeli Öğrenme
Takviyeli öğrenme, bir aracıya dayalıdır. Bir etmen, bir ortamda eylemlerde bulunur ve ondan gözlemler ve ödüller alır. Bir temsilcinin kümülatif ödülü en üst düzeye çıkarmak için eğitilmesi gerekir. Giriş bölümünde belirtildiği gibi, klasik makine öğrenimi algoritmalarıyla, makine öğrenimi mühendislerinin özellik çıkarımı yapması, yani ortamı iyi temsil eden ve bir makine öğrenimi algoritmasına beslenen iyi özellikler oluşturması gerekir.
Derin öğrenmeyi kullanarak, yüksek boyutlu girdi (örneğin video) alan uçtan uca bir sistem oluşturmak mümkündür ve bundan bir aracının iyi eylemlerde bulunması için en uygun stratejiyi öğrenir.
2013 yılında, Londra AI girişimi DeepMind, ajanları doğrudan yüksek boyutlu duyusal girdilerden kontrol etmeyi öğrenmede büyük bir atılım yarattı. Sadece ekrana bakarak Atari oyunlarını oynamayı yapay bir sinir ağını nasıl öğrettiklerini gösterdikleri bir makale yayınladılar. Google tarafından satın alındılar ve ardından Nature'da bazı iyileştirmelerle birlikte yeni bir makale yayınladılar: Derin pekiştirmeli öğrenme yoluyla insan düzeyinde kontrol .
Diğer makine öğrenimi paradigmalarının aksine, pekiştirmeli öğrenmenin bir süpervizörü yoktur, yalnızca bir ödül sinyali vardır. Geri bildirim gecikmeli: Denetimli öğrenme algoritmalarında olduğu gibi anlık değildir. Veriler sıralıdır ve bir aracının eylemleri, aldığı sonraki verileri etkiler.
Şimdi, bir etmen, belirli bir durumda olan çevresinde konumlanmıştır. Bunu daha ayrıntılı olarak açıklamak için, bu pekiştirmeli öğrenme ortamını modellemenin resmi bir yolu olan bir Markov karar süreci kullanıyoruz. Bir durumdan diğerine geçiş için bir dizi durumdan, bir dizi olası eylemden ve kurallardan (örneğin, olasılıklar) oluşur.
Ajan, çevreyi dönüştürerek eylemler gerçekleştirebilir. Ödüle $ R_t $ diyoruz. Bu, ajanın $t$ adımında ne kadar iyi yaptığını gösteren bir skaler geri besleme sinyalidir.
Uzun vadeli iyi bir performans için, yalnızca anlık ödüller değil, aynı zamanda gelecekteki ödüller de dikkate alınmalıdır. $t$ zaman adımından bir bölüm için toplam ödül $ R_t = r_t + r_{t+1} + r_{t+2} + \ldots + r_n $'dır. Gelecek belirsiz ve gelecekte ne kadar ileri gidersek, gelecek tahminleri o kadar farklı olabilir. Bu nedenle, indirimli bir gelecek ödülü kullanılır: $ R_t = r_t +\gamma r_{t+1} + \gamma^2r_{t+2} + \ldots + \gamma^{nt}r_n = r_t + \gamma R_{t+1} $. Bir temsilci, indirimli gelecekteki ödülü en üst düzeye çıkaran eylemi seçmelidir.
Derin Q-öğrenme
$ Q(s, a) $ işlevi,
Gelecekteki bir ödülün tahmini Bellman denklemi ile verilir: $ Q(s, a) = r + \gamma \max_{a'}Q(s', a') $ . Başka bir deyişle, bir duruma $ s $ ve bir eylem $ a $ tarafından verilen maksimum gelecekteki ödül, bir sonraki durum için anında ödül artı maksimum gelecekteki ödüldür.
Doğrusal olmayan fonksiyonlar (sinir ağları) kullanılarak Q değerlerinin yaklaşımı çok kararlı değildir. Bu nedenle, istikrar için deneyim tekrarı kullanılır. Bir eğitim oturumundaki bölümler sırasındaki deneyim, bir tekrar belleğinde saklanır. En son geçişi kullanmak yerine yeniden oynatma belleğinden rastgele mini yığınlar kullanılır. Bu, aksi takdirde sinir ağını yerel bir minimuma götürecek olan sonraki eğitim örneklerinin benzerliğini bozar.
Derin Q-öğrenme hakkında bahsedilmesi gereken iki önemli husus daha var: Keşif ve sömürü. Sömürü ile mevcut bilgi verilen en iyi karar verilir. Keşif daha fazla bilgi toplar.

Algoritma, sinir ağı tarafından önerilen bir eylemi gerçekleştirdiğinde, sömürü yapıyor: Sinir ağının öğrenilmiş bilgisinden yararlanıyor. Buna karşılık, bir algoritma rastgele bir eylemde bulunabilir, yeni olasılıkları keşfedebilir ve sinir ağına potansiyel yeni bilgiler sunabilir.
DeepMind'ın Playing Atari with Deep Reinforcement Learning adlı makalesinden alınan "Deneyimi Tekrar Oynatma ile Derin Q-öğrenme algoritması" aşağıda gösterilmiştir.
DeepMind, Derin Q-ağları (DQN) olarak kendi yaklaşımlarıyla eğitilmiş evrişimsel ağları ifade eder.
Flappy Bird Kullanan Derin Q-öğrenme Örneği
Flappy Bird, başlangıçta Vietnamlı video oyun sanatçısı ve programcı Dong Nguyen tarafından geliştirilen popüler bir mobil oyundu. İçinde, oyuncu bir kuşu kontrol eder ve yeşil borular arasında onlara çarpmadan uçmaya çalışır.
Aşağıda, PyGame kullanılarak kodlanmış bir Flappy Bird klonundan bir ekran görüntüsü verilmiştir:
Klon o zamandan beri çatallandı ve değiştirildi: Arka plan, sesler ve farklı kuş ve boru stilleri kaldırıldı ve kod, basit takviye öğrenme çerçeveleriyle kolayca kullanılabilecek şekilde ayarlandı. Değiştirilmiş oyun motoru bu TensorFlow projesinden alınmıştır:
Ancak TensorFlow kullanmak yerine PyTorch kullanarak derin bir pekiştirmeli öğrenme çerçevesi oluşturdum. PyTorch, hızlı ve esnek deneyler için bir derin öğrenme çerçevesidir. Güçlü GPU hızlandırması ile Python'da tensörler ve dinamik sinir ağları sağlar.
Sinir ağı mimarisi, derin pekiştirmeli öğrenme yoluyla İnsan düzeyinde kontrol belgesinde kullanılan DeepMind ile aynıdır.
Katman | Giriş | Filtre boyutu | adım | Filtre sayısı | aktivasyon | Çıktı |
---|---|---|---|---|---|---|
dönş1 | 84x84x4 | 8x8 | 4 | 32 | ReLU | 20x20x32 |
dönş2 | 20x20x32 | 4x4 | 2 | 64 | ReLU | 9x9x64 |
dönş3 | 9x9x64 | 3x3 | 1 | 64 | ReLU | 7x7x64 |
fc4 | 7x7x64 | 512 | ReLU | 512 | ||
fc5 | 512 | 2 | Doğrusal | 2 |
Üç evrişimsel katman ve iki tam bağlantılı katman vardır. Doğrusal aktivasyonu kullanan sonuncusu hariç, her katman ReLU aktivasyonunu kullanır. Sinir ağı, oyuncunun yegane olası eylemlerini temsil eden iki değer verir: "Uç" ve "hiçbir şey yapma".
Giriş, dört ardışık 84x84 siyah beyaz görüntüden oluşur. Aşağıda, sinir ağına beslenen dört görüntünün bir örneği verilmiştir.
Görüntülerin döndürüldüğünü fark edeceksiniz. Bunun nedeni, klonun oyun motorunun çıktısının döndürülmüş olmasıdır. Ancak sinir ağı bu tür görüntüler kullanılarak öğretilir ve daha sonra test edilirse, performansını etkilemeyecektir.
Ayrıca, bu görev için alakasız olduğundan zeminin atlandığı şekilde görüntünün kırpıldığını da fark edebilirsiniz. Boruları ve kuşu temsil eden tüm pikseller beyazdır ve arka planı temsil eden tüm pikseller siyahtır.
Bu, sinir ağını tanımlayan kodun bir parçasıdır. Sinir ağlarının ağırlıkları, $\mathcal{U}(-0.01, 0.01)$ tekdüze dağılımını takip edecek şekilde başlatılır. Sinir ağlarının parametrelerinin önyargı kısmı 0.01 olarak ayarlanmıştır. Birkaç farklı başlatma denendi (Xavier tek tip, Xavier normal, Kaiming tek tip, Kaiming normal, tek tip ve normal), ancak yukarıdaki başlatma, sinir ağını yakınsamasını ve en hızlı şekilde eğitmesini sağladı. Sinir ağının boyutu 6.8 MB'dir.
class NeuralNetwork(nn.Module): def __init__(self): super(NeuralNetwork, self).__init__() self.number_of_actions = 2 self.gamma = 0.99 self.final_epsilon = 0.0001 self.initial_epsilon = 0.1 self.number_of_iterations = 2000000 self.replay_memory_size = 10000 self.minibatch_size = 32 self.conv1 = nn.Conv2d(4, 32, 8, 4) self.relu1 = nn.ReLU(inplace=True) self.conv2 = nn.Conv2d(32, 64, 4, 2) self.relu2 = nn.ReLU(inplace=True) self.conv3 = nn.Conv2d(64, 64, 3, 1) self.relu3 = nn.ReLU(inplace=True) self.fc4 = nn.Linear(3136, 512) self.relu4 = nn.ReLU(inplace=True) self.fc5 = nn.Linear(512, self.number_of_actions) def forward(self, x): out = self.conv1(x) out = self.relu1(out) out = self.conv2(out) out = self.relu2(out) out = self.conv3(out) out = self.relu3(out) out = out.view(out.size()[0], -1) out = self.fc4(out) out = self.relu4(out) out = self.fc5(out) return out
Yapıcıda, tanımlanmış hiperparametreler olduğunu fark edeceksiniz. Bu blog gönderisinin amacı için hiperparametre optimizasyonu yapılmamıştır. Bunun yerine, hiperparametreler çoğunlukla DeepMind'ın makalelerinden kullanılır. Burada, bazı hiperparametreler DeepMind'ın makalesinden daha düşük olacak şekilde ölçeklenmiştir, çünkü Flappy Bird, ayarlama için kullandıkları Atari oyunlarından daha az karmaşıktır.
Ayrıca epsilon bu oyun için çok daha makul olacak şekilde değiştirildi. DeepMind bir epsilon kullanır, ama biz burada 0.1 kullanıyoruz. Bunun nedeni, daha yüksek epsilonların kuşu çok fazla kanat çırpmaya zorlaması, bu da kuşu ekranın üst kenarına doğru itmesi ve sonunda her zaman kuşun bir boruya çarpmasıyla sonuçlanmasıdır.
Takviye öğrenme kodunun iki modu vardır: Eğit ve test et. Test aşamasında pekiştirmeli öğrenme algoritmasının oyunu oynamayı ne kadar iyi öğrendiğini görebiliriz. Ama önce, sinir ağının eğitilmesi gerekiyor. En aza indirilecek kayıp fonksiyonunu ve kayıp fonksiyonunu en aza indirecek optimize edicileri tanımlamamız gerekiyor. Kayıp fonksiyonu için Adam optimizasyon yöntemini ve ortalama karesel hatayı kullanacağız:
optimizer = optim.Adam(model.parameters(), lr=1e-6) criterion = nn.MSELoss()
Oyun somutlaştırılmalıdır:
game_state = GameState()
Yeniden oynatma belleği bir Python listesi olarak tanımlanır:
replay_memory = []
Şimdi ilk durumu başlatmamız gerekiyor. Bir eylem iki boyutlu tensördür:
- [1, 0] "hiçbir şey yapmamayı" temsil eder
- [0, 1] "yukarı uçmayı" temsil eder
frame_step
yöntemi bize bir sonraki ekranı, ödülü ve sonraki durumun terminal olup olmadığı hakkında bilgi verir. Ödül, her kuşun borudan geçmediği zaman ölmeden yaptığı hareket için 0.1
, borudan başarılı bir şekilde geçtiği takdirde 1
ve kuş çarptığında -1
.
resize_and_bgr2gray
işlevi zemini kırpar, ekranı 84x84 görüntüye yeniden boyutlandırır ve renk alanını BGR'den siyah beyaza değiştirir. image_to_tensor
işlevi, görüntüyü bir PyTorch tensörüne dönüştürür ve CUDA varsa onu GPU belleğine yerleştirir. Son olarak, son dört ardışık ekran bir araya getirilir ve sinir ağına gönderilmeye hazırdır.
action = torch.zeros([model.number_of_actions], dtype=torch.float32) action[0] = 1 image_data, reward, terminal = game_state.frame_step(action) image_data = resize_and_bgr2gray(image_data) image_data = image_to_tensor(image_data) state = torch.cat((image_data, image_data, image_data, image_data)).unsqueeze(0)
İlk epsilon, bu kod satırı kullanılarak ayarlanır:
epsilon = model.initial_epsilon
Ana sonsuz döngü takip eder. Yorumlar koda yazılır ve yukarıda yazılan Deep Q-learning with Experience Replay algoritması ile kodu karşılaştırabilirsiniz.
Algoritma, yeniden oynatma belleğinden mini yığınları örnekler ve sinir ağının parametrelerini günceller. Eylemler, epsilon açgözlü keşif kullanılarak yürütülür. Epsilon zamanla tavlanıyor. Küçültülmekte olan kayıp fonksiyonu $ L = \frac{1}{2}\left[\max_{a'}Q(s', a') - Q(s, a)\right]^2 $'dır. $ Q(s, a) $, Bellman denklemi kullanılarak hesaplanan temel doğruluk değeridir ve sinir ağından $ \max_{a'}Q(s', a') $ elde edilir. Sinir ağı, olası iki eylem için iki Q değeri verir ve algoritma en yüksek Q değerine sahip eylemi alır.
while iteration < model.number_of_iterations: # get output from the neural network output = model(state)[0] # initialize action action = torch.zeros([model.number_of_actions], dtype=torch.float32) if torch.cuda.is_available(): # put on GPU if CUDA is available action = action.cuda() # epsilon greedy exploration random_action = random.random() <= epsilon if random_action: print("Performed random action!") action_index = [torch.randint(model.number_of_actions, torch.Size([]), dtype=torch.int) if random_action else torch.argmax(output)][0] if torch.cuda.is_available(): # put on GPU if CUDA is available action_index = action_index.cuda() action[action_index] = 1 # get next state and reward image_data_1, reward, terminal = game_state.frame_step(action) image_data_1 = resize_and_bgr2gray(image_data_1) image_data_1 = image_to_tensor(image_data_1) state_1 = torch.cat((state.squeeze(0)[1:, :, :], image_data_1)).unsqueeze(0) action = action.unsqueeze(0) reward = torch.from_numpy(np.array([reward], dtype=np.float32)).unsqueeze(0) # save transition to replay memory replay_memory.append((state, action, reward, state_1, terminal)) # if replay memory is full, remove the oldest transition if len(replay_memory) > model.replay_memory_size: replay_memory.pop(0) # epsilon annealing epsilon = epsilon_decrements[iteration] # sample random minibatch minibatch = random.sample(replay_memory, min(len(replay_memory), model.minibatch_size)) # unpack minibatch state_batch = torch.cat(tuple(d[0] for d in minibatch)) action_batch = torch.cat(tuple(d[1] for d in minibatch)) reward_batch = torch.cat(tuple(d[2] for d in minibatch)) state_1_batch = torch.cat(tuple(d[3] for d in minibatch)) if torch.cuda.is_available(): # put on GPU if CUDA is available state_batch = state_batch.cuda() action_batch = action_batch.cuda() reward_batch = reward_batch.cuda() state_1_batch = state_1_batch.cuda() # get output for the next state output_1_batch = model(state_1_batch) # set y_j to r_j for terminal state, otherwise to r_j + gamma*max(Q) y_batch = torch.cat(tuple(reward_batch[i] if minibatch[i][4] else reward_batch[i] + model.gamma * torch.max(output_1_batch[i]) for i in range(len(minibatch)))) # extract Q-value q_value = torch.sum(model(state_batch) * action_batch, dim=1) # PyTorch accumulates gradients by default, so they need to be reset in each pass optimizer.zero_grad() # returns a new Tensor, detached from the current graph, the result will never require gradient y_batch = y_batch.detach() # calculate loss loss = criterion(q_value, y_batch) # do backward pass loss.backward() optimizer.step() # set state to be state_1 state = state_1
Artık tüm parçalar yerine oturduğuna göre, sinir ağımızı kullanan veri akışına üst düzey bir genel bakış:
İşte eğitimli bir sinir ağına sahip kısa bir dizi.
Yukarıda gösterilen sinir ağı, birkaç saat boyunca üst düzey bir Nvidia GTX 1080 GPU kullanılarak eğitildi; Bunun yerine CPU tabanlı bir çözüm kullanıldığında, bu özel görev birkaç gün sürecektir. Oyun motorunun FPS'si eğitim sırasında çok büyük bir sayıya ayarlandı: 999…999 - başka bir deyişle, saniyede mümkün olduğunca çok kare. Test aşamasında, FPS 30 olarak ayarlandı.
Aşağıda, yinelemeler sırasında maksimum Q değerinin nasıl değiştiğini gösteren bir grafik bulunmaktadır. Her 10.000'inci yineleme gösterilir. Aşağı doğru bir artış, belirli bir kare için (bir yineleme bir karedir) sinir ağının kuşun gelecekte çok düşük bir ödül alacağını, yani çok yakında çökeceğini tahmin ettiği anlamına gelir.
Tam kod ve önceden eğitilmiş model burada mevcuttur.
Derin Takviyeli Öğrenme: 2B, 3B ve Hatta Gerçek Hayat
Bu PyTorch pekiştirmeli öğrenme eğitiminde, bir insanın oyunla ilk kez karşılaştığında yapacağı gibi yalnızca bir deneme-yanılma yaklaşımı kullanarak, bir bilgisayarın oyun hakkında önceden herhangi bir bilgiye sahip olmadan Flappy Bird oynamayı nasıl öğrenebileceğini gösterdim.
Algoritmanın PyTorch çerçevesi kullanılarak birkaç kod satırında uygulanabilmesi ilginçtir. Bu blogdaki yöntemin dayandığı makale nispeten eskidir ve daha hızlı yakınsama sağlayan çeşitli modifikasyonlara sahip birçok yeni makale mevcuttur. O zamandan beri, 3D oyunlar oynamak için ve gerçek dünyadaki robotik sistemlerde derin pekiştirmeli öğrenme kullanıldı.
DeepMind, Maluuba ve Vicarious gibi şirketler yoğun bir şekilde derin pekiştirmeli öğrenme üzerinde çalışıyor. Bu teknoloji, Go'da dünyanın en iyi oyuncularından biri olan Lee Sedol'u yenen AlphaGo'da kullanıldı. O zamanlar, makinelerin Go'daki en iyi oyuncuları yenmesinin en az on yıl alacağı düşünülüyordu.
Derin pekiştirici öğrenmeye (ve genel olarak yapay zekaya) ilgi ve yatırımlar, potansiyel yapay genel zekaya (AGI) - bir algoritma şeklinde ifade edilebilecek insan düzeyinde zekaya (veya hatta ötesine) bile yol açabilir ve bilgisayarlarda simüle edilmiştir. Ancak AGI başka bir makalenin konusu olmak zorunda kalacak.
Referanslar:
- Derin Takviyeli Öğrenmenin Gizemini Çözme
- Flappy Bird için Derin Takviyeli Öğrenme
- Vikipedi'de "Evrişimli sinir ağı"
- Wikipedia'da "Takviyeli öğrenme"
- Wikipedia'da "Markov karar süreci"
- RL'de University College London kursu