Este foi um projeto de aprendizagem como uma introdução ao aprendizado de máquina. Ele usa redes neurais e um algoritmo genético para desenvolver comportamentos de direção e prevenção de obstáculos para personagens de IA. Este comportamento seria aplicado, por ex. um jogo ou simulação onde um personagem precisa evitar obstáculos de forma autônoma para chegar a um destino. Também funciona bem como um padrão errante geral.
Começa a funcionar bem em 20 gerações e se torna muito eficaz por volta de 50.
Os atores lançam 9 raios para frente e para os lados, agindo como “apalpadores”. Eles são alimentados na rede como entradas, junto com a velocidade e um multiplicador para a distância do raio. Duas camadas ocultas são usadas e três saídas. Eles consistem em velocidade, ângulo de giro e multiplicador da distância do sensor.
Uma captura de tela de depuração mostrando sensores em diferentes comprimentos:
Quando o comprimento do apalpador é reduzido, a distância lateral entre as pontas das linhas é menor, o que permite detectar e navegar em espaços mais apertados. Quando aumentado, permite detectar obstáculos mais distantes, permitindo que o tempo diminua a velocidade. Combinado com a velocidade como mais uma entrada, eles praticamente nunca ficam presos em espaços apertados ou ficam paralisados ​​ao entrar em um local onde todos os obstáculos são equidistantes.
Em outras palavras, eles se movem naturalmente e não tropeçam em obstáculos difíceis. Pelo menos para o ambiente apresentado nesta demonstração. Trabalhei em muitas iterações antes de decidir por essa topologia.
A aprendizagem é supervisionada, com um algoritmo genético com uma função de aptidão de “duração da jornada”. Este é o terreno único e não repetitivo que um ator percorre durante cada geração. É calculado explorando a praticidade do mecanismo de física do Unity – uma grade de volumes de gatilho é disposta no mapa, e avançar através de um (e não para trás) aumenta a duração da jornada. Um gatilho não pode ser coberto duas vezes na mesma geração. Isto impede a seleção de atores que simplesmente giram em círculos.
Por que pequenos BB8s?
Fiquei satisfeito com o comportamento complexo que a rede foi capaz de lidar. O movimento é criado com o mecanismo de física do Unity, portanto, há variáveis ​​de atrito estático/dinâmico e impulso para lidar. Fiz algumas compensações no código, mas fiquei satisfeito porque a topologia da rede se prestou bem à criação de um comportamento bastante dinâmico e confiável. A primeira iteração do projeto foi apenas 2D, construída com espaços reservados que não eram agradáveis ​​à vista. Um tempo antes eu havia escrito um controlador de personagem BB8 para Unity, apenas como um projeto divertido. Achei que seria divertido fazer esse projeto em 3D, e isso foi um acessório conveniente. Embora a detecção de acertos seja restrita a um plano 2D, a adição do momento angular de um personagem rolante tornou o problema muito mais complicado.
A primeira iteração usou apenas uma camada oculta e teve um comportamento eficaz, mas simplista. Eles moviam-se em padrões previsíveis que eram eficazes, mas não muito naturais. Eles mudavam de direção com frequência, como se fossem um esquilo altamente indeciso. Usar um personagem rolante introduziu um desafio adicional que acabou tornando o comportamento muito mais natural.