
Com quatro parâmetros, posso perguntar a um elefante, e com cinco posso fazê-lo mover a tromba.
- John Von Neumann
A idéia de " programação diferenciável " é muito popular no mundo do aprendizado de máquina. Para muitos, não está claro se esse termo reflete uma mudança real na maneira como os pesquisadores entendem o aprendizado de máquina, ou é apenas (outra) rebranding de "aprendizado profundo". Este post explica as novidades da programação diferenciada (ou ∂P) na tabela de aprendizado de máquina.
Mais importante ainda, a programação diferenciada é a mudança oposta à direção da aprendizagem profunda; de modelos cada vez mais parametrizados a modelos mais simples que usam a estrutura do problema em maior extensão.
Em seguida, folheamos uma tela de texto desinteressante, queremos descobrir o que é a diferenciação automática e até preenchê-la de uma catapulta!
Força bruta com benefícios
Diferenciabilidade é uma idéia básica que torna o aprendizado profundo tão bem-sucedido. Onde as pesquisas de força bruta, mesmo para centenas de parâmetros do modelo, seriam muito caras, os gradientes permitem a passagem pseudo-aleatória de partes interessantes do espaço de parâmetros e encontram um bom conjunto. Ao executar um algoritmo aparentemente ingênuo, obtemos uma boa generalidade, mas está longe de ser óbvio que precisamos diferenciar, digamos, trabalhando com sequências na tradução de idiomas, mas tudo acaba sendo simples, mostramos um pouco de criatividade.
E quanto aos neurônios biológicos e ? Não há nada de especial nessa fórmula; Este é um exemplo simples e flexível de uma função não linear altamente paramétrica. De fato, esse é provavelmente o pior recurso na maioria dos casos. Uma camada da rede neural, em princípio, pode classificar imagens de gatos, mas apenas usando um truque relativamente desinteressante. Funciona perfeitamente! - mas as letras pequenas alertam que você pode precisar de mais parâmetros do que átomos no universo. Para realmente fazer esse trabalho funcionar, você precisa codificar a estrutura problemática do modelo - é aqui que começa a parecer mais com a programação tradicional.
Por exemplo, ConvNets têm uma enorme vantagem sobre o perceptron, porque trabalham com kernels de imagem , conhecidos por usar invariância de conversão. Face - é a face, independentemente de ser exibida no canto superior esquerdo da imagem ou no centro, mas onde o perceptron deve estudar esse caso em cada caso, o kernel pode responder imediatamente a qualquer parte da imagem. É difícil analisar redes convolucionais em termos estatísticos, mas é muito mais fácil considerá-las como uma versão automática do que os especialistas em processamento de imagens escreveram manualmente. O núcleo da imagem é o primeiro e mais fácil programa diferenciável.
Estrutura de codificação, Redux
Os kits de ferramentas de ML estão cada vez mais suportando diferenciação algorítmica (AD), o que nos permite diferenciar modelos usando loops, ramificações e recursão - ou qualquer programa construído em um conjunto de primitivas matemáticas diferenciáveis. Isso levou a uma arquitetura mais complexa: os modelos de PNL são cada vez mais parsers de gramática clássicos com modelos com aumento de pilha , e você pode até diferenciar um análogo de uma máquina de Turing ou de um intérprete de linguagem de programação .
O último passo dado pela programação diferenciada é não considerar mais a multiplicação, a convolução e a RNN da matriz como elementos fundamentais da aprendizagem profunda, mas apenas como casos especiais. Podemos aplicar métodos de aprendizado profundo a qualquer função diferenciável parametrizada . Funções tão complexas quanto simuladores físicos ou traçadores de raios também podem ser diferenciadas e otimizadas. Até a computação quântica pode se encaixar nessa estrutura.

