Usando algoritmos genéticos em redes neurais

Para resolver problemas matemáticos de forma computacional, os algoritmos genéticos eram muito populares há alguns anos, mas recentemente foram suplantados pela maior versatilidade das redes neurais. Entretanto, as duas abordagens podem ser usadas em conjunto, produzindo algoritmos ainda mais eficientes que as soluções individuais.

Os algoritmos genéticos são aplicados em problemas de otimização. Seu funcionamento se baseia na exploração de um universo conhecido de soluções na busca da solução ideal. Através de uma métrica de desempenho, ele seleciona as melhores soluções em uma de suas iterações, e a partir delas, gera novas soluções “filhas”, que tendem a ter performance cada vez melhor. O nome desta abordagem se deve ao fato de que o algoritmo simula o fluxo da informação genética através do processo da seleção natural. Em biologia, um indivíduo com genes “melhores” costuma ter desempenho melhor, o que lhe garante uma vantagem competitiva na disputa por recursos, e que também lhe torna mais apto a passar seus genes para a próxima geração. Ao longo do tempo, estas iterações naturais fazem com que a espécie se torne cada vez mais adaptada ao ambiente onde vive. No campo da computação, este mecanismo é imitado de forma que cada solução para um problema é encarado como um indivíduo, que em seu cromossomo carrega os valores para as variáveis que está tentando solucionar. Estas variáveis, por isso, costumam ser chamadas de genes. As soluções são relacionadas com a variável de saída, que pode ser considerada o fenótipo, e este valor é então utilizado para determinar o desempenho, ou fitness, da solução. Ao final de cada iteração, esta população é levada a procriar; nesta etapa, os indivíduos com melhor fitness são selecionados com maior probabilidade para gerar as soluções filhas. Na etapa de procriação ocorre o crossover, que é a troca aleatória de informação genética (ou seja, a troca de valores das variáveis de entrada), que costuma ser sucedida por uma etapa de mutação, onde alguns desses valores são alterados também de forma randômica. A mutação inclui um elemento de incerteza no método, que tem potencial para gerar soluções ainda melhores, não contidas na população original. O resultado da iteração são as soluções da próxima geração, e o processo é repetido de acordo com algum critério estabelecido pelo desenvolvedor. O vídeo abaixo exemplifica o funcionamento dos algoritmos genéticos.

Um exemplo clássico de problema que pode ser resolvido por algoritmos genéticos é o transporte de mercadorias valiosas. Imagine que um caminhão deve transportar produtos, e cada produto tem um volume e um valor. O caminhão também tem como variável limitante o volume máximo que pode transportar. O problema a ser resolvido é maximizar o volume e o valor das mercadorias transportadas, para que o custo do frete rateado entre os produtos seja mais barato. Neste caso, cada produto representa um gene, cujo valor vai indicar a quantidade daquele produto que pode ser transportada. O cromossomo contém uma lista com a quantidade de todos os produtos que serão carregados naquela viagem. O volume do caminhão entra como limitante; nenhuma solução que ultrapasse o limite de volume do caminhão deve ser considerada. O fitness pode ser medido como o valor total dos produtos que o caminhão está transportando.

Neste exemplo é possível perceber que o universo de soluções possíveis não é infinito, e que com capacidade computacional suficiente, talvez seja possível tentar resolver o problema usando outros algoritmos que de fato investiguem todo este universo. Entretanto, esta nem sempre é a situação, e os algoritmos genéticos acabam agindo como uma busca direcionada pela solução ideal, que usa menos recursos do que um processo exaustivo.

As redes neurais surgiram como uma solução muito mais abrangente. De forma semelhante aos algoritmos genéticos, as redes neurais também recebem os valores das variáveis de entrada associados a uma (ou mais) variável de saída, mas eles funcionam entendendo matematicamente as relações entre essas variáveis, sendo capazes de, depois do devido treinamento, prever o valor da variável de saída dado valores inéditos de entrada. O vídeo abaixo serve de introdução ao tema.

Um exemplo comum de aplicação de redes neurais é prever, através de vários indicadores sanguíneos, se uma pessoa está ou não doente. Atualmente, existe uma vasta biblioteca de arquiteturas de redes neurais, e elas encontram uso nas áreas mais diversas, como visão computacional, reconhecimento de fala e processamento de linguagem natural.

Um dos problemas dos algoritmos baseados em redes neurais é que eles costumam ser muito mais lentos que outras alterativas. Isto se deve ao fato de que, em cada iteração do método, uma correção pequena é feita aos seus parâmetros internos (pesos e biases das camadas escondidas), de forma que são necessárias várias iterações até se encontrar uma solução adequada. Outro problema é que alguns parâmetros do regime de treinamento, chamados de hiperparâmetros, não são ajustados durante este treinamento, devendo ser informados pelo desenvolvedor. Entre estes hiperparâmetros estão o número de épocas, o tamanhos dos batches, métodos de otimização e valores de variáveis associadas a métodos de regularização. Entretanto, se observa que estas duas situações podem ser tratadas como problemas de otimização: o primeiro problema busca os melhores valores dos parâmetros internos, e o segundo os melhores valores dos hiperparâmetros, para que a rede atinja o melhor desempenho possível. É justamente nestas etapas que os algoritmos genéticos podem ser integrados às redes neurais para tornar a busca mais direcionada e, por consequência, mais rápida.

