Acelerando a Neuroevolução Profunda: treine o Atari em horas em um único PC

Photo of Acelerando a Neuroevolução Profunda: treine o Atari em horas em um único PC
Facebook
VKontakte
share_fav

Recentemente publicamos um artigo anunciando cinco pesquisas sobre neuro evolução profunda, incluindo a descoberta de que algoritmos genéticos podem resolver problemas de aprendizagem de reforço profundo, bem como alternativas populares, como Q-learning profundo e gradientes de políticas.

Esse trabalho baseia-se em Salimans et al., 2017, que mostrou o mesmo para estratégias de evolução (ES), outro algoritmo de neuro evolução. Nós também descrevemos como a ES pode ser melhorada adicionando exploração na forma de uma pressão para que os agentes sejam novos, e como a ES se relaciona com o gradiente descendente.

Toda essa pesquisa foi computacionalmente cara: ela foi conduzida entre 720 e 3000 CPUs distribuídas em um grande cluster de computação de alto desempenho, aparentemente colocando a neuroevolução profunda fora do alcance da maioria dos pesquisadores, estudantes, empresas e entusiastas.

Lançamos um código-fonte aberto que possibilita conduzir essa pesquisa de maneira muito mais rápida e barata. Com este código, o tempo que leva para treinar redes neurais profundas para jogar o Atari, que demora cerca de 1 hora em 720 CPUs, agora leva cerca de 4 horas em um único desktop moderno.

Este ponto é importante porque afeta dramaticamente nossas percepções sobre a gama de recursos necessários para conduzir este tipo de pesquisa, tornando-a acessível a um grupo muito maior de pesquisadores.

frostbite_ga_noframeskip solution1

Legenda: As técnicas de neuroevolução são uma alternativa competitiva para resolver problemas desafiadores de aprendizagem de reforço profundo, como o Atari e a locomoção humanoide. São mostrados comportamentos de redes neurais profundas, treinadas com um algoritmo genético simples.

O que mudou para torná-lo mais rápido e funcionar em apenas um computador?

Acontece que os desktops modernos e sofisticados, que possuem dezenas de núcleos virtuais, agem como um cluster de computação modesto. Se as avaliações forem executadas corretamente em paralelo, uma execução que leva 1 hora em 720 núcleos, poderá ser executada nas CPUs de um computador pessoal de 48 núcleos em 16 horas, que é mais lento, mas não proibitivo/inviável. Os desktops modernos também possuem GPUs, que são rápidas na execução de redes neurais profundas (DNNs).

Nosso código maximiza o uso de CPUs e GPUs em paralelo. Ele executa redes neurais profundas na GPU, os domínios (por exemplo, videogames ou simuladores físicos) na CPU e executa várias avaliações em paralelo em um lote, permitindo que todo o hardware disponível seja utilizado de forma eficiente. Conforme descrito abaixo, ele também contém operações personalizadas do TensorFlow, que melhoram significativamente a velocidade de treinamento.

Habilitar o treinamento em GPUs exigiu algumas modificações em como as operações da rede neural são computadas. Em nossa configuração, a execução de uma única rede neural foi mais rápida usando uma única CPU do que uma GPU. Mas as GPUs se beneficiam muito quando cálculos semelhantes (por exemplo, as passagens avançadas de redes neurais) são executados em paralelo. Para aproveitar a GPU, nós agregamos múltiplas passagens avançadas da rede neural em lotes.

Isso é comum na pesquisa de redes neurais, mas geralmente envolve a mesma rede neural processando um lote de entradas diferentes. A evolução, no entanto, opera em populações de diferentes redes neurais, mas as acelerações ocorrem mesmo se as redes forem diferentes (embora os requisitos de memória sejam aumentados).

Nós implementamos este batching/loteamento de população com operações básicas do TensorFlow e ele gerou uma aceleração de aproximadamente 2x, reduzindo o tempo de treinamento para cerca de 8 horas. No entanto, percebemos que poderíamos fazer melhor. Embora o TensorFlow forneça todas as operações necessárias, essas operações não são adaptadas para esse tipo de cálculo.

Dessa forma, adicionamos dois tipos de operações personalizadas do TensorFlow, que combinaram para gerar outra aceleração de 2x, reduzindo o treinamento para aproximadamente 4 horas em uma única máquina, o número originalmente mencionado.

A primeira operação personalizada do TensorFlow acelerou significativamente as GPUs. Ela é construída especificamente para computação de rede neural heterogênea em domínios de RL onde os episódios são de comprimento diferente, como é o caso do Atari e muitas tarefas de aprendizado de robô simuladas. Ela permite que a GPU execute apenas quantas redes forem necessárias, em vez de exigir que um conjunto fixo (grande) de redes seja executado em cada iteração.

As melhorias descritas até agora tornaram as GPUs mais econômicas do que as CPUs. Na verdade, as GPUs eram tão rápidas que as simulações Atari (CPU) não conseguiam acompanhar, mesmo quando as bibliotecas de multiprocessamento eram usadas para paralelizar a computação. Para melhorar o desempenho da simulação, adicionamos um segundo conjunto de operações personalizadas do TensorFlow.

Elas mudaram o invólucro da simulação Atari do Python para comandos personalizados do TensorFlow (redefinição, etapa, observação) que aproveitam os recursos rápidos de multithreading fornecidos pelo TensorFlow sem as lentidões típicas associadas à interação do Python com o TensorFlow. No geral, essas mudanças levaram a uma aceleração de aproximadamente 3x no simulador Atari.

