Back-End

13 nov, 2017

Uber AI Labs abre código do Pyro, uma linguagem de programação probabilística profunda

Publicidade

Alcançar o objetivo da Uber de levar um transporte confiável para todos, exige uma previsão e otimização sem esforço em cada momento. As oportunidades variam de fazer a correspondência entre motoristas e passageiros, sugerir rotas ótimas, encontrar combinações de pool sensíveis e até mesmo criar a próxima geração de veículos inteligentes. Para resolver esses desafios, estamos combinando técnicas de inteligência artificial (IA) de ponta com a vasta experiência de cientistas de dados, engenheiros e outros usuários. Estamos explorando uma abordagem tool-first que permitirá que nós e outros, criemos a próxima geração de soluções de IA.

Como parte dessa iniciativa, a Uber AI Labs anunciou no início de novembro, a abertura do código da nossa linguagem de programação probabilística Pyro! O Pyro é uma ferramenta para a modelagem probabilística profunda, unificando o melhor do deep learning moderno e da modelagem bayesiana. O objetivo do Pyro é acelerar a pesquisa e as aplicações dessas técnicas, e torná-las mais acessíveis para uma comunidade mais ampla de IA.

A Uber AI Labs é diversificada, tanto em termos das aplicações que estamos explorando, quanto em técnicas que usamos. Reunimos várias tribos de IA, com especialistas em deep learning, métodos bayesianos, computação evolutiva e aprendizagem de reforço. O próprio Pyro reúne o melhor do deep learning moderno, modelagem bayesiana e abstração de software: é uma linguagem de programação moderna, universal e probabilística profunda.

Acreditamos que as ideias críticas para resolver a IA, virão de um esforço conjunto entre uma comunidade mundial de pessoas que buscam abordagens diversas. Ao abrirmos o código do Pyro, esperamos incentivar o mundo científico a colaborar para tornar as ferramentas de IA mais flexíveis, abertas e fáceis de usar. Esperamos que a versão atual (alfa!) do Pyro seja de maior interesse para os modeladores probabilísticos que desejam alavancar grandes conjuntos de dados e redes profundas, para os usuários PyTorch que desejam uma computação bayesiana fácil de usar e para os cientistas de dados prontos para explorar os limites da nova tecnologia.

Abaixo, descrevemos nossas motivações para criar o Pyro, delineamos seus princípios de design e algumas poucas informações sobre a implementação, e indicamos as próximas etapas para o desenvolvimento desse framework.

Por que Pyro?

A probabilidade é a matemática do raciocínio sob a incerteza, assim como o cálculo é a matemática para o raciocínio sobre as taxas de mudança. Modelos construídos na linguagem de probabilidade podem capturar raciocínio complexo, saber o que não sabem e descobrir uma estrutura em dados sem supervisão. Além disso, a probabilidade fornece uma maneira para especialistas humanos fornecerem conhecimento aos sistemas de IA na forma de crenças a priori.

Especificar diretamente modelos probabilísticos pode ser complicado, e implementá-los pode ser muito propenso a erros. As linguagens de programação probabilísticas (PPLs) resolvem esses problemas casando probabilidade com o poder representacional das linguagens de programação. Um programa probabilístico é uma mistura de computação determinística comum e valores de amostras aleatórios; essa computação estocástica representa uma história generativa sobre dados. As probabilidades estão implícitas nessa representação – não há necessidade de derivar fórmulas – e, no entanto, essa especificação também é universal: qualquer modelo computacional probabilístico pode ser escrito dessa maneira. O Pyro baseia-se no Python completo como sua linguagem de base, tornando-o claro e familiar para muitos.

Ao observar o resultado de um programa probabilístico, podemos descrever um problema de inferência, traduzido como: “o que deve ser verdadeiro se essa escolha aleatória tivesse um certo valor observado?”. Os sistemas de programação probabilística fornecem algoritmos de inferência universais que podem realizar inferências com pouca intervenção do usuário. Pense nisso como o compilador para um PPL: ele nos permite dividir o trabalho entre o modelador e o especialista em inferência.

No entanto, a inferência é o principal desafio para a modelagem probabilística, e a inferência não escalável é o principal modo de falha de PPLs. Aproveitando o poder do deep learning, os avanços recentes introduziram uma nova abordagem da inferência probabilística e implementação de PPL. A ideia-chave é descrever a inferência em um modelo através de um segundo modelo chamado modelo de inferência ou guia em Pyro (essa é, na verdade, uma ideia que remonta, até pelo menos à máquina de Helmholtz). Assim como um modelo é uma história generativa para os dados, um guia é uma história generativa para traduzir os dados em escolhas latentes.

É claro que não podemos simplesmente escrever o guia correto (é por isso que a inferência é difícil). Em vez disso, usamos a abordagem variacional, especificando uma família de guias parametrizados e depois resolvendo um problema de otimização para mover o guia para a distribuição posterior do modelo. Essa otimização pode ser automatizada graças à diferenciação automática, uma técnica para a computação eficiente do gradiente de um programa e vários truques para estimar o gradiente de uma expectativa.

O Pyro é contruído com a excelente biblioteca PyTorch, que inclui a diferenciação automática usando uma matemática tensor muito rápida, acelerada por GPU. O PyTorch constrói gradientes dinamicamente, o que permite que os programas Pyro incluam estrutura de controle estocástico, ou seja, escolhas aleatórias em um programa Pyro podem controlar a presença de outras escolhas aleatórias no programa. A estrutura de controle estocástico é crucial para tornar um PPL universal. Por isso, o Pyro pode representar qualquer modelo probabilístico, ao mesmo tempo em que fornece inferência automática, baseada em otimização que é flexível e escalável para grandes conjuntos de dados.