Algoritmos genéticos aplicados aos parâmetros internos de redes neurais

Durante o treinamento de uma rede neural, a cada iteração os parâmetros internos são ajustados ligeiramente com o objetivo de maximizar seu desempenho, o que é tratado matematicamente como a minimização de seu erro. Acontece que, como via de regra a rede é inicializada com valores aleatórios, pode ser que esta inicialização resulte em uma rede que no espaço de soluções esteja muito distante da solução ideal. A ideia de aplicar algoritmos genéticos neste processo trata de considerar várias redes neurais paralelas como indivíduos, e seus parâmetros internos como genes. O fitness pode ser dado pelo erro determinado durante o treinamento, de forma que as redes com menor erro têm fitness maior. Então, as redes de melhor desempenho trocam aleatoriamente alguns valores de seus parâmetros internos, o que tende a colocar as soluções filhas mais próximas da solução ideal.

A figura abaixo exemplifica uma população de soluções contendo cinco indivíduos, sendo cada um uma rede neural com quatro neurônios na camada de entrada, dois neurônios nas duas camadas escondidas, e um neurônio na camada de saída. Após seu treinamento, eles são ordenados pelo seu fitness, representado em uma escala de cor. Ao final da primeira geração, os indivíduos com maior fitness são selecionados com maior probabilidade para gerar a geração seguinte. O processo de crossover está demonstrado apenas uma vez, pela troca dos valores dos parâmetros internos das duas redes com maior fitness, que no exemplo permutam suas duas camadas finais. O ganho em desempenho é representado pelo aumento do fitness na segunda geração.

Uma implementação desta abordagem pode ser encontrada aqui. No exemplo, o autor mostrou que o uso da metodologia resultou em melhoria de precisão de 57 para 95%.

Algoritmos genéticos aplicados aos hiperparâmetros de redes neurais

Neste caso, os valores dos hiperparâmetros é que são considerados os genes. Também temos que inicializar várias redes em paralelo, as quais continuam sendo avaliadas em função de seu erro. A cada iteração do algoritmo genético, as soluções com melhor desempenho trocam alguns de seus valores de hiperparâmetro. Este método também tende a reduzir o tempo necessário para convergir até a solução ideal, já que ele insere uma direção a esta busca, não sendo necessário investigar todas as combinações possíveis dos valores de hiperparâmetro.

A figura abaixo exemplifica uma população de soluções contendo cinco indivíduos, sendo cada um uma rede neural com a mesma estrutura. Após seu treinamento, eles são ordenados pelo seu fitness, representado em uma escala de cor. Ao final da primeira geração, os indivíduos com maior fitness são selecionados com maior probabilidade para gerar a geração seguinte. O processo de crossover está demonstrado apenas uma vez, pela troca dos valores dos hiperparâmetros das duas redes com maior fitness, que no exemplo permutam dois de seus cinco valores. O ganho em desempenho é representado pelo aumento do fitness na segunda geração.

Uma implementação desta abordagem está disponível aqui. No exemplo, o autor mostrou que o uso de algoritmo genético resultou em um aumento pequeno de precisão, mas o tempo de treinamento reduziu de 63 para 7 horas.


Neste artigo, mostramos como é possível integrar dois métodos computacionais para que seus benefícios individuais se somem de forma sinergística. Neste caso, demonstramos como o uso de algoritmos genéticos pode auxiliar no treinamento de redes neurais, tanto para a busca dos melhores parâmetros internos (pesos e biases) como dos hiperparâmetros.

Sobre o autor

3 comentários em “Usando algoritmos genéticos em redes neurais”

  1. Ótimo artigo. A forma como vocês escrevem e explicam as coisas é muito boa. (considerando R e Python) Já existem pacotes que permitem utilizarmos algoritmos genéticos com as redes neurais tanto na otimização dos parâmetros, quanto dos hiperparâmetros de forma integrada ou temos que fazer na mão? Se tivermos que procurar na documentação dos pacotes, qual seria o termo mais apropriado para verificar se existe suporte ao uso de algoritmos genéticos em redes neurais? Seria o GNN (Genetic_Neural_Network)? Encontrei um pacote no R chamado gnn: Generative Neural Networks, mas pela descrição não parece ser a mesma coisa.

    1. Olá Juliano! Que bom que gostou do artigo 🙂
      Eu estava procurando na semana passada, e até achei um otimização no TensorFlow (veja aqui: https://www.tensorflow.org/probability/api_docs/python/tfp/optimizer/differential_evolution_minimize), mas parece que funciona em versões mais antigas das bibliotecas. Para procurar, veja na lista de otimizadores (optimizers). O que acha mais fácil são implementações manuais, conforme os dois exemplos dos links no artigo. Sobre o pacote GNN, parece que é para GANs (geração automática de imagens)

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.