Os cientistas há muito tempo usam modelos mecanicistas que ficam entre programação explícita e aprendizado de máquina. Equações diferenciais com parâmetros livres usados em física, epidemiologia ou farmacodinâmica são equivalentes a redes neurais em tudo, exceto na terminologia. Eles simplesmente visam fornecer uma funcionalidade muito mais restrita, porque é muito mais simples.
Um progresso verdadeiramente poderoso é o seguinte: diferenciabilidade generalizada significa que todos esses métodos se conectam como tijolos de lego .
Em vez de sempre escrever novos programas para ML, podemos reutilizar programas existentes usando mecanismos físicos em modelos robóticos com base em aprendizado profundo. Onde os algoritmos modernos de aprendizado por reforço precisam criar um modelo detalhado do mundo exterior com base apenas no que eles serão recompensados (soa como força bruta ), podemos simplesmente aplicar conhecimentos detalhados e precisos dos sistemas físicos antes que o aprendizado comece.
Mesmo as áreas mais maduras da aprendizagem profunda não se destacam; após o núcleo de convolução, o próximo passo natural para os modelos de imagem é um traçador de raios diferenciável . A renderização em 3D contém muito conhecimento estrutural sobre como as cenas são exibidas em pixels, que ainda desempenharão um papel em nossa cozinha. Digamos que um modelo tome decisões em um ambiente simulado exibido como pixels, que o modelo usa como entrada. Em princípio, agora podemos diferenciar todo o ciclo, o que nos permitirá ver diretamente a influência do ambiente nas decisões do modelo e vice-versa. Isso pode aumentar significativamente o poder de um ambiente simulado realista para modelos de treinamento, como carros com direção automática.
Como na ciência, os modelos híbridos podem ser mais eficientes e resolver algumas das compensações entre aprendizado profundo e programação explícita. Por exemplo, um planejador de trajetória de voo de um drone pode ter um componente de rede neural que só pode fazer alterações ligeiramente corretivas em um programa explícito confiável, fazendo com que seu comportamento geral seja analisado enquanto se adapta aos dados empíricos. Isso também é bom para a interpretabilidade: os parâmetros de modelos e simulações mecanicistas geralmente têm interpretações físicas claras; portanto, se o modelo avaliar os parâmetros internos, fará uma declaração clara sobre o que, na sua opinião, acontece fora.
Se tudo isso é maravilhoso, por que todos não desistiram e correram para aprender a se diferenciar? Infelizmente, as limitações das estruturas existentes dificultam a construção de modelos dessa complexidade e é impossível reutilizar a riqueza de conhecimentos incorporados no código científico existente. A necessidade de reimplementar mecanismos físicos do zero em uma linguagem de modelagem muito limitada transforma um script de dez linhas em um projeto de pesquisa de vários anos. Mas os avanços na linguagem e na tecnologia de compilação , especialmente na diferenciação automática , nos aproximam do Santo Graal: "apenas diferencie meu mecanismo de jogo, por favor".
Então, o que é programação diferenciada?
A programação diferenciada permite aplicar métodos de aprendizado profundo a programas existentes complexos, reutilizando com eles uma enorme quantidade de conhecimento incorporado neles. Aprendizado profundo, estatística, programação e ciência - tudo o que tenta dizer sua palavra na modelagem do mundo à nossa volta - é hora de combiná-lo, juntando-o como partículas em um colisor de hádrons . Isso melhorará os modelos atuais e permitirá que o ML seja aplicado em áreas onde suas limitações atuais - interpretabilidade ou requisitos computacionais e de dados - os tornam não aplicáveis individualmente.
Problemas de gerenciamento diferenciáveis
A seguir, mostramos que a diferenciabilidade pode trazer algumas tarefas de gerenciamento simples, mas clássicas, nas quais geralmente usamos o Aprendizado por Reforço (RL) como uma caixa preta. Modelos diferenciáveis (modelos ∂P) não apenas revelam estratégias de controle muito mais eficazes, mas também aprendem várias ordens de magnitude mais rapidamente. O código está disponível para estudo - na maioria dos casos, ele aprende em alguns segundos em qualquer laptop.
Siga o gradiente
A diferenciação é a força motriz em quase todas as etapas do aprendizado profundo; para esta função usamos o gradiente para descobrir como uma mudança em x
afetará y
. Apesar da natureza matemática, os gradientes são na verdade um conceito muito geral e intuitivo. Esqueça as fórmulas que você teve que procurar na escola; vamos fazer algo mais divertido, como jogar algo ao longo de um caminho parabólico.