Essas inovações devem acelerar qualquer pesquisa de aprendizado por reforço que tenha múltiplas instâncias de um domínio (por exemplo, Atari ou o simulador físico MuJoCo) executado em paralelo, que é uma técnica cada vez mais comum no aprendizado por reforço, como a Q-learning profunda distribuída (DQN) e gradientes de política distribuídos (por exemplo, A3C).

Uma vez que tivemos a capacidade de executar rapidamente uma população de redes em GPUs e simuladores de domínio mais rápidos nas CPUs, o desafio tornou-se manter todos os recursos do computador funcionando o máximo possível.

Se fizéssemos uma passagem avançada em cada rede neural, perguntando qual ação deveria ser tomada no estado atual, enquanto cada um estivesse computando sua resposta, as CPUs executando os simuladores de jogos não estariam fazendo nada.

Da mesma forma, se tomarmos as ações e solicitarmos aos simuladores de domínio “que estados resultam dessas ações?”, as GPUs que executam as redes neurais ficariam inativas durante essa etapa de simulação. Esta é a opção Multithreaded CPU + GPU mostrada abaixo. Enquanto uma melhoria a um relação ao cálculo de encadeamento único ainda é ineficiente.

Uma solução melhor é ter dois ou mais subconjuntos de redes neurais emparelhados com simuladores e manter as GPUs e CPUs sendo executadas ao mesmo tempo atualizando redes ou simulações de diferentes conjuntos, dependendo de qual etapa (rede neural ou simulação) está pronta para ser tomada. Essa abordagem é a opção mais à direita, “CPU + GPU com pipelines” mostrada na figura a seguir.

Com isso, e as outras melhorias mencionadas acima, conseguimos obter o tempo de treinamento para as redes neurais de parâmetro de cerca de 4M para o número mencionado acima (cerca de 4 horas em um único computador).

Otimizando o escalonamento de populações de redes heterogêneas em RL. As caixas azuis são simuladores de domínio, como o emulador de jogos Atari ou motores físicos como MuJoCo, que podem ter episódios de diferentes comprimentos. Uma maneira ingênua de usar uma GPU (à esquerda) resultaria em baixo desempenho por dois motivos:

  1. Um tamanho de lote de um para a GPU, que não aproveita suas capacidades de computação paralela, e;
  2. Tempo ocioso enquanto a GPU aguarda a CPU e vice-versa.

Uma abordagem multithreaded (ao centro) permite um uso mais eficiente da GPU por ter várias CPUs acionando os simuladores em paralelo, mas faz com que a GPU fique inativa enquanto as CPUs estão funcionando e vice-versa.

Nossa implementação em pipeline (à direita) permite que a GPU e a CPU operem de maneira eficiente. Essa abordagem também funciona com várias GPUs e CPUs operando simultaneamente, que foi o que fizemos na prática.

O impacto de experimentos mais rápidos e mais baratos

Nosso código permite que todos na comunidade de pesquisa, incluindo estudantes e aprendizes autodidatas, façam uma rápida iteração experimental sobre o treinamento de redes neurais profundas em problemas desafiadores como o Atari, que até então era um luxo limitado apenas a laboratórios acadêmicos e indústrias bem financiadas.

Código mais rápido gera avanços na pesquisa. Por exemplo, nosso novo código nos permitiu lançar uma pesquisa extensiva de hiper parâmetros para o algoritmo genético por uma fração do custo, o que levou a melhorias de desempenho na maioria dos jogos Atari em relação àqueles que originalmente informamos.

Atualizamos nossa publicação arXiv original com esses novos resultados. O código mais rápido também catalisa todas as nossas pesquisas atuais para melhorar a neuro evolução profunda, encurtando nossos tempos de iteração, permitindo que experimentemos cada nova ideia em mais domínios e executemos os algoritmos por mais tempo.

Nosso novo repositório de software inclui uma implementação de nosso algoritmo genético profundo, o algoritmo de estratégias de evolução de Salimans et al. e nosso controle de pesquisa aleatória (surpreendentemente competitivo!).

Esperamos que os outros usem nosso código para acelerar suas próprias atividades de pesquisa. Também convidamos a comunidade a construir a partir de/sob nosso código para melhorá-lo. Por exemplo, mais acelerações são possíveis com o treinamento de GPU distribuído e com a adição de outras operações do TensorFlow personalizadas para esse tipo de computação.

Há muito impulso em torno da neuroevolução profunda. Além do nosso trabalho e do OpenAI mencionado acima, também houve avanços recentes em deep learning usando algoritmos evolutivos da DeepMind, Google Brain e Sentient. Esperamos que o nosso código aberto contribua para esse momento, tornando o campo mais acessível.

Geralmente, nosso objetivo é diminuir o custo de fazer essa pesquisa até o ponto em que pesquisadores de todas as áreas/experiências possam tentar suas próprias ideias para melhorar a neuro evolução profunda e aproveitá-la para atingir seus objetivos.

Para ser notificado sobre futuras postagens no blog do Uber AI Labs, inscreva-se em nossa lista de discussão ou inscreva-se no canal do YouTube do Uber AI Labs. Se você estiver interessado em entrar para o Uber AI Labs, por favor, inscreva-se no Uber.ai.

Assine a newsletter da Uber para acompanhar as mais recentes inovações da Engenharia da Uber.

***

Este artigo é do Uber Engineering. Ele foi escrito por Felipe Petroski Such, Kenneth O. Stanley e Jeff Clune. A tradução foi feita pela Redação iMasters com autorização. Você pode conferir o original em: https://eng.uber.com/accelerated-neuroevolution/

ver iMasters
#redes neurais
#deep learning
#tensorflow
#desenvolvimento
#uber engineering
#tecnologia