Em Pyro, tanto os modelos generativos quanto os guias de inferência podem incluir redes neurais profundas como componentes. Os modelos probabilísticos profundos resultantes mostraram grande promessa em trabalhos recentes, especialmente para problemas de machine learning sem supervisão e semissupervisionados.

Em resumo:

  • Por que modelagem probabilística? Para capturar corretamente a incerteza em modelos e previsões para o aprendizado sem supervisão e semissupervisionado, e para fornecer sistemas de IA com conhecimento prévio declarativo.
  • Por que programas probabilísticos (universais)? Para fornecer uma linguagem clara, de alto nível e completa para especificar modelos complexos.
  • Por que modelos probabilísticos profundos? Para aprender conhecimento generativo de dados e reificar conhecimento de como fazer inferência.
  • Por que inferência por otimização? Para permitir escalar para grandes dados e alavancar avanços na otimização moderna e na inferência variacional.

Princípios e insights de design do Pyro

No desenvolvimento do Pyro, buscamos satisfazer quatro princípios de design. O Pyro foi construído para ser:

  • Universal: Pyro é um PPL universal; ele pode representar qualquer distribuição de probabilidade computacional. Como? Ao partir de uma linguagem universal com iteração e recursão (código Python arbitrário), e depois adicionar amostras aleatórias, observação e inferência.
  • Escalável: Pyro escala para grandes conjuntos de dados com pouca sobrecarga acima do código manuscrito. Como? Construindo técnicas modernas de otimização de caixa preta, que usam minilotes de dados para se assemalham à inferência.
  • Mínimo: Pyro é ágil e sustentável. Como? O Pyro é implementado com um pequeno núcleo de abstrações poderosas e combináveis. Sempre que possível, o trabalho pesado é delegado para o PyTorch e outras bibliotecas.
  • Flexível: Pyro visa à automação quando você a quer e controle quando você precisa dele. Como? O Pyro usa abstrações de alto nível para expressar modelos de generativos e de inferência, ao mesmo tempo em que permite aos especialistas personalizar facilmente a inferência.

Esses princípios geralmente levam à implementação do Pyro em direções opostas. Ser universal, por exemplo, exige permitir a estrutura de controle arbitrário dentro dos programas Pyro, mas essa generalidade dificulta a escala. Da mesma forma, a construção automática de funções objetivas usando abstrações mínimas torna muito mais fácil o protótipo de novos modelos, mas isso também tende a ocultar a computação objetiva de usuários avançados que desejam flexibilidade para modificar o objetivo.

Durante a nossa pesquisa, resolvemos essas tensões com muitas técnicas de outros esforços PPL (principalmente WebPPL e Edward) e descobrimos algumas novas ideias. Por exemplo, descobrimos que os manipuladores de efeitos combináveis podem separar a manipulação do fluxo de controle da computação da função objetivo. As operações básicas em um PPL são a amostragem de uma distribuição, observando os valores da amostra e inferindo os resultados posteriores em execuções resultantes. No entanto, o comportamento exigido das demonstrações de amostragem depende do contexto de inferência em que elas ocorrem. Por exemplo, ao calcular a evidência padrão – objetivo de limite inferior – as declarações de amostragem no guia devem realmente ostrar novos valores, enquanto as instruções de amostragem no modelo só devem reutilizar esses valores. A implementação do Pyro cria esses efeitos específicos do contexto de um conjunto de objetos Poutine (um saboroso portmanteau para Pyro Coroutine), como Trace, Replay e Condition. Cada Poutine fornece uma pequena modificação no manuseio de construções Pyro (amostragem, construção de parâmetros etc.); colocar Poutines em camadas juntas nos permite construir as operações necessárias para diferentes algoritmos de inferência. Com essa lógica de programa tratada por Poutines, o principal código de inferência centra-se na construção de objetivos e na estimativa de gradientes.

Próximos passos

Já útil para pesquisas em seu estado alfa, o Pyro continuará a mudar rapidamente nos próximos meses, à medida que nos envolvamos com a programação probabilística e com comunidades de deep learning.

As possíveis orientações para expandir e melhorar o Pyro são múltiplas, refletindo tanto os vários domínios de aplicação do Pyro como a vibrante comunidade de pesquisa que trabalha em modelagem e inferência probabilística profunda. Algumas das nossas direções técnicas de maior prioridade incluem:

  • Melhorar as abstrações para modelagem rápida (por exemplo, fornecendo guias padrão automáticos) e uso avançado (por exemplo, refinando o contrato de composição de nossos objetos Poutine).
  • Acrescentar objetivos adicionais (por exemplo, divergência alfa, infoVAE e perda baseada em GAN) e técnicas adicionais para estimar expectativas de gradientes.
  • Adicionar a cadeia Markov Monte Carlo (MCMC) e a inferência Sequential Monte Carlo (SMC), especialmente Hamiltonian Monte Carlo (HMC), e usá-los dentro dos objetivos de inferência variacional.
  • Explorar linguagens para processos Gaussianos e aplicações, como a otimização bayesiana.

Em longo prazo, esperamos que as principais orientações do desenvolvimento do Pyro sejam conduzidas por aplicações e pelas prioridades da comunidade Pyro emergente (como refletido em suas issues no GitHub).

***

Este artigo é do Uber Engineering. Ele foi escrito por Noah Goodman. A tradução foi feita pela Redação iMasters com autorização. Você pode conferir o original em: https://eng.uber.com/pyro/