Codificação de entrada / saída para uma rede neural para aprender um jogo baseado em grade

13

Estou escrevendo um jogo de brinquedo simples, com a intenção de treinar uma profunda rede neural sobre ela. As regras dos jogos são aproximadamente as seguintes:

  • O jogo tem um tabuleiro composto por células hexagonais.
  • Ambos os jogadores têm a mesma coleção de peças que podem escolher posicionar livremente no tabuleiro.
  • Colocar tipos diferentes de peças premia pontos (ou diminui os pontos do oponente), dependendo da posição e da configuração entre si.
  • Quem tiver mais pontos ganha.

Existem regras adicionais (sobre turnos, número e tipos de peças, etc ...), mas elas não são importantes no contexto desta questão. Quero criar uma rede neural profunda que possa aprender iterativamente jogando contra si mesma. Minhas perguntas são sobre representação de entrada e saída. Em particular:

  • Como o padrão das peças é importante, eu estava pensando em ter pelo menos algumas camadas convolucionais. A placa pode ser de vários tamanhos, mas em princípio muito pequena (6x10 nos meus testes, para ser expandida por poucas células). Isso faz sentido? Que tipo de pool posso usar?
  • Como representar os dois lados? No presente trabalho sobre trânsito, autores usam duas matrizes de entrada, um para as pedras brancas e um para pedras pretas. Também pode funcionar neste caso? Mas lembre-se de que tenho tipos diferentes de peças, digamos A, B, C e D. Devo usar matrizes de entrada 2x4? Parece muito escasso e de pouca eficiência para mim. Receio que seja muito escasso para as camadas convolucionais funcionarem.
  • Eu pensei que o resultado poderia ser uma distribuição de probabilidades sobre a matriz, representando as posições do tabuleiro, além de um conjunto separado de probabilidades, indicando qual peça jogar. No entanto, eu também preciso representar a capacidade de passar o turn, o que é muito importante. Como posso fazer isso sem diluir seu significado entre outras probabilidades?
  • E o mais importante , imponho apenas jogadas vencedoras ou perdidas também? A imposição de lances vencedores é fácil, porque apenas defino as probabilidades desejadas como 1. No entanto, ao perder, o que posso fazer? Defina essa probabilidade de movimento como 0 e todos os outros com o mesmo valor? Além disso, faz sentido aplicar movimentos pela diferença final de pontuação, mesmo que isso contraria o significado dos resultados, que são aproximadamente probabilidades?

Além disso, desenvolvi o mecanismo de jogo no node.js pensando em usar o Synaptic como estrutura, mas não tenho certeza de que ele possa funcionar com redes convolucionais (duvido que exista uma maneira de corrigir os pesos associados aos campos perceptivos locais). Algum conselho sobre outras bibliotecas compatíveis com o nó?

Totem
fonte
Vamos supor que você deseja que a máquina aprenda o jogo desconhecido e depois aprenda como vencê-lo? (Ao contrário de aprender a ganhar um jogo cujas regras estão disponíveis para o programador antes de escrever o software de aprendizagem de máquina)
FauChristian

Respostas:

1
  • Para representar as peças, você deve poder usar uma única matriz de entrada. Apenas designe um número inteiro para os diferentes tipos de peças. Pedras brancas podem ser números inteiros positivos e pedras pretas podem ser negativas.

  • Você pode usar sigmoid para ter confiança na posição da placa e ativação linear para o identificador da peça. pass seria outra saída sigmóide. Eu não acho que você terá que se preocupar com a diluição do passe . Por ser uma ação tão valiosa, a pontuação dependerá muito do resultado do passe e terá um grande gradiente. Se você precisar selecionar a ação de passe com alta frequência para fins de aprendizado por reforço, apenas atribua uma probabilidade maior à ação de passe em sua função de escolha aleatória.

  • A diferença de pontuação final tem um grande impacto na conveniência dos movimentos. Uma grande diferença de pontuação deve resultar em um grande impacto na função. Portanto, convém incluir a magnitude da diferença de pontuação na sua função de perda.

Esse é o tipo de trabalho que o Deep Q Learning faz. Talvez você queira investigar isso também.

Imagem padrão
fonte
1

Você não precisa de camadas de conv, pois não alimenta uma imagem como entrada (veja abaixo). Como alternativa, você pode tentar usar uma imagem do quadro (com peças diferentes com formas diferentes). Isso também pode funcionar. Então eu iria para 2 camadas conv, passo 1, tamanho do kernel igual à metade do tamanho de uma peça. Eu tentaria com um único pool máximo.

Ao contrário da outra resposta, eu sugeriria o uso de um tensor 3d como entrada, com o número de canais iguais a diferentes partes. As outras duas dimensões iguais corresponderiam ao número de células no quadro. Várias transformações no NN não serão capazes de distinguir muito bem vários números inteiros. É por isso que é melhor ter uma codificação única dos tipos de peças.

Eu usaria apenas um vetor com n + 1 componentes para saída: n para todos os movimentos possíveis e 1 para o passe. Codificaria a recompensa esperada para cada movimento, não a probabilidade.

Não sabe ao certo o que você quer dizer com a imposição de movimentos. Mas quando você treiná-lo com algo como Q-learning, faria sentido fazer um movimento completamente aleatório de vez em quando com uma certa probabilidade (digamos 10% das vezes). Pesquisa https://en.wikipedia.org/wiki/Reinforcement_learning

hellmean
fonte
Os tensores são um exagero.
FauChristian