Orijinal: Dylan Djian
Kestane satranç derlemesi
Qubit Üretildi | Genel Hesap QbitAI
Gün içinde, Ke Jienin 9. danını yendikten kısa bir süre sonra AlphaGonun Master versiyonu alındı AlphaGo Zero (Kısaca Gou Ling) yenildi.
Ustayı yenmek için git anlamayan bir yapay zekadan 21 günler .
Dahası, insan bilgisiyle beslenmesine gerek yoktur, en iyi satranç oyuncusu olmasına bağlıdır. Bireysel çalışma .
Yapabilirsen Beslemek Böyle bir YZ, satranç oynayamasa bile gurur duyabilir.
Yani, Dylan Djian, Paris'ten genç bir adam (kısaltması Xiaodi), tıpkı bir köpek gibi kağıt Başarmak için.
Yapay zeka satranç oyuncusu SuperGo'yu seçti ve ayrıca Kod (Portal için metnin altına bakın).
bunun yanı sıra Öğreticiler
Temsilci üç bölüme ayrılmıştır:
Biri Özellik çıkarıcı (Feature Extractor), ikincisi Strateji ağı (Politika Ağı), üçüncüsü Değer ağı (Değer Ağı).
Sonuç olarak, Gou Ling'e sevgiyle "iki başlı canavar" da denildi. Özellik çıkarıcı Vücut , Diğer iki ağ Beyin .
Özellik çıkarıcı
Özellik çıkarma modeli bir artık ağdır ( ResNet ), Katman atlama bağlantısı eklemektir ( Bağlantıyı Atla ) , İzin Vermek gradyan Daha sorunsuz yayın.
Kod olarak yazılan atlama görünümü:
1 sınıf BasicBlock (nn.Modül):
2 "" "
32 evrişimli ve bir atlama bağlantısına sahip temel artık blok
Son ReLU aktivasyonundan önce 4.
5 "" "
6
7 def __içinde__ (self, inplanes, planes, stride = 1, downsample = None):
8 süper (BasicBlock, self) .__ init __ ()
9
10 self.conv1 = nn.Conv2d (uçaklar, uçaklar, kernel_size = 3,
11 adım = adım, dolgu = 1, önyargı = Yanlış )
12 self.bn1 = nn.BatchNorm2d (uçaklar)
13
14 self.conv2 = nn.Conv2d (uçaklar, uçaklar, kernel_size = 3,
15 adım = adım, dolgu = 1, önyargı = Yanlış )
16 self.bn2 = nn.BatchNorm2d (uçaklar)
17
18
19 def ileri (öz, x):
20 artık = x
yirmi bir
22 çıkış = self.conv1 (x)
23 çıkış = F.relu (self.bn1 (çıkış))
yirmi dört
25 çıkış = self.conv2 (çıkış)
26 çıkış = self.bn2 (çıkış)
27
28 çıkış + = artık
29 çıkış = F.relu (çıkış)
30
31 dönüş dışarı
Ardından, bunu özellik çıkarma modeline ekleyin:
1 sınıf Ekstraktör (nn.Modül):
2 def __içinde__ (kendisi, uçaklar, dış uçlar):
3 süper (Çıkarıcı, öz) .__ init __ ()
4 self.conv1 = nn.Conv2d (düzlem içi, dış düzlem, adım = 1,
5 kernel_size = 3, padding = 1, bias = Yanlış )
6 self.bn1 = nn.BatchNorm2d (dış düzlemler)
7
8 için blok içinde aralığı (BLOKLAR):
9 setattr (self, "res {}". Format (blok), \
10 BasicBlock (dış düzlemler, dış düzlemler))
11
12
13 def ileri (öz, x):
14 x = F.relu (self.bn1 (self.conv1 (x)))
15 için blok içinde aralığı (BLOKLAR-1):
16 x = getattr (self, "res {}". Format (blok)) (x)
17
18 feature_maps = getattr (self, "res {}". Format (BLOCKS-1)) (x)
19 dönüş feature_maps
Strateji ağı
Strateji ağı yalnızca sıradan bir CNN'dir ve bir Toplu standardizasyon (Toplu Normalleştirme), tamamen bağlı bir katman var, çıktı Olasılık dağılımları .
1 sınıf PolicyNet (nn.Modül):
2 def __içinde__ (kendisi, uçaklar, dış uçlar):
3 süper (PolicyNet, self) .__ init __ ()
4 self.outplanes = outplanes
5 self.conv = nn.Conv2d (düzlem içi, 1, kernel_size = 1)
6 self.bn = nn.BatchNorm2d (1)
7 self.logsoftmax = nn.LogSoftmax (dim = 1)
8 self.fc = nn.Linear (dış düzlemler-1, dış düzlemler)
9
10
11 def ileri (öz, x):
12 x = F.relu (self.bn (self.conv (x)))
13 x = x.view (-1, self.outplanes-1)
14 x = self.fc (x)
15 proba = self.logsoftmax (x) .exp ()
16
17 dönüş probas
Değer ağı
Bu ağ biraz daha karmaşık. Standart konfigürasyona ek olarak, tam bağlantılı bir katman daha eklenir. Son olarak, mevcut durumu temsil etmek üzere (-1,1) arasındaki değeri hesaplamak için Hiperbolik Tanjant kullanın Galibiyet tarafı Ne kadar büyük.
Kod şuna benzer-
1 sınıf ValueNet (nn.Modül):
2 def __içinde__ (kendisi, uçaklar, dış uçlar):
3 süper (ValueNet, self) .__ init __ ()
4 self.outplanes = outplanes
5 self.conv = nn.Conv2d (düzlem içi, 1, kernel_size = 1)
6 self.bn = nn.BatchNorm2d (1)
7 self.fc1 = nn.Linear (dış düzlemler-1, 256)
8 self.fc2 = nn.Linear (256; 1)
9
10
11 def ileri (öz, x):
12 x = F.relu (self.bn (self.conv (x)))
13 x = x.view (-1, self.outplanes-1)
14 x = F.relu (self.fc1 (x))
15 kazanan = F.tanh (self.fc2 (x))
16 dönüş kazanan
Dog Zero'nun çok önemli başka bir kısmı daha var. Monte Carlo Ağacı Arama (MCTS).
AI satranç oyuncuları yapabilir önceden En yüksek kazanma yüzdesine sahip yeri bulun.
Simülatörde, rakibin bir sonraki hamlesi simüle edilir ve bir sonraki hamle karşı önlemler vermek için verilir, bu yüzden ilerleyin Bir adımdan daha fazlası .
Düğüm
Ağaçtaki her düğüm farklı bir durumu temsil eder ve farklı istatistiklere sahiptir:
Her bir düğümün geçme sayısı n, toplam eylem değeri w, bu noktayı geçme olasılığı p, ortalama eylem değeri q (q = w / n) ve başka bir yerden düğüm O adım Ve bu düğümden başlayarak, tüm mümkün Sonraki adım .
1 sınıf Düğüm :
2 def __içinde__ (öz, ebeveyn = Yok, proba = Yok, hareket = Yok):
3 self.p = proba
4 self.n = 0
5 self.w = 0
6 self.q = 0
7 self.children =
8 self.parent = ebeveyn
9 self.move = hareket
Dağıtım (Kullanıma Sunma)
İlk adım, PUCT (Polinom Güven Ağacı) algoritmasıdır. PUCT işlevinin bir varyantını seçin (aşağıda) maksimize etmek , Gidilecek yol.
Kod olarak yazılırsa-
1 def seç (düğümler, c_puct = C_PUCT):
2 "PUCT formülüne dayalı olarak seçimin optimize edilmiş versiyonu"
3
4 total_count = 0
5 için ben içinde aralık (nodes.shape):
6 toplam_sayı + = düğüm
7
8 action_scores = np.zeros (nodes.shape)
9 için ben içinde aralık (nodes.shape):
10 eylem_ skoru = düğümler + c_puct * düğümleri * \
11 (np.sqrt (toplam_sayı) / (1 + düğüm ))
12
13 eşittir = np.where (action_scores == np.max (action_scores))
14 Eğer equals.shape > 0:
15 dönüş np.random.choice (eşittir)
16 dönüş eşittir
Bitirme
Seçim, bir yaprak düğüme (Yaprak Düğümü) ulaşıncaya kadar devam eder ve bu düğüm henüz dallanmamıştır.
1 def is_leaf (kendi):
2 "" "Bir düğümün yaprak olup olmadığını kontrol edin" ""
3
4 dönüş len (self.children) == 0
Yaprak düğümüne, oralardan biri Rastgele durum Değerlendirilecek ve tüm "sonraki adımların" olasılıkları türetilecektir.
Tüm yasaklı yerleştirme noktaları için olasılık sıfır olacak ve ardından toplam olasılık 1'e düşürülecek.
Daha sonra, bu yaprak düğümü dalları doğuracaktır (hepsi çocuğun yerleştirilebileceği konumlardır ve olasılık sıfır değildir). kod aşağıdaki gibi gösterilir -
1 def genişletmek (self, probas):
2 self.children =
Güncelleme
Dallar doğduktan sonra yaprak düğümü ve anneleri, İstatistiksel veri Aşağıdaki iki kod dizisi kullanılarak güncellenecektir.
1 def Güncelleme (öz, v):
2 "" "Bir kullanıma sunulduktan sonra düğüm istatistiklerini güncelleyin" ""
3
4 self.w = self.w + v
5 self.q = self.w / self.n Eğer self.n > 0 Başka 0
1 süre current_node.parent:
2 current_node.update (v)
3 akım_dodu = geçerli_od.parent
Simülatör kurulur ve her olası "sonraki adımın" kendi istatistikleri vardır.
Bu verilere göre, algoritma seç Bir adım, gerçekten gitmek istediğiniz yerdir.
İki seçenek vardır, biri en çok simüle edilen noktayı seçmektir. Test ve gerçek mücadele için deneme.
Diğeri, Stokastik olarak seçer, düğüm geçilir Sıklık Bir olasılık dağılımına dönüştürülen aşağıdaki kod kullanılır
1 toplam = np.sum (action_scores)
2 probas = action_scores / toplam
3 hareket = np.random.choice (action_scores.shape, p = probas)
İkincisi, AlphaGo'nun daha olası seçenekleri keşfetmesine olanak tanıyan eğitim için uygundur.
Gou Lingin pratiği üç sürece ayrılmıştır: asenkron nın-nin.
Biri Kendi kendine oyun (Self-Play), veri oluşturmak için kullanılır.
1 def self_play ():
2 süre Doğru :
3 new_player, kontrol noktası = load_player ()
4 Eğer yeni oyuncu:
5 oyuncu = new_player
6
7 ## Süreçlerin kendi kendine oynanan maç sırasını oluşturun
8 sonuç = create_matches (oyuncu, çekirdekler = PARALLEL_SELF_PLAY,
9 eşleşme_sayısı = SELF_PLAY_MATCH)
10 için _ içinde aralık (SELF_PLAY_MATCH):
11 sonuç = results.get ()
12 db.insert ({
13 "oyun": sonuç,
14 "id": game_id
15})
16 game_id + = 1
iki Eğitim (Eğitim), mevcut sinir ağını iyileştirmek için yeni oluşturulmuş verileri kullanın.
1 def tren ():
2 kriter = AlphaLoss ()
3 veri kümesi = SelfPlayDataset ()
4 oyuncu, kontrol noktası = load_player (geçerli_zaman, yüklenen_sürüm)
5 optimize edici = create_optimizer (player, lr,
6 param = kontrol noktası)
7 best_player = derin kopya (oyuncu)
8 dataloader = DataLoader (veri kümesi, collate_fn = collate_fn, \
9 batch_size = BATCH_SIZE, karıştır = Doğru )
10
11 süre Doğru :
12 için batch_idx, (durum, taşıma, kazanan) içinde numaralandır (dataloader):
13
14 ## Mevcut ağın bir kopyasını değerlendirin
15 Eğer total_ite% TRAIN_STEPS == 0:
16 pending_player = derin kopya (oyuncu)
17 sonuç = değerlendirme (pending_player, best_player)
18
19 Eğer sonuç:
20 best_player = pending_player
yirmi bir
22 örnek = {
23 'durum': eyalet,
24 'kazanan': kazanan,
25'move ': hareket et
26}
27 optimizer.zero_grad ()
28 kazanan, probas = pending_player.predict (örnek)
29
30 kayıp = ölçüt (kazanan, örnek, \
31 proba, örnek)
32 kayıp geri ()
33 optimizer.step ()
34
35 ## Yeni oyunları getir
36 Eğer total_ite% REFRESH_TICK == 0:
37 last_id = fetch_new_games (koleksiyon, veri kümesi, last_id)
Eğitim için Kayıp işlevi Şöyle ifade edilir:
1 sınıf AlphaLoss (torch.nn.Module):
2 def __içinde__ (kendi):
3 süper (AlphaLoss, self) .__ init __ ()
4
5 def ileri (self, pred_winner, kazanan, pred_probas, probas):
6 value_error = (kazanan-pred_winner) ** 2
7 policy_error = torch.sum ((- probas *
8 (1e-6 + pred_probas) .log ()), 1)
9 total_error = (value_error.view (-1) + policy_error) .mean ()
10 dönüş total_error
Üç Değerlendirme (Değerlendirme), eğitimli temsilcinin veri oluşturan aracıdan daha iyi olup olmadığına bakın (en iyiler ilk adıma geri döner ve veri oluşturmaya devam eder)
1 def değerlendirmek (oyuncu, yeni_oyuncu):
2 sonuç = oyun (oyuncu, rakip = yeni_oyuncu)
3 black_wins = 0
4 white_wins = 0
5
6 için sonuç içinde Sonuçlar:
7 Eğer sonuç == 1:
8 white_wins + = 1
9 elif sonuç == 0:
10 black_wins + = 1
11
12 ## Eğitimli oyuncunun (siyah) şundan daha iyi olup olmadığını kontrol edin
13 ## eşiğe bağlı olarak mevcut en iyi oyuncu
14 Eğer black_wins > = EVAL_THRESH * len (sonuçlar):
15 dönüş Doğru
16 dönüş Yanlış
Üçüncü kısım çok önemlidir. Devam etmek İçin en iyi ağı seçin Devam etmek Yapay zekanın satranç becerileri yalnızca yüksek kaliteli veriler oluşturarak geliştirilebilir.
Üç bağlantı Defalarca , Güçlü bir satranç oyuncusu geliştirmek için.
Xiaodi, AI satranç oyuncularını eğitmek için okulun sunucusunu kullandı Bir hafta .
SuperGo hala genç ve 9x9'luk bir tahtada eğitilmiş.
Xiaodi, yapay zekasının henüz anlamadığını söyledi. Yaşam ve ölüm Şey, ama Go'nun bir Kara kapma Tekrar oyun.
Hiçbir süper yetenekli satranç oyuncusu eğitilmemiş olsa da, bu girişim hala kutlanmaya değer.
Reddit'teki meslektaşlarından da tebrik mesajları var.
Umut verici anlam
AI Go ile ilgilenenler bunu da deneyebilir PyTorch başarmak.
Portalı uygulamak için kod:
https://github.com/dylandjian/SuperGo
Eğitim metni portalı:
https://dylandjian.github.io/alphago-zero/
AlphaGo Zero tez portalı:
https://www.nature.com/articles/nature24270.epdf
Dün (2 Ağustos) Ke Jie'nin doğum günüydü.
- Bitiş -
Samimi işe alım
Qubit, editörleri / muhabirleri işe alıyor ve merkezi Pekin, Zhongguancun'da bulunuyor. Yetenekli ve hevesli öğrencilerin bize katılmasını dört gözle bekliyoruz! Ayrıntılar için, lütfen QbitAI diyalog arayüzünde "işe alım" kelimesiyle yanıt verin.
Qubit QbitAI · Toutiao İmzalayan Yazar
' ' Yapay zeka teknolojisi ve ürünlerindeki yeni eğilimleri takip edin