Inicio     |     Sobre     |     GitHub     |     Games     |     Contato                        

sexta-feira, 15 de março de 2019

Resumo Semanal de Pesquisa: Project Malmo e Jogos para Aplicar Inteligencia Artificial



    Essa semana foi iniciada com um estudo mais aprofundado de ferramentas e ambientes para a aplicação de um agente cognitivo. Durante as leituras feitas, foi reforçada a ideia de que os jogos são excelentes ambientes para a aplicação de sistemas inteligentes. Por isso tem surgido um numero considerável de aplicações que permitem o uso de jogos como ambientes para o teste de sistemas inteligentes.


A Inteligencia Artificial em Jogos Atuais


    Vale ressaltar que a importância da inteligencia artificial (IA) para o desenvolvimento de jogos mais inteligentes e atrativos tem se tornado a cada dia maior. É interessante citar o exemplo do uso da inteligencia artificial no jogo Assassin's Creed Origins. No jogo os NPCs (Personagens não controlados por jogadores), diferente da maioria dos jogos, estão em constante funcionamento, mesmo quando o jogador não está por perto. É como se continuassem sua vida, seu cotidiano, eles possuem objetivos básicos que procuram estar sempre sendo cumpridos pelo sistema inteligente implementado. Isso é muito interessante pois gera situações no jogo completamente fora do roteiro, que pode tornar a experiencia de jogo unica para cada jogador. Um exemplo acontece quando um grupo de animais carnívoros sentem fome e atacam um acampamento onde o jogador precisava se infiltrar, criando uma situação que de certa forma auxilia o jogador em seu objetivo e o faz expectador de uma situação unica que não foi programada para acontecer.

    Em jogos realistas como GTA (Grand Theft Auto) a inteligencia artificial é de extrema importância para dar a sensação de mundo real ao jogo, principalmente quando o jogador interage com um NPC. Jogos que oferecem liberdade, como por exemplo, o próprio GTA 5 ou os jogos The Elder Scrolls V Skyrim, The Sims 4 ou Black Desert tem a IA como fator importante para tentar garantir um maior realismo ao jogo, fazer com que os NPCs e inimigos (humanos, animais ou monstros) hajam não só de forma inteligente mas também natural. Já jogos de estratégia como os MOBA (e.g. League of Legends e Dota 2) e RTS (e.g. StarCraft) usam a IA para tornar o jogo mais desafiador e também para auxiliar o jogador no seu processo de aprendizado, podendo usar os sistemas inteligentes para se adaptar ao nível do jogador ou para jogar de forma mais inteligente.

    É interessante citar também os casos dos jogos Minecraft e No Man's Sky. Minecraft é um jogo de sucesso, onde sua liberdade dentro do jogo e a não existência de um objetivo obrigatório tornou o jogo um grande atrativo. São poucas as interações dentro do jogo, fora do modo multplayer o jogador pode interagir com o ambiente, com os animais e inimigos e com os chamados Village, que são como moradores do mundo de minecraft. Essa interação é extremamente básica, animais agressivos atacam o jogador e podem persegui-lo, animais não agressivos fogem quando atacados, com o alimento correto o jogador pode atrair determinados animais e até domesticá-los, os inimigos atacam o jogador e os Village podem se mover, construir e destruir blocos e trocar itens com o jogador. Ainda sem uma história complexa por trás do jogo, e sem uma interação realista ou desafiadora com os NPCs o jogo é o sucesso que se tornou. 


    No Man's Sky é um jogo mais recente, que apresentou uma ideia inovadora que lembra muito Minecraft em alguns aspectos (como o da liberdade e da falta de um objetivo obrigatório) mas que foi ainda mais longe, Mundos infinitos (ou quase), o jogo oferece um ambiente imenso em que seria impossível para uma pessoa explorar cor completo antes do nosso sol se apagar (literalmente). Nesse jogo também foi oferecida a garantia de não repetição, todos os planetas são gerados randomicamente no momento em que são descobertos (não só os planetas mas também os animais e as plantas), logo foi prometido que seria quase impossível uma pessoa ver animais ou vegetação iguais em diferentes planetas. Por fim, o Hype para o lançamento do jogo foi grande, porém com ele veio a decepção. O jogo trouxe basicamente tudo o que prometeu, então o que faltou? Talvez a falta de uma história e de objetivos não tenha sido a melhor fórmula para esse jogo, talvez a dificuldade de se encontrar com outro jogador por conta da imensidão do jogo, talvez pela falta de possibilidades de iteração maior com NPCs ou talvez de uma inteligencia maior por parte dos NPCs que era possível se comunicar. O jogo entregou um novo modelo, uma nova formula que se estudada pode trazer inovação e jogos de muito sucesso.