Quando lançamos projéteis com a ajuda de três tiros, nosso x
(entrada) representa a configuração (digamos, o tamanho do contrapeso ou o ângulo de ejeção), e y
é a distância que o projétil percorre antes do pouso. Se você está tentando mirar, o gradiente diz algo muito útil - aumente ou diminua um determinado parâmetro. Para maximizar a distância, basta seguir o gradiente.
OK, mas como obtemos o parâmetro certo? Mas com a ajuda de uma coisa complicada chamada diferenciação algorítmica , que permite diferenciar não apenas fórmulas simples que você aprendeu na escola, mas também programas de qualquer complexidade - por exemplo, nosso simulador Trebuchet . Como resultado, podemos pegar um simulador simples escrito em Julia e o pacote diff diff DiffEq sem um estudo aprofundado, e obter gradientes para isso em uma chamada de função.
Jogando coisas
Precisamos alvejar o trabuco no alvo, usando gradientes para ajustar o ângulo de ejeção; Isso é chamado de estimativa de parâmetros e já vimos exemplos semelhantes . Podemos tornar a tarefa mais interessante, migrando para o meta-método: em vez de apontar o trebuchet para um alvo, otimizamos a rede neural, que pode direcioná-la para qualquer alvo. Eis como funciona: uma rede neural aceita duas entradas, uma distância alvo em metros e a velocidade atual do vento. Na rede, são definidas as configurações do trabuco (a massa do contrapeso e o ângulo de disparo), que são alimentados a um simulador que calcula a distância percorrida. Em seguida, comparamos com nosso objetivo e percorremos toda a cadeia para ajustar o peso da rede. Nosso "conjunto de dados" é um conjunto de alvos e velocidades do vento selecionados aleatoriamente.

Uma boa característica desse modelo simples é que o aprendizado é rápido, porque expressamos exatamente o que queremos do modelo de uma maneira completamente diferenciada. Inicialmente, fica assim:

Após cerca de cinco minutos de treinamento (no mesmo núcleo do processador do meu laptop), fica assim:

Se você quiser influenciar a trajetória, aumente a velocidade do vento:

Desvio de 16 cm, ou cerca de 0,3%. Que tal apontar diretamente para o trabuco? Isso é fácil com a descida do gradiente, pois temos gradientes. No entanto, esse é um processo iterativo lento que leva cerca de 100 ms por vez. Pelo contrário, a operação de uma rede neural leva 5 μs (vinte mil vezes mais rápido) com uma leve perda de precisão. Esse truque, chamado “inversão aproximada da função através de gradientes”, é muito comum e pode ser usado não apenas em sistemas dinâmicos, mas também em um algoritmo de transferência de estilo rápido .
Esse é o problema de gerenciamento mais simples possível que usamos principalmente para fins ilustrativos. Mas podemos aplicar os mesmos métodos de maneiras mais avançadas aos problemas clássicos de RL.
Carrinho, conheça o poste
Um desafio de gerenciamento mais reconhecível é o CartPole , o "Olá mundo" para o aprendizado por reforço. O desafio é aprender a equilibrar o pilar vertical empurrando sua base para a esquerda ou direita. Nossa configuração é geralmente semelhante ao caso do Trebuchet: a implementação de Julia nos permite considerar diretamente as recompensas recebidas pelo ambiente como perdas. ∂P nos permite alternar perfeitamente de um modelo simples para um modelo RL.

