Em 2018, o Google venceu o Campeão de GO com sua Rede Neural AlphaGo, e houve tanta repercussão. Novas e excelentes bibliotecas de Aprendizado de Máquina de código aberto se tornaram disponíveis, usando GPUs domésticas para acelerar o processo de treinamento.
Tomei a decisão de tentar fazer isso com o Abak, mas quando comecei, mal sabia o que era uma rede neural. Tive uma pequena tentação na faculdade (1996), mas sem dados, GPU e um objetivo, era complexo abordar. Além disso: matematicamente, Redes Neurais é um assunto pesado, e você precisa de muita inspiração.
Após muita pesquisa intensa e obsessiva, consegui construir um modelo e fazê-lo aprender.
Sobre os ombros de gigantes, minha primeira intenção foi aprender com o Dr. Gerald Tesauro, que desenvolveu o TD-Gammon nos anos 90. Se me lembro corretamente, esta foi a primeira implementação prática de um algoritmo de aprendizado por reforço.
Mas como o Abak é um jogo bidimensional, não pude usar o modelo proposto e tive que desenvolver o meu próprio. Decidi usar a saída de alguns dos algoritmos como parte do modelo, como informação especializada, para que a NN tivesse o processo de aprendizado mais fácil. Me senti trapaceando fazendo isso.
Aqui está uma comparação entre ambos os modelos, Backgammon e Abak.
O modelo TD amplamente usado do Backgammon descreve colunas. Para cada coluna do tabuleiro, 4 entradas são usadas para descrevê-la.
- Sem peças: [0,0,0,0]
- Uma peça: [1,0,0,0]
- Duas peças: [1,1,0,0],
- Três peças: [1,1,1,0]
- Mais de três peças: [1,1,1,1].
Tem 28 desses conjuntos (um por coluna do tabuleiro) para se referir a cada equipe, então 28*2*4 entradas no total, mais algumas para contar peças na barra. Infelizmente, estou escrevendo isto de memória, o que pode não ser preciso.
O modelo do Abak é muito diferente. Ele descreve peças, e cada uma tem um conjunto de características. Em versões mais novas, adicionei uma descrição simplificada do tabuleiro para complementar, com resultados que não foram incríveis, mas as características ainda estão lá.
O modelo de descrição do jogo tem quatro partes [477 entradas]:
- Descrição das Peças (14x30): A descrição inclui estatísticas da peça, distância, altura, etc. Não inclui a classe, que é herdada pela sua posição no modelo.
- Estado da Equipe (4x2): Contagem de algumas características de peças ou status.
- Mapa de força (24x2).
- Estado do jogo: quem lança em seguida! (1).
Você pode conferir uma descrição completa do modelo abaixo.
Versões:
1.- Python Cumpy (TD-V1).
A primeira versão desta IA foi treinada em Python puro usando Cumpy, uma biblioteca similar ao Numpy que roda na GPU. Eu queria aprender do zero, então mesmo tendo brincado um pouco com o Tensorflow, decidi ir sem nada (bem, equipado com a fantástica combinação Python e Cumpy).
Características:
- Uma rede que estima as chances da equipe 0 vencer o jogo.
- Sem consciência de pontos.
- Não tinha a flag "quem lança em seguida".
- Não tinha o mapa de força.
- Uma camada oculta, com ativadores sigmoid.
- Levou 45.000 jogos para vencer minha IA anterior escrita com informação especializada (GOAFI).
- Aprendeu por 4.500.000 jogos. E venceu 75% dos casos contra GOFAI.
- Ficou em produção por 2 anos.
2.- Tensorflow (TD-V2).
Minha dor com a Versão 1 era que não era boa calculando chances de vitória porque foi treinada sem a flag "quem lança em seguida". De alguma forma, os resultados da NN eram bastante bons para selecionar um bom movimento, mas matematicamente não eram consistentes. A Versão 2 corrigiu esse problema e adicionou uma nova rede para calcular as chances do jogo terminar em 1, 2 ou 3 pontos.
Escolhi Tensorflow desta vez para treinar o novo modelo porque queria aprender um framework, e encontrei um excelente exemplo para começar.
Características:
- Uma rede para calcular as chances da equipe 0 vencer o jogo.
- Uma rede para calcular a probabilidade do jogo terminar em 1, 2 ou 3 pontos.
- Inclui o novo mapa de força.
- Duas camadas ocultas, com diferentes ativadores: Leaky RELU para as camadas ocultas e sigmoid na camada de saída.
- Levou 12.000 jogos para vencer 50% das vezes contra TD-V1.
- Aprendeu por 350.000 jogos e alcançou uma taxa de vitória de 80% contra TD-V1.
3.- Versão 3: Em Espera.
Como a milha final na tomada de decisão de selecionar o melhor movimento, há um algoritmo simples que busca a melhor Equidade [%W*%p1+%W*%p2+%W*%p3].
Dependendo do objetivo da partida, do número de pontos necessários para cada jogador vencer, e do valor do dado, ele pondera a saída das redes de forma diferente.
Gostaria de fazer uma NN que lide com isso. Essa será a V3. Não está em desenvolvimento agora.
Modelo da Rede Neural do Abak:
Descrição da Peça (14 entradas x 30 peças):
- Distância até casa x/25
- Quantidade de peças acima x/4
- Quantidade de peças abaixo x/4
- Está na barra [0,1]
- Está em casa [0,1]
- Está segura (a distância = 0). [0,1]
- Está fazendo um bloqueio com outra peça [0,1]
- Pode ser aprisionada pelo druida [0,1]
- Está aprisionada pelo druida [0,1]
- Está aprisionando (esta entrada é apenas para cada druida) [0,1]
- Risco de ser capturada na zona próxima (6 posições à frente) [0..1]
- Risco de ser capturada na zona distante (12 posições à frente) [0..1]
- Risco de ser aprisionada pelo druida [0..1]
- Chances de movimento [0..1]
Entrada relacionada ao jogo para cada equipe (4x2):
- Quantidade de peças na barra. x/15
- Quantidade de peças seguras. x/15
- Todas as peças estão em casa. [0,1]
- Quantidade de peças seguras 0. [0,1]
Mapa de Força: (24*2):
Por último, um mapa de força, similar ao que o Doutor Tesauro propôs para o Backgammon, mas simplificado. Para cada posição e para cada equipe, tem um número entre 0 e 1, representando quão forte aquele bloqueio é:
- 0.0se vazio.
- 0.1se há uma peça.
- 0.5se essa peça é um guarda.
- 1.0se duas ou mais peças estão lá.