Games como Ambientes/Playground para Inteligencia Artificial


      Não é só a inteligencia artificial que auxilia os jogos no seu desenvolvimento, o contrário também acontece. Jogos digitais vem auxiliando a IA em seu desenvolvimento, e também vem se mostrando excelentes ambientes para essa aplicação. Alguns dos jogos que já se tornaram ambientes para aplicação de sistemas inteligentes foram Minecraft, GTA 5 e StarCraft (ver links no final do texto). Veja mais sobre ambientes de aplicação de sistemas inteligentes nessa publicação <>.

      Empresas de grande nome como Google, DeepMind e Microsoft já entraram nesse novo campo de exploração. E essa atenção que esse novo campo de pesquisa tem conquistado gerou até mesmo competições e desafios que oferecem bons prêmios aos vencedores.

    Sentdex é um youtuber que produz conteúdo relacionado a linguagem de programação Python, Deep Learning e Machine Learning <https://www.youtube.com/user/sentdex>. Ele chamou a atenção após aplicar um sistema inteligente em um carro no jogo GTA 5. O carro autônomo foi colocado para treinar e aprender a dirigir evitando colisões, os videos podem ser vistos aqui <https://www.youtube.com/playlist?list=PLQVvvaa0QuDeETZEOy4VdocT7TOjfSA8a>.



     O SSCAIT (Student StarCraft AI Tournament) é um evento educacional, realizado desde 2011, cujo objetivo é disponibilizar um ambiente competitivo e desafiador (focando em estudantes) para competições de inteligencia artificial. Usando como ambiente do jogo StarCraft, são desenvolvidos bots programados em C ++ ou Java (usando o BWAPI) para jogar partidas 1v1, mais sobre esse evento pode ser visto em <https://sscaitournament.com/>.

      O project Malmo é uma API que permite o desenvolvimento de agentes inteligentes aplicados ao ambiente do jogo Minecraft <https://github.com/Microsoft/malmo/>. Também já foram realizadas competições e desafios colaborativos envolvendo o projeto, e esse vem crescendo e tomando lugar não apenas entre estudantes e entusiastas mas também entre cientistas que buscam testar e aprimorar seus sistemas.


       As competições geraram um material que pode auxiliar muitos pesquisadores, desde artigos (alguns dos quais estão presentes nos links no final desse texto) até uma variedade de ambientes e experimentos já prontos para a aplicação de agentes, como é possível observar nessas páginas <https://github.com/crowdAI/marLo>, <https://github.com/kuri8ive/Deep-Reinforcement-Learning-Hands-on-by-Minecraft-with-ChainerRL/blob/master/README.md>.



Project Malmo


    Project Malmo se mostrou uma das ferramentas mais apropriadas para a aplicação do sistema cognitivo devida a liberdade de criação de objetivos e experimento que a mesma oferece, mas nada impede que mais a diante sejam usados outros ambientes para novos testes. A API oferecida também possui bons tutoriais que ajudam a entender como a ferramenta funciona, e também possui suporte e uma comunidade que busca explorar as possibilidades do projeto.

    Para iniciarmos nossos estudos da ferramenta foram (estão sendo) lidos trabalhos relacionados que usam a ferramenta com intuitos similares, e foram seguidos os tutoriais e exercícios propostos para se familiarizar com a ferramenta, esses tutoriais estão disponíveis no arquivo <http://microsoft.github.io/malmo/0.14.0/Python_Examples/Tutorial.pdf>, eles dão uma noção básica geral do funcionamento do Malmo, ensinando como controlar o agente e como modificar o ambiente e criar missões.