Um leitor astuto pode perceber um problema. A área de ação para a tábua do piso - um deslocamento para a esquerda ou direita - é discreta e, portanto, não diferenciável. Resolvemos esse problema introduzindo discretização diferenciável, definida da seguinte maneira :
f (x) = \ esquerda \ {\ begin {matrix} \, 1, \, x \ geqslant0 \\ -1, \, x <0 \ end {matrix} \ right.
Em outras palavras, fazemos o gradiente se comportar como se era uma função idêntica. Dado o quanto a idéia matemática de diferenciabilidade já é usada no ML, talvez não seja surpreendente que possamos simplesmente enganar aqui; para o treinamento, tudo o que precisamos é de um sinal para informar nossa caminhada pseudo-aleatória pelo espaço de parâmetros, e o resto são os detalhes. Os resultados falam por si. Nos casos em que os métodos de RL precisam ser treinados em centenas de episódios antes de resolver o problema, os modelos ∂P precisam de apenas 5 episódios para finalmente vencer.

O Pêndulo e Backprop através do Tempo
Um objetivo importante da RL (aprendizagem por reforço) é lidar com a remuneração diferida quando uma ação não nos ajuda a melhorar os resultados de várias etapas seguidas. Quando o ambiente é diferenciável, o ∂P permite treinar o agente na propagação reversa no tempo, como em uma rede recursiva! Nesse caso, o estado do ambiente se torna um "estado oculto" que muda entre as etapas do tempo.

Para demonstrar essa técnica, consideramos um modelo de pêndulo , no qual a tarefa é girar o pêndulo até que fique em pé e mantê-lo em equilíbrio instável. Isso é difícil para os modelos RL; Após cerca de 20 episódios de treinamento, o problema está resolvido, mas muitas vezes o caminho para a solução claramente não é o ideal. Por outro lado, o BPTT pode superar o ranking dos líderes de RL em um episódio de treinamento. É instrutivo observar como esse episódio se desenrola; no início da gravação, a estratégia é aleatória e o modelo melhora com o tempo. O ritmo do aprendizado é quase alarmante.

O modelo é adequado para usinar qualquer ângulo inicial e possui algo próximo à estratégia ideal. Ao reiniciar, o modelo se parece com isso.

Este é apenas o começo; obteremos sucesso real aplicando DP em ambientes com os quais geralmente é difícil trabalhar com RL, onde já existem simulações e modelos ricos (como na maioria das ciências naturais e de engenharia) e onde a interpretabilidade é um fator importante (como na medicina).
O mapa não é o território
Uma limitação desses modelos de brinquedos é que eles equiparam o ambiente de aprendizado simulado ao ambiente de teste; Obviamente, o mundo real não é diferenciável. Em um modelo mais realista, a simulação nos fornece um padrão aproximado de comportamento, que é refinado pelos dados. Esses dados informam, digamos, os efeitos simulados do vento, o que, por sua vez, melhora a qualidade dos gradientes que o simulador passa para o controlador. Os modelos podem até fazer parte do passe direto do controlador, permitindo refinar suas previsões sem ter que estudar a dinâmica do sistema do zero. Aprender essas novas arquiteturas fará um trabalho emocionante no futuro.
Coda
A idéia básica é que a programação diferenciável, na qual simplesmente escrevemos um programa numérico arbitrário e o otimizamos usando gradientes, é uma maneira poderosa de criar melhores modelos e arquiteturas semelhantes ao aprendizado profundo, especialmente quando temos uma grande biblioteca de programas diferenciáveis à mão . Os modelos descritos são apenas visualizações, mas esperamos que eles tenham uma idéia de como essas idéias podem ser implementadas de uma maneira mais realista.
Assim como a programação funcional envolve raciocinar e expressar algoritmos usando padrões funcionais, a programação diferenciável envolve a expressão de algoritmos usando padrões diferenciáveis. A comunidade de aprendizado profundo já desenvolveu muitos desses padrões de design, por exemplo, para lidar com problemas de gerenciamento ou com uma estrutura de dados consistente e semelhante a uma árvore. À medida que a área cresce, muito mais será inventado e, como resultado desses programas, provavelmente até as arquiteturas mais avançadas de aprendizado profundo parecerão rudes e atrasadas.
Referências
