Redes Neurais Evolucionárias
André L. N. Muniz e Cícero Augusto M. da S. Neves
Departamento de Ciência da Computação – Universidade Federal da Bahia (UFBA) Salvador – BA – Brasil
{amuniz,cicero}@im.ufba.br
Resumo. Este artigo apresenta um método para evolução de pesos e topologia de uma rede neural (chamado de NEAT), criado por Kenneth O. Stanley da University of Texas at Austin, que busca solucionar os principais problemas que são encontrados no uso de algoritmos genéticos para otimização da estrutura topológica de uma rede neural artificial. Direcionado por três princípios básicos, que serão apresentados no decorrer do artigo o NEAT se apresenta como um forte candidato a facilitar o uso de RNA's para soluções de problemas, além de dar oportunidade para o uso de RNA's de outras maneiras não pensadas anteriormente.
1. Definição do Problema
Um dos aspectos mais importantes que define o bom desempenho de uma rede neural é a sua topologia. No entanto, encontrar a melhor topologia nem sempre é uma tarefa trivial, e normalmente exige uma grande experiência sobre o problema sendo tratado. Outro fator que piora esta situação é que o conjunto de topologias válidas (isto é, topologias que resolvem o problema com algum grau de satisfação) para uma rede neural é muito grande. Além disso, é possível que duas arquiteturas semelhantes possuam desempenho bem diferentes e duas arquiteturas diferentes possuam desempenho equivalentes, tal como é afirmado em [5]. Dessa forma, muitos trabalhos são realizados no meio acadêmico para tentar se obter um método que gere automaticamente a topologia mais adequada para uma RNA. Nesta tentativa, os algoritmos genéticos se apresentam como uma boa alternativa para se obter a melhor topologia, uma vez que para utilizá-los não é necessário que se tenha conhecimento anterior do domínio problema, pois eles não requerem a priori uma análise do espaço de soluções possíveis.
2. TWEANNs (Topology and Weight Evolutionary Neural Networks)
A área que estuda a evolução das RNAs é chamada de Neuro-Evolução (NeuroEvolution). TWEANN é um tipo de rede neural que busca evoluir tanto a topologia da rede quanto os pesos das conexões. Dentro desta abordagem, alguns problemas surgem quando se tenta aplicar os conceitos de algoritmos genéticos à evolução da estrutura das RNAs, tais como a codificação mais adequada que possua representação tanto da topologia quanto das conexões e permita haver cromossomos de tamanhos diferentes, como realizar cruzamento de cromossomos que representam estruturas completamente distintas, como evitar que inovações nas estruturas se percam durante o processo de evolução e como minimizar o espaço de busca de soluções. Na próxima seção será apresentado um método para solucionar os problemas descritos anteriormente. Este método foi desenvolvido e apresentado por Kenneth Stanley da University of Texas at Austin em [1, 2 e 3].
3. NEAT (NeuroEvolution of Augmenting Topologies)
Este método é direcionado por três princípios básicos: implementação de um método para identificar estruturas homólogas (isto é, estruturas que possuem pontos em comum), proteção da inovação, através da segregação em espécies, e minimização do tamanho do espaço de busca. Nas subseções a seguir, será explicado o método NEAT a partir destes três princípios citados.
3.1. Codificação genética e mutação
Para que seja possível evoluir a topologia de uma RNA, é necessário uma codificação genética flexível. Este requisito é importante pois, para permitir que as estruturas se tornem cada vez mais complexas, o genoma deve ser dinâmico e não pode ter um tamanho fixo, senão a complexidade da sua solução poderia estar limitada ao tamanho máximo de genes no seu genoma. O genoma do NEAT possui esta flexibilidade e é composto por duas listas de genes, uma representando os neurônios e a outra as conexões. Cada gene de neurônio possui um número de identificação e uma indicação do seu tipo (entrada, oculto ou saída). Cada gene de conexão possui uma identificação global chamada Innovation Number (a ser explicado na próxima subseção), uma identificação dos neurônios que estão conectados, sendo um de entrada e outro de saída, o valor do peso e uma flag de habilitação, que indica se esta conexão deve ser representada no fenótipo (isto é, na RNA).
Figura 1. Exemplo de genoma e seu respectivo fenótipo. Figura retirada de [1].
NEAT permite haver mutações tanto nos pesos das conexões quanto na estrutura da rede, como já foi citado. Para provocar uma mutação nos pesos basta que cada um seja acrescido ou diminuído de um valor real, com uma dada probabilidade. A topologia pode sofrer dois tipos de mutação: adição de um neurônio (add Node) e adição de uma conexão (add Connection). Na mutação add Node um novo nó (neurônio) é adicionado onde antes existia apenas uma conexão e um novo gene de neurônio é criado. Dessa forma surgem duas conexões, sendo que a conexão de entrada do novo nó recebe peso igual a 1 (um) e a conexão de saída recebe o peso igual ao da antiga conexão que havia ali. Isto implica na criação de dois novos genes de conexão e a desabilitação de um gene existente no cromossomo. Já na mutação add Connection, um novo gene de conexão é criado ligando dois nós da rede, que anteriormente não estavam ligados, e o seu peso é igual a 1 (um).
Figura 2. Exemplo de mutações no NEAT. Na figura, os retângulos pequenos representam os genes das conexões. A cadeia de genes à esquerda representa o genoma antes da mutação e à direita após a mutação. Cada gene aí mostrado possui um número no topo que identifica o seu Innovation Number e outros dois números separados por uma seta que representam os nós ligados. O gene que possui a sigla “DIS” está desabilitado e não será representado no fenótipo (rede). Figura retirada de [1].
Através destas mutações, percebe-se que o tamanho dos genomas no NEAT crescem gradualmente e podem exitir diversos tipos de conexões ligando os neurônios da rede. A partir disso surge uma dificuldade de como combinar redes com topologias diferentes através do crossover de forma que a nova rede gerada seja uma rede válida, ou seja, que os seus neurônios estejam ligados corretamente e permita uma correta avaliação dessa rede. Na próxima subseção será explicado como o NEAT resolve este problema.
3.2. Reprodução (Crossover e marcação de histórico dos genes)
A solução que permite um correto crossover no NEAT é a utilização do Innovation Number. Este identificador permite um rastreamento da origem de um gene de conexão, permitindo assim saber a qual estrutura ele se refere. A atribuição do Innovation Number ocorre da seguinte maneira: quando um novo gene de conexão é criado, um contador global é incrementado e o valor resultante é atribuído a este gene. Dessa maneira, um dado gene de conexão pode ser rastreado durante toda a evolução da população. Um problema pode ocorrer deste processo se por acaso dois genes que representem a mesma ligação sejam criados na mesma geração, o que geraria uma duplicação de identificadores sem necessidade. Mas isto pode ser facilmente contornado através da manutenção de uma lista de genes criados numa dada geração. Assim, se genes idênticos forem criados na mesma geração, eles receberão o mesmo Innovation Number. Agora sabemos como combinar genes que representam a mesma estrutura topológica, pois eles possuem um identificador global. Neste artigo, um gene é dito mais velho ou mais novo do que outro se ele possui maior ou menor Innovation Number respectivamente.
Enfim, para realizar o crossover é preciso comparar os genomas dos pais entre si. Cada genoma é alinhado um contra o outro, de forma que haja uma ordem crescente do
Innovation Number – IN – (ver Figura 3). Os genes de um pai que não possuam correspondentes (mesmo IN) no outro são chamados de disjoint, caso o outro pai possua genes mais velhos, ou podem ser chamados de excess caso o outro pai não possua genes mais velhos. Os genes disjoint e excess são herdados do pai com melhor fitness, mas se este for igual, eles podem ser herdados randomicamente. Genes com o mesmo IN podem ser cruzados de duas maneiras. Na primeira, o gene passado ao filho é escolhido aleatoriamente entre os pais. Na segunda, o gene passado ao filho recebe a média do peso dos genes dos pais. NEAT utiliza estes dois métodos. Genes desabilitados têm uma chance de serem reativados nos novos indivíduos.
Figura 3. Exemplo de crossover. Figura retirada de [1].
Estas marcações do histórico dos genes permitem ao NEAT realizar o crossover sem uma análise sobre a topologia da rede, pois a compatibilidade entre as estruturas é garantida apenas pelo IN. No entanto, em [1] Stanley afirma que redes recentemente evoluídas têm inicialmente o seu fitness diminuído, mas isso ocorre apenas porque a rede ainda não teve o tempo necessário para se otimizar. Aliado a isso, ele afirma que redes menos complexas tendem a se otimizar mais rapidamente. Isto provoca o problema de que inovações em potencial podem ser perdidas caso este tempo necessário não seja dado à nova rede e ela seja superada por redes menores, que podem não levar a uma solução ótima global. Na próxima subseção, será apresentado como o NEAT resolve esse problema.
3.3. Proteção da Inovação através de segregação de espécies
O NEAT realiza a segregação das soluções existentes em uma população, em espécies. Essa segregação tem como objetivo dar tempo às inovações topológicas de aprimorarem
suas estruturas antes de terem que competir com um número maior de indivíduos.
Para realizar tal segregação, é feita uma medida de “distância histórica”, que indica o quanto em comum dois indivíduos têm historicamente. Utilizando-se as marcações de histórico dos genes, a distância ð entre dois indivíduos é medida através da seguinte equação:
ð = c1E/N + c2D/N + c3W
Onde E representa a quantidade de genes excedentes entre os dois genomas, D é a quantidade de genes disjuntos e W a diferença de pesos média entre genes que se combinam. As constantes c1, c2 e c3 servem para dar o devido peso para cada um desses elementos e N é a quantidade de genes no maior genoma.
A organização e classificação dos genomas (cromossomos) em espécies, se dá da seguinte maneira: no início do processo evolucionário, é criada a espécie de número 1 e o primeiro genoma criado é designado a ela. Os cromossomos subseqüentes são comparados com todos os outros grupos existentes. Caso a distância ð entre o genoma que está sendo comparado e o representante da espécie for menor que um limite inferior ðt, tal genoma é colocado na espécie corrente. Caso o cromossomo não se classifique em nenhuma das espécies, uma nova espécie é criada para acolher o novo indivíduo. A comparação começa pelas espécies mais antigas, o que dá a elas uma chance de receber novos indivíduos. Dessa forma, o NEAT é capaz de identificar espécies que não apresentaram melhoramentos durante muitas gerações e removê-las da população.
O NEAT faz uso da divisão de fitness explícita, onde cada indivíduo compartilha de um fitness comum ao seu nicho, evitando que uma espécie se torne muito grande ou que um indivíduo tome conta de toda uma espécie. Baseado nisto é designado a cada espécie um número máximo de descendentes que esta pode ter. Por fim, a escolha de quem vai ser parte da próxima geração é feita do seguinte modo: a fração de indivíduos que teve o pior fitness é eliminada, os pais que irão gerar novos indivíduos para a próxima geração são escolhidos aleatoriamente dos indivíduos remanescentes e o melhor indivíduo é mantido para a próxima geração.
3.4. Minimização de espaço de busca através de complexificação
A população inicial do NEAT é constituída por indivíduos com a mesma estrutura topológica (todos os nós de entrada conectados a todos os nós de saída, sem camadas ocultas), variando somente os pesos das conexões entre um indivíduo e outro, e a partir daí novas estrututras são introduzidas através da mutação.
O NEAT consegue minimizar o espaço de busca de soluções, evitando que estruturas desnecessárias sejam introduzidas na população. Isto é alcançado através do processo de complexificação, onde novas estruturas, introduzidas através da mutação, só sobrevivem casos se mostrem úteis através da avaliação de fitness.
Este processo permite que o NEAT, busque por espaços de soluções reduzidos, pois uma vez que uma nova estrutura é introduzida, os pesos das conexões já existentes já estão otimizados, sendo necessário apenas otimizar os pesos das novas conexões para que estas trabalhem bem com as já existentes, ou vice-versa. Além disso, como diferentes inovações ocorrem ao mesmo, o NEAT consegue buscar em diferentes espaços de solução simultaneamente. Por fim, como a busca pela solução tende a começar por espaços de dimensão muito grande, já próximos de atingir um objetivo, a maioria do
trabalho de busca já foi cumprido em espaços de dimensões menores, fazendo com que se tenha menos parâmetros a serem otimizados. Consequentemente o NEAT consegue realizar buscas em espaços com dimensões muito grandes de forma eficiente.
4. Conclusão
Através deste estudo, podemos concluir que a aplicação de algoritmos genéticos à evolução de redes neurais (Neuro-Evolução) é uma área que pode ainda apresentar resultados inovadores à inteligência artificial. Entre as áreas que despertam maior interesse em pesquisa estão jogos e simulações, pois envolvem processo de otimização em tempo real. Existem algumas aplicações que poderiam apresentar resultados muito interessantes, as quais são Robocode [6] e InGE [7], pois elas apresentam um ambiente no qual o NEAT poderia atuar para dar mais realiadade e portanto aumentar o grau de entretenimento.
5. Referências
[1] Stanley, K. (2004) “Efficient Evolution of Neural Networks through Complexification”, Tese de Ph.D, págs 7-41, The University of Texas at Austin. [2] Stanley, K., Miikkulainen, R. (2002) “Efficient Reinforcement Learning through
Evolving Neural Networks Topologies”, Proceedings of the Genetic and Evolutionary Computation Conference.
[3] Stanley, K., Miikkulainen, R. (2002) “Efficient Evolution of Neural Networks Topologies”, Proceedings of the 2002 Congress on Evolutionary Computation.
[4] Stanley, K., Bryant, B., Miikkulainen, R. (2005) “Evolving Neural Networks Agents in the NERO Video Game”, Proceedings of the IEEE 2005 Symposium on Computational Intelligence and Games.
[5] Rezende, S. (2003) “Sistemas Inteligentes – Fundamentos e Aplicações”, ed. Manole, págs 254-257.
[6] Robocode Central http://robocode.sourceforge.net/
[7] Indigente Game Engine – InGE