DICA: É possível controlar e jogar com o agente normalmente como no jogo Minecraft. Também é possível o uso de comandos como por exemplo /time set 1000 para tornar dia (apertando a tecla "t" para abrir a caixa de texto).

   Para baixar e usar o Project Malmo de forma simples basta seguir as instruções nesse links <https://github.com/Microsoft/malmo#getting-started>.

   Uma vez que o arquivo foi baixado e está funcionando normalmente basta rodar seguindo as instruções a baixo:

cd Minecraft 
launchClient.bat (Windows) 
./launchClient.sh (Linux ou MacOSX)

OBS: Os experimentos do tutorial estão na linguagem de programação Python, estarei usando a linguagem Java no meu projeto, mas como meu conhecimento em ambas é quase o mesmo acredito que não há problemas nisso.

   O primeiro experimento apresentado é simples, já com o Cliente do Minecraft rodando, ao executar o arquivo tutorial_1.py pode-se observar que o agente é gerado no ambiente, a simulação dura alguns segundos e nada além disso acontece.

  Ao inserir os códigos apresentados no tutorial é possível ver finalmente o agente fazendo movimentos enquanto dura a execução. É possível testar e brincar com esses códigos e ver como funciona cada um deles, como o agente age conforme a disposição das ações inseridas no código.

#Codigos apresentados
agent_host.sendCommand("move 1")
agent_host.sendCommand("turn -0.5")
agent_host.sendCommand("jump 1")
agent_host.sendCommand("pitch 1")
time.sleep(1)
agent_host.sendCommand("attack 1")


As ações possíveis apresentadas nesse ponto podem ser dispostas em uma tabela da seguinte maneira:


OBS: Os valores que são entre -1 e 1 se referem a velocidade, onde quanto mais próximo de 1 ou -1 maior será a velocidade e quanto mais próximo de 0 (e.g. 0.03) menor será a velocidade.


Vídeo do experimento: <https://youtu.be/mNO6hCFJM34>

A segunda etapa (tutorial_2.py) do tutorial diz respeito a edição do ambiente usando o XML, o primeiro passo é editar a linha de código <FlatWorldGenerator generatorString="3;7,220*1,5*3,2;3;,biome_1"/> para deixar o ambiente diferente ou mais interessante.

DICA: Uma excelente ferramenta que pode ser usada para facilitar o processo de criar strings do ambiente é o Chunkbase <https://chunkbase.com/apps/superflat-generator#3;7,2*3,2;1;village>.

Em seguida setamos o tempo do servidor para sempre estar anoitecendo, para isso usamos o seguinte trecho de código:

<ServerInitialConditions>
        <Time>
                <StartTime>12000</StartTime>
                <AllowPassageOfTime>false</AllowPassageOfTime>
        </Time>
</ServerInitialConditions>

Em seguida setamos a posição inicial do agente para que ele sempre apareça olhando para o por do sol:

 <AgentStart>
         <Placement x="0" y="56" z="0" yaw="90"/>
 </AgentStart>

E por fim mudamos a condição do ambiente para que sempre esteja "chovendo" (Lembrando que em biomas frios ao invés de chuva oq eu se vê é neve).

<Weather>rain</Weather>

O código final será parecido com o seguinte:



DICA: Ctrl + C termina um processo. F5 Altera a visão do pesquisador em relação ao agente e F3 exibe os dados da simulação na tela.

Agora ainda no mesmo código é sugerido usar o trecho de código a seguir, e o que acontece é mostrado na imagem:

<DrawingDecorator>
     <DrawSphere x="-27" y="70" z="0" radius="30" type="air"/>
</DrawingDecorator>



O DrawingDecorator permite criar formas primitivas de blocos no Minecraft, sendo que essas formas primitivas podem ser:

<DrawCuboid x1, y1, z1, x2, y2, z2, type/>
<DrawLine x1, y1, z1, x2, y2, z2, type/>
<DrawBlock x, y, z, type/>
<DrawSphere x, y, z, radius, type/>
<DrawItem x, y, z, type/>

O próximo passo será feito no tutorial_3.py
Assim como no jogo aqui também é possível o uso do inventário pelo agente, para dar um item ao agente desde o inicio do jogo é preciso adicionar a seguinte linha ao AgentStart, após o nó Placement:

<Inventory>
<InventoryItem slot="0" type="diamond_pickaxe"/>
</Inventory>


Existem 40 slots de inventário no Minecraft, numerados de 0 a 39 sendo que:

  • 0-8 são os slots “hotbar” - eles são exibidos no HUD e podem ser selecionados pelo agente usando o comando “hotbar.x” fornecido pelo InventoryCommands;
  • 9-35 são as três linhas de itens visíveis no menu de inventário do jogador (pressione <E> dentro do jogo para ver isso);
  • 36-39 são os slots que guardam os equipamentos usados (por exemplo, diamond_helmet, etc);
OBS: Os slots são indexados em 0, mas os comandos de tecla são indexados em 1, dessa forma, para selecionar o slot 8, a sequência de comandos seria:

agent_host.sendCommand (“hotbar.9 1”) # pressione a tecla
agent_host.sendCommand (“hotbar.9 0”) # libera a tecla

DICA: Nesse momento o slot 39 será ignorado, mas para saber mais, consulte os gerenciadores de missão ObservationFromFullInventory, ObservationFromHotBar e InventoryCommands.

DESAFIO PROPOSTO:
Execute tutorial_4.py. No centro, há um bloco de diamante. Usando o que já sabemos, você consegue fazer seu agente chegar lá antes que o tempo acabe?
(Isso pode ser feito com sete linhas de código.)

Resolução:

Levando em conta que nesse ponto ainda não sabemos como o agente vê os objetos no ambiente para saber quando há um cubo bloqueando seu caminho e quando ele chegou ao bloco de diamante. Sabemos pela imagem do experimento executado (sem modificação) que ele possui uma picareta que poderá usar para quebrar os cubos em seu caminho, e que haverá cubos, porém não sabemos exatamente quando.


Então seguindo a instrução anterior, primeiro vamos equipar a picareta que está no slot 9:

agent_host.sendCommand("hotbar.9 1")
agent_host.sendCommand("hotbar.9 0")

Vamos adicionar um movimento para frente para ver o que acontece:

agent_host.sendCommand("move 1")

Conforme é possível observar no vídeo o agente equipa a picareta e anda para frente, mas logo é bloqueado por um bloco. Precisamos destruir esse bloco, não há problema algum em adicionar ataques a cada movimento, porém como ele está olhando para frente, provavelmente atacará o ar, para fazermos que o agente olhe para baixo e ataque a cada passo vamos usar os comandos pitch e attack, da seguinte forma antes do move:

agent_host.sendCommand("pitch 0.3")
time.sleep(1)
agent_host.sendCommand("pitch 0")
agent_host.sendCommand("attack 1")
agent_host.sendCommand("move 1")

Repare que o time.sleep é usado para dar um tempo para que o agente abaixe a câmera e em seguida pare o movimento. Esse é o código final:




Ainda nesse exemplo é possível observar que o experimento pode ser finalizado de duas formas diferentes, a primeira é pelo tempo e a segunda é quando o agente chega ao bloco de diamante, ambas definições estão no XML respectivamente nas seguintes linhas:

<ServerQuitFromTimeUp timeLimitMs="30000"/>

<AgentQuitFromReachingPosition>
 <Marker x="-26.5" y="40" z="0.5" tolerance="0.5" description="Goal_found"/>
 </AgentQuitFromReachingPosition>

Uma maneira alternativa apresentada seria finalizar a simulação quando o agente toca em um determinado tipo de bloco, segue um exemplo:

<AgentQuitFromTouchingBlockType>
           <Block type="diamond_block" />

</AgentQuitFromTouchingBlockType>

A missão também termina quando o agente morre. Agora vamos passar para o próximo exercício (tutorial_5.py), onde é possível observar uma possível solução para o desafio anterior comentado, vamos usar esse  código apresentado.


Ao executar vemos que o ambiente mudou, agora temos lava ao redor do nosso objetivo e o agente morre queimado pela lava quando quebra o bloco que o separa da mesma, como isso pode ser evitado?


A forma que o tutorial apresenta de auxiliar nessa missão é usar o ObservationFromGrid no XML, esse é responsável por permitir que o agente consiga ver o que há a sua volta, no formato de um array JSON que carregam a informação dos tipos de objetos a sua volta. O código presente nesse exemplo é o seguinte:

<ObservationFromGrid>
         <Grid name="floor3x3">
                 <min x="-1" y="-1" z="-1"/>
                 <max x="1" y="-1" z="1"/>
         </Grid>
</ObservationFromGrid>

Ele permite a visão de até 3 cubos ao seu redor (3x3).

DESAFIO PROPOSTO:
Faça com que o agente chegue a seu objetivo (bloco de diamante) evitando cair na lava:

Resolução:
Parte da resolução já está no código, agora só precisamos cuidar da parte lógica par fazer tudo funcionar. Digamos que queremos que o agente pule a lava quando ver em sua frente:


O que foi feito no código? Foi criado uma variável pulo e levando em consideração a visão 3x3 e a explicação dada anteriormente no tutorial sobre a direção do personagem e a posição 3 do grid ser o objeto a sua frente, então:

se pulo for verdadeiro e o que tem em baixo (grid[4]) não é lava:
   então para de pular
se o que tem a frente (grid[3]) for lava:
   então pular



tutorial_6.py

Até o momento todas as atividades realizadas pelo agente foram estáticas ou continuas, a inteligencia artificial muitas vezes pode assumir ações dinâmicas. Com isso o próximo passo mostra como criar um ambiente de experimento que possibilite a aplicação de um sistema mais elaborado.

OBS: Nessa etapa o XML se encontra em um arquivo separado do código tutorial_6.py.


No XML desse experimento podemos observar o uso dos seguintes comandos:

  • <DiscreteMovementCommands /> Faz com que o agente se mova um bloco de cada vez;
  • <RewardForTouchingBlockType> O agente recebe 100 pontos de recompensa quando toca um bloco de lápis-lazúli e recebe -100 por tocar a lava;
  • <RewardForSendingCommand> Para cada comando executado pelo agente ele recebe -1 de recompensa, assim quanto menos comandos, melhor;
Também há novidades no código presente no arquivo tutorial_6.py:

Nesse primeiro trecho de código o arquivo XML é carregado:

mission_file = './tutorial_6.xml'
with open(mission_file, 'r') as f:
   print "Loading mission from %s" % mission_file
   mission_xml = f.read()
   my_mission = MalmoPython.MissionSpec(mission_xml, True)

Uma vez que o arquivo XML foi carregado é possível modifica-lo diretamente pela API como mostra esse exemplo:

# add 20% holes for interest
for x in range(1,4):
   for z in range(1,13):
   if random.random()<0.1:
   my_mission.drawBlock( x,45,z,"lava")

Já a linha de código a seguir mostra como executar um experimento (ou missão) repetidas vezes:

for i in range(num_repeats):

Ao executarmos esse experimento podemos observar um novo ambiente, e a simulação sendo executada repetidas vezes. O ambiente aqui é um corredor de areia com um bloco azul quase no final, há lava em volta e em alguns blocos no meio do corredor. Após alguns testes já é possivel observar o agente aos poucos aprendendo a chegar mais longe sem cair na lava.



    O final do tutorial e dos desafios juntamente com as continuações do projeto seguem no resumo da semana que vem, até lá!

    Para saber mais e ter um melhor domínio sobre a ferramenta aconselho a leitura e execução dos exercícios propostos no tutorial <http://microsoft.github.io/malmo/0.14.0/Python_Examples/Tutorial.pdf>.

Próximos passos:
  • Finalizar tutoriais do Project Malmo
  • Definir e construir os experimentos do projeto.
  • Definis quais dados serão coletados.
  • Definir como será feita a análise desses dados. 
  • Iniciar o estudo aprofundado da arquitetura cognitiva usada.

Links e Referências:

GTA 5 e Sentdex

StarCraft ambientes e competições

Project Malmo e Marlo

Outros

Pesquisar e ler:

DeepStack: Expert-level artificial intelligence in heads-up no-limit poker


Nenhum comentário:

Postar um comentário