Skip to content

Deep Learning Book

  • Início
  • Capítulos
  • Cursos Online
  • Contato

Deep Learning Book

Em Português, Online e Gratuito

Deep Learning Book

Capítulo 66 – Algoritmo de Agente Baseado em IA com Reinforcement Learning – Parte 1

by

O Aprendizado por Reforço (Reinforcement Learning) é uma abordagem computacional para entender e automatizar aprendizado direcionado e tomada de decisão. Distingue-se de outras abordagens por sua ênfase na aprendizagem de um agente a partir da interação direta com seu ambiente, sem exigir supervisão ou modelos completos do ambiente.

Em nossa opinião, a Aprendizado por Reforço é o primeiro campo a abordar seriamente problemas computacionais que surgem ao aprender com a interação com um ambiente para atingir objetivos de longo prazo. É um dos métodos mais avançados em Inteligência Artificial.

O Aprendizado por Reforço usa a estrutura formal dos Processos de Decisão de Markov para definir a interação entre um agente de aprendizagem e seu ambiente em termos de estados, ações e recompensas. Essa estrutura pretende ser uma maneira simples de representar características essenciais do problema de Inteligência Artificial. Esses recursos incluem uma sensação de causa e efeito, um senso de incerteza e não-determinismo, e a existência de metas explícitas. Algo muito similar ao aprendizado humano.

Os conceitos de valor e função de valor são essenciais para a maior parte dos métodos de Aprendizado por Reforço. Assumimos a posição de que a função de valor é importante para a pesquisa eficiente no espaço das políticas. O uso de funções de valor distingue os métodos de Aprendizado por Reforço dos métodos evolutivos que buscam diretamente no espaço de políticas orientado por avaliações de políticas inteiras.

Para ilustrar a ideia geral do Aprendizado por Reforço, vamos descrever um algoritmo (conjunto de etapas) que implementa o que seria um agente baseado em IA usando essa técnica. Passaremos por cada detalhe do algoritmo, inclusive alguns detalhes matemáticos. A construção de um algoritmo é a primeira parte do trabalho de construção de uma aplicação de Inteligência Artificial. Vamos usar o contexto de um jogo, para que o exemplo fique ainda mais claro. Mas o processo descrito aqui não é muito diferente de um agente de carro autônomo, por exemplo.

Muitos se preocupam apenas com a programação, sem compreender que existe um raciocínio lógico antes disso, que determina como deve ser a solução a ser implementada. Esse raciocínio lógico pode ser descrito em etapas, o que chamados de algoritmo. Isso é o que queremos praticar com você agora.

Algoritmo de um Agente Baseado em IA

Considere o famoso Jogo da Velha.

jogo_da_velha

Dois jogadores revezam-se jogando em um tabuleiro de três por três, conforme a figura acima. Um jogador joga Xs e o outro OS até que um jogador ganhe colocando três marcas em uma fileira, horizontal, vertical ou diagonal. Se o tabuleiro estiver totalmente preenchido e nenhum jogador conseguir três marcas, então o jogo fica empatado.

Vamos assumir que estamos jogando contra um jogador imperfeito, aquele cujo jogo às vezes está incorreto e nos permite vencer. Por enquanto, consideremos empates e perdas igualmente ruins para nós. Como podemos construir um agente de IA que encontrará as imperfeições no jogo de seu oponente e aprenderá a maximizar sua chances de ganhar?

Embora este seja um problema simples, ele não pode ser facilmente resolvido de maneira satisfatória. através de técnicas clássicas. Por exemplo, a solução clássica “minimax” da Teoria dos Jogos, não seria ideal aqui porque assume uma maneira particular de jogar pelo oponente. Por exemplo, um jogador minimax nunca chegaria a um estado de jogo do qual poderia perder, mesmo que, de fato, sempre tenha saído desse estado por causa de jogo incorreto do oponente.

Métodos clássicos de otimização para problemas de decisão sequenciais, como programação dinâmica, poderiam calcular uma solução ideal para qualquer oponente, mas exige como entrada, uma especificação completa desse oponente, incluindo as probabilidades com as quais o oponente faz cada jogada em cada estado do tabuleiro. Vamos supor que esta informação não está disponível a priori para esse problema, pois não existe para a grande maioria dos problemas de interesse prático.

Por outro lado, essas informações podem ser estimadas a partir da experiência, neste caso, jogando muitos jogos contra o oponente. O melhor que se pode fazer sobre esse problema é primeiro aprender um modelo do comportamento do oponente, até algum nível de confiança e, em seguida, aplicar a programação dinâmica para calcular uma solução ideal o modelo aproximado do oponente. No final, isso não é tão diferente de alguns dos métodos de aprendizado por reforço.

Um método evolutivo aplicado a esse problema pesquisaria diretamente o espaço de políticas possíveis para alguém com alta probabilidade de vencer o oponente. Aqui, uma política é uma regra que informa ao agente o que fazer para cada estado do jogo – todas as configurações possíveis de Xs e Os no tabuleiro três por três. Para cada política considerada, uma estimativa de sua probabilidade de vitória seria obtida jogando algum número de jogos contra o oponente. Essa avaliação direcionaria então quais políticas devem ser consideradas a seguir.

Um método evolutivo típico escalaria no espaço de políticas, gerando e avaliando sucessivamente políticas na tentativa de obter melhorias incrementais. Ou, talvez, um algoritmo genético possa ser usado para manter e avaliar uma população de políticas. Literalmente centenas de diferentes métodos de otimização podem ser aplicados.

Uma função de valor poderia ser um método eficaz nesse cenário. Aqui está como o problema do jogo da velha seria tratado com um método que faz uso de uma função de valor.

Primeiro, montaríamos uma tabela de números, uma para cada estado possível do jogo. Cada número será a estimativa mais recente da probabilidade de ganharmos nesse estado. Tratamos essa estimativa como o valor do estado, e toda a tabela é a função de valor aprendido. O estado A tem um valor mais alto que o estado B ou é considerado “melhor” do que o estado B, se a estimativa atual da probabilidade de ganharmos em A for maior do que em B. Supondo que sempre jogamos Xs, então para todos os estados com três Xs seguidos a probabilidade de ganhar é 1, porque já vencemos.

Da mesma forma, para todos os estados com três Os seguidos ou preenchidos, a probabilidade correta é 0, pois não podemos ganhar com eles. Definimos os valores iniciais de todos os outros estados para 0,5, representando que temos 50% de chance de ganhar.

Em seguida, jogamos muitos jogos contra o oponente. Para selecionar nossos movimentos, examinamos os estados que resultariam de cada um de nossos movimentos possíveis (um para cada espaço em branco no tabuleiro) e procuramos seus valores atuais na tabela. Na maioria das vezes nos movemos avidamente, selecionando o movimento que leva ao estado com maior valor, ou seja, com o maior valor de probabilidade estimada de vitória. Ocasionalmente, no entanto, selecionamos um movimento aleatoriamente. Estes são chamados movimentos exploratórios porque nos levam a ter uma experiência que, de outra forma, jamais poderíamos ter. Uma sequência de movimentos feitos e considerados durante um jogo podem ser diagramados como na figura abaixo:

agente

Poderíamos usar Deep Learning para realizar parte do aprendizado do processo descrito anteriormente e alimentar o agente com o resultado desse aprendizado. Isso é o que chamamos de Deep Reinforcement Learning.

Reinforcement Learning e Deep Reinforcement Learning são estudados na prática em Inteligência Artificial Aplicada a Finanças. Muitos robôs investidores usam Aprendizado por Reforço como técnica principal.

Continuaremos na parte 2. Acompanhe o próximo capítulo.

Referências:

Customizando Redes Neurais com Funções de Ativação Alternativas

A Beginner’s Guide to Deep Reinforcement Learning

What is reinforcement learning? The complete guide

Reinforcement learning

Reinforcement Learning, Second Edition

Applications of Reinforcement Learning in Real World

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 64 – Componentes do Aprendizado Por Reforço (Reinforcement Learning)

by

O Aprendizado Por Reforço pode ser entendido através de seus componentes: agente, ambiente, estados, ações e recompensas, todos os quais explicaremos neste capítulo. Letras maiúsculas indicarão conjuntos de objetos e letras minúsculas indicarão um objeto específico. Por exemplo: A são todas as ações possíveis, enquanto a é uma ação específica contida no conjunto.

Agente: um agente executa ações; por exemplo, um drone fazendo uma entrega ou Super Mario navegando em um videogame. O algoritmo é o agente. Pode ser útil considerar que, na vida, o agente é você.

Ação (A): A é o conjunto de todos os movimentos possíveis que o agente pode fazer. Uma ação é quase autoexplicativa, mas deve-se notar que os agentes geralmente escolhem de uma lista de ações possíveis e discretas. Nos videogames, a lista pode incluir correr para a direita ou para a esquerda, pular alto ou baixo, agachar-se ou ficar parado. Nos mercados de ações, a lista pode incluir a compra, venda ou manutenção de qualquer um de uma matriz de ativos financeiros e seus derivativos. Ao lidar com drones, as alternativas incluiriam muitas velocidades e acelerações diferentes no espaço 3D.

Fator de desconto: O fator de desconto é multiplicado por recompensas futuras, conforme descoberto pelo agente, a fim de amortecer o efeito dessas recompensas na escolha de ação do agente. Por quê? Ele foi projetado para fazer com que as recompensas futuras valham menos que as recompensas imediatas; isto é, aplica um tipo de hedonismo de curto prazo no agente. Geralmente expressa com a letra grega minúscula gama: γ. Se γ for 0,8 e houver uma recompensa de 10 pontos após três etapas de tempo, o valor atual dessa recompensa será de 0,8³ x 10. Um fator de desconto de 1 faria as recompensas futuras valerem tanto quanto as recompensas imediatas. Estamos lutando contra o imediatismo aqui. O agente deve escolher as ações que levam à melhor solução global possível, não apenas a melhor solução imediata.

Ambiente: O mundo pelo qual o agente se move e que responde ao agente. O ambiente toma o estado atual e a ação do agente como entrada e retorna como saída a recompensa do agente e seu próximo estado. Se você é o agente, o ambiente pode ser as leis da física e as regras da sociedade que processam suas ações e determinam as consequências delas.

Estado (S): Um estado é uma situação concreta e imediata em que o agente se encontra; ou seja, um local e momento específico, uma configuração instantânea que coloca o agente em relação a outras coisas importantes, como ferramentas, obstáculos, inimigos ou prêmios. Pode ser a situação atual retornada pelo ambiente ou qualquer situação futura. Você já esteve no lugar errado na hora errada? Isso é um estado.

Recompensa (R): Uma recompensa é o feedback pelo qual medimos o sucesso ou o fracasso das ações de um agente em um determinado estado. Por exemplo, em um videogame, quando Mario toca uma moeda, ele ganha pontos. A partir de qualquer estado, um agente envia a saída na forma de ações para o ambiente, e o ambiente retorna o novo estado do agente (que resultou da ação no estado anterior), bem como recompensas, se houver. As recompensas podem ser imediatas ou atrasadas. Eles avaliam efetivamente a ação do agente.

Política (π): A política é a estratégia que o agente emprega para determinar a próxima ação com base no estado atual. Ele mapeia estados para ações, as ações que prometem a maior recompensa.

Valor (V): O retorno esperado a longo prazo com desconto, em oposição à recompensa de curto prazo R. Vπ (s) é definido como o retorno esperado a longo prazo do estado atual sob a política π. Descontamos as recompensas ou diminuímos seu valor estimado, quanto mais futuro elas ocorrerem. E lembre-se de Keynes: “A longo prazo, estamos todos mortos”. É por isso que você desconta recompensas futuras. É útil distinguir.

Valor Q ou Valor da Ação (Q): O valor Q é semelhante ao Valor, exceto pelo fato de ser necessário um parâmetro extra, a ação atual a. Qπ (s, a) refere-se ao retorno a longo prazo de uma ação que executa uma ação sob política π do estado atual s. Q mapeia pares de ação e estado para recompensas. Observe a diferença entre Q e política.

Trajetória: Uma sequência de estados e ações que influenciam esses estados. A vida de um agente é apenas uma bola lançada alta e arqueando-se no espaço-tempo sem ser perturbada, como os humanos no mundo moderno.

Distinções Principais: Recompensa é um sinal imediato recebido em um determinado estado, enquanto valor é a soma de todas as recompensas que você pode antecipar desse estado. Valor é uma expectativa de longo prazo, enquanto recompensa é um prazer imediato. O valor é comer salada de espinafre no jantar, antecipando uma vida longa e saudável; recompensa é comer hamburguer com batata frita e refrigerante para o jantar e comprometer sua saúde futura. Eles diferem em seus horizontes temporais. Assim, você pode ter estados em que o valor e a recompensa divergem: você pode receber uma recompensa baixa e imediata (espinafre), mesmo quando se move para uma posição com grande potencial de valor a longo prazo; ou você pode receber uma alta recompensa imediata (hamburguer com batata frita e refrigerante) que leva à diminuição das perspectivas ao longo do tempo. É por isso que a função de valor, em vez de recompensas imediatas, é o que o aprendizado por reforço procura prever e controlar.

Portanto, ambientes são funções que transformam uma ação executada no estado atual no próximo estado e uma recompensa; agentes são funções que transformam o novo estado e recompensam na próxima ação. Podemos conhecer e definir a função do agente, mas na maioria das situações em que é útil e interessante aplicar o aprendizado por reforço, não sabemos a função do ambiente. É uma caixa preta onde só vemos as entradas e saídas. É como o relacionamento da maioria das pessoas com a tecnologia: sabemos o que faz, mas não sabemos como funciona. O aprendizado por reforço representa a tentativa de um agente de aproximar a função do ambiente, para que possamos enviar ações para o ambiente de caixa preta que maximize as recompensas que ele distribui.

 

simple_RL_schema

 

No loop de feedback acima, os subscritos indicam as etapas de tempo t e t + 1, cada uma das quais se refere a estados diferentes: o estado no momento t e o estado no momento t + 1. Diferente de outras formas de aprendizado de máquina – como aprendizado supervisionado e não supervisionado – o aprendizado por reforço só pode ser pensado sequencialmente em termos de pares de ação de estado que ocorrem um após o outro.

O aprendizado por reforço julga as ações pelos resultados que elas produzem. É orientado a objetivos, e seu objetivo é aprender sequências de ações que levarão um agente a atingir seu objetivo ou maximizar sua função objetivo. aqui estão alguns exemplos:

Nos videogames, o objetivo é terminar o jogo com mais pontos, para que cada ponto adicional obtido ao longo do jogo afete o comportamento subsequente do agente; ou seja, o agente pode aprender que deve atirar em navios de guerra, tocar em moedas ou desviar de meteoros para maximizar sua pontuação.

No mundo real, o objetivo pode ser que um robô viaje do ponto A ao ponto B, e cada centímetro que o robô é capaz de se aproximar do ponto B pode ser contado como pontos. Aqui está um exemplo de uma função objetiva para o aprendizado por reforço; ou seja, a maneira como define seu objetivo:

reinforcementlearning_objective

Estamos somando a função de recompensa r sobre t, que significa etapas de tempo. Portanto, essa função objetivo calcula toda a recompensa que poderíamos obter executando, digamos, um jogo. Aqui, x é o estado em um determinado momento, a é a ação executada nesse estado e r é a função de recompensa para x e a.

Outro exemplo é a otimização de portfólios financeiros (uma das principais aplicações atuais da Aprendizagem Por Reforço). Dado o volume de movimentação de diversos ativos financeiros, o agente procura a melhor combinação possível de investimentos que garanta o maior retorno financeiro no longo prazo. Essa é a tecnologia por trás dos Robôs Investidores e que ensinamos em detalhes em Inteligência Artificial Aplicada a Finanças.

Quer aprender um pouco da Matemática desta incrível técnica de aprendizagem de máquina e como ela se relaciona com Deep Learning? Então acompanhe os próximos capítulos.

Referências:

Customizando Redes Neurais com Funções de Ativação Alternativas

A Beginner’s Guide to Deep Reinforcement Learning

What is reinforcement learning? The complete guide

Reinforcement learning

Applications of Reinforcement Learning in Real World

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 63 – Aplicações da Aprendizagem Por Reforço no Mundo Real

by

Enquanto as Redes Neurais Convolucionais (CNNs) e as Redes Neurais Recorrentes (RNNs) estão se tornando cada vez mais importantes para as empresas devido às suas aplicações em Visão Computacional e Processamento de Linguagem Natural, o Aprendizado por Reforço como uma estrutura para a neurociência computacional de um modelo para o processo de tomada de decisão parece estar subvalorizado. A Aprendizagem Por Reforço não deve ser negligenciada no espaço da pesquisa corporativa, dados seus enormes potenciais em auxiliar na tomada de decisões.

O Aprendizado por Reforço (ou Reinforcement Learning – RL), conhecido como modelo de aprendizado semi-supervisionado em Machine Learning, é uma técnica para permitir que um agente tome ações e interaja com um ambiente, a fim de maximizar as recompensas totais. Aprendizado por Reforço é geralmente modelado como um Processo de Decisão de Markov (MDP) e estudaremos isso em mais detalhes nos capítulos seguintes.

Mas aqui vai uma explicação bem simples e objetiva para ajudar a compreender o conceito:

Imagine que um bebê recebe um controle remoto da TV em sua casa (ambiente). Em termos simples, o bebê (agente) primeiro observará e construirá sua própria representação do ambiente (estado). Em seguida, o bebê curioso executará certas ações, como pressionar o controle remoto (ação) e observará a resposta da TV (próximo estado). Como uma TV não responde e é monótona, o bebê não gosta dela (recebendo uma recompensa negativa) e realiza menos ações que levarão a esse resultado (atualização da política) e vice-versa. O bebê repetirá o processo até encontrar uma política (o que fazer em diferentes circunstâncias) com a qual está satisfeito (maximizar as recompensas totais (com desconto)). Isso é o Aprendizado por Reforço. Lembre-se que em Machine Learning o que fazemos é tentar reproduzir o aprendizado humano através de diferentes técnicas.

O estudo da Aprendizagem Por Reforço é construir uma estrutura matemática para resolver problemas. Por exemplo, para encontrar uma boa política, poderíamos usar métodos baseados em valores, como Q-learning, para medir o quão boa é uma ação em um determinado estado ou métodos baseados em políticas para descobrir diretamente quais ações executar em diferentes estados sem saber quão boas as ações são.

No entanto, os problemas que enfrentamos no mundo real podem ser extremamente complicados de várias maneiras diferentes e, portanto, um algoritmo típico de Aprendizagem Por Reforço não tem nenhuma pista para resolver. Por exemplo, o espaço de estado é muito grande no jogo do GO, o ambiente não pode ser totalmente observado no jogo de pôquer e há muitos agentes interagindo entre si no mundo real. Os pesquisadores inventaram métodos para resolver alguns dos problemas usando redes neurais profundas para modelar as políticas desejadas, funções de valor ou mesmo os modelos de transição, que, portanto, são chamados de Aprendizado por Reforço Profundo (Deep Reinforcement Learning). 

Mas abordaremos tudo isso em detalhes mais a frente. Por hora, vejamos algumas das principais aplicações da Aprendizagem Por Reforço.

Gerenciamento de Recursos em Clusters de Computadores

Projetar algoritmos para alocar recursos limitados a diferentes tarefas é desafiador e requer heurísticas geradas por humanos. O artigo “Gerenciamento de recursos com aprendizado por reforço profundo” explica como usar o RL para aprender automaticamente a alocar e programar recursos de computador para jobs em espera, com o objetivo de minimizar a desaceleração média do job (tarefa).

O espaço de estados foi formulado como a alocação de recursos atual e o perfil de recursos dos jobs. Para o espaço de ação, eles usaram um truque para permitir que o agente escolha mais de uma ação a cada etapa do tempo. A recompensa era a soma de (-1 / duração do job) em todos os jobs no sistema. Em seguida, eles combinaram o algoritmo REINFORCE e o valor da linha de base para calcular os gradientes da política e encontrar os melhores parâmetros de política que fornecem a distribuição de probabilidade das ações para minimizar o objetivo. 

Controle de Semáforo

No artigo “Sistema multiagente baseado em aprendizado por reforço para controle de sinais de tráfego de rede”, os pesquisadores tentaram projetar um controlador de semáforo para resolver o problema de congestionamento. Testados apenas em ambiente simulado, seus métodos mostraram resultados superiores aos métodos tradicionais e lançaram uma luz sobre os possíveis usos da RL de múltiplos agentes no projeto de sistemas de tráfego.

Cinco agentes foram colocados na rede de tráfego de cinco cruzamentos, com um agente RL no cruzamento central para controlar a sinalização de tráfego. O estado foi definido como um vetor de oito dimensões, com cada elemento representando o fluxo de tráfego relativo de cada faixa. Oito opções estavam disponíveis para o agente, cada uma representando uma combinação de fases, e a função de recompensa foi definida como redução no atraso em comparação com o passo anterior. Os autores usaram o DQN para aprender o valor Q dos pares {state, action}.

Robótica

Há um incrível trabalho na aplicação de RL em robótica. Recomendamos a leitura desse paper com o resultado de uma pesquisa de RL em robótica. Neste outro trabalho, os pesquisadores treinaram um robô para aprender políticas para mapear imagens de vídeo brutas para as ações do robô. As imagens RGB foram alimentadas em uma CNN e as saídas foram os torques do motor. O componente RL era a pesquisa de política guiada para gerar dados de treinamento provenientes de sua própria distribuição de estado.

Configuração de Sistemas Web

Existem mais de 100 parâmetros configuráveis ​​em um Sistema Web e o processo de ajuste dos parâmetros requer um operador qualificado e vários testes de rastreamento e erro. O artigo “Uma abordagem de aprendizado por reforço à auto-configuração do sistema Web on-line” mostrou a primeira tentativa no domínio sobre como fazer a reconfiguração autônoma de parâmetros em sistemas web multicamada em ambientes dinâmicos baseados em VM.

O processo de reconfiguração pode ser formulado como um MDP finito. O espaço de estado era a configuração do sistema, o espaço de ação era {aumentar, diminuir, manter} para cada parâmetro e a recompensa era definida como a diferença entre o tempo de resposta pretendido e o tempo de resposta medido. Os autores usaram o algoritmo de Q-learning para executar a tarefa.

Embora os autores tenham usado alguma outra técnica, como a inicialização de políticas, para remediar o grande espaço de estados e a complexidade computacional do problema, em vez das combinações potenciais de RL e rede neural, acredita-se que o trabalho pioneiro tenha preparado o caminho para futuras pesquisas nessa área. .

Química

O RL também pode ser aplicado na otimização de reações químicas. Pesquisadores mostraram que seu modelo superou um algoritmo de última geração e generalizou para mecanismos subjacentes diferentes no artigo “Otimizando reações químicas com aprendizado de reforço profundo”.

Combinado com o LSTM para modelar a função de política, o agente RL otimizou a reação química com o processo de decisão de Markov (MDP) caracterizado por {S, A, P, R}, em que S era o conjunto de condições experimentais (como temperatura, pH, etc), A foi o conjunto de todas as ações possíveis que podem alterar as condições experimentais, P foi a probabilidade de transição da condição atual da experiência para a próxima condição e R foi a recompensa que é uma função do estado.

A aplicação é excelente para demonstrar como a RL pode reduzir o trabalho demorado e de tentativa e erro em um ambiente relativamente estável.

Recomendações Personalizadas

O trabalho de recomendações de notícias sempre enfrentou vários desafios, incluindo a dinâmica de mudança rápida das notícias, os usuários que se cansam facilmente e a Taxa de Cliques que não pode refletir a taxa de retenção de usuários. Guanjie et al. aplicaram RL no sistema de recomendação de notícias em um documento intitulado “DRN: Uma Estrutura de Aprendizado de Reforço Profundo para Recomendação de Notícias” para combater os problemas.

Na prática, eles construíram quatro categorias de recursos, a saber: A) recursos do usuário, B) recursos de contexto como os recursos de estado do ambiente, C) recursos de notícias do usuário e D) recursos de notícias como os recursos de ação. Os quatro recursos foram inseridos na Deep Q-Network (DQN) para calcular o valor Q. Uma lista de notícias foi escolhida para recomendar com base no valor Q, e o clique do usuário nas notícias foi parte da recompensa que o agente da RL recebeu. 

Os autores também empregaram outras técnicas para resolver outros problemas desafiadores, incluindo repetição de memória, modelos de sobrevivência, Dueling Bandit Gradient Descent e assim por diante. 

Leilões e Publicidade

Pesquisadores do Alibaba Group publicaram um artigo “Leilões em tempo real com aprendizado de reforço de agentes múltiplos em publicidade gráfica” e afirmaram que sua solução distribuída de agentes múltiplos baseada em cluster (DCMAB) alcançou resultados promissores e, portanto, planejam realizar uma teste ao vivo na plataforma Taobao.

De um modo geral, a plataforma de anúncios Taobao é um local para os comerciantes fazerem um lance para exibir anúncios para os clientes. Isso pode ser um problema de vários agentes, porque os comerciantes fazem lances uns contra os outros e suas ações são inter-relacionadas. No artigo, comerciantes e clientes foram agrupados em diferentes grupos para reduzir a complexidade computacional. O espaço de estado dos agentes indicava o status de custo-receita dos agentes, o espaço de ação era o lance (contínuo) e a recompensa era a receita causada pelo cluster de clientes.

Talvez você esteja curioso por saber como seria o algoritmo para resolver esse tipo de problema. Aqui está o algoritmo criado pelos pesquisadores (mais detalhes no paper da pesquisa, no link anterior):

Jogos

A RL é tão conhecida hoje em dia porque é o algoritmo convencional usado para resolver jogos diferentes e às vezes alcançar um desempenho super-humano.

O mais famoso deve ser AlphaGo e AlphaGo Zero. O AlphaGo, treinado com inúmeros jogos humanos, já alcançou um desempenho super-humano usando a rede de valor e a pesquisa de árvores Monte Carlo (MCTS) em sua rede de políticas. No entanto, os pesquisadores tentaram uma abordagem mais pura da RL – treinando-a do zero. Os pesquisadores deixaram o novo agente, AlphaGo Zero, jogar sozinho e finalmente derrotar o AlphaGo 100-0.

Aprendizagem Profunda (Deep Learning)

Mais e mais tentativas de combinar RL e outras arquiteturas de aprendizado profundo podem ser vistas recentemente e mostraram resultados impressionantes.

Um dos trabalhos mais influentes da RL é o trabalho pioneiro da Deepmind para combinar a CNN com a RL. Ao fazer isso, o agente tem a capacidade de “ver” o ambiente por meio de sensores de alta dimensão e depois aprender a interagir com ele.

RL e RNN são outras combinações usadas pelas pessoas para tentar novas ideias. RNN é um tipo de rede neural que possui “memórias”. Quando combinada com a RL, a RNN oferece aos agentes a capacidade de memorizar as coisas. Por exemplo, combinaram LSTM com RL para criar uma profunda rede Q recorrente (DRQN) para jogar jogos do Atari 2600. Também usaram RNN e RL para resolver problemas de otimização de reações químicas.

O Deepmind mostrou como usar modelos generativos e RL para gerar programas. No modelo, o agente treinado adversamente usou o sinal como recompensa para melhorar as ações, em vez de propagar os gradientes para o espaço de entrada como no treinamento da GAN. Incrível, não?

O Que Você Precisa Saber Antes de Aplicar a RL ao seu Problema?

Existem várias coisas necessárias para que a RL possa ser aplicada.

Entendendo seu problema: Você não precisa necessariamente usar RL no seu problema e, às vezes, simplesmente não pode usá-lo. Convém verificar se o seu problema possui algumas das seguintes características antes de decidir usar a RL:

  • a) tentativa e erro (você pode aprender a fazer melhor recebendo comentários do ambiente);
  • b) recompensas atrasadas;
  • c) pode ser modelado como MDP;
  • d) seu problema é um problema de controle.

Um ambiente simulado: Muitas iterações são necessárias antes que um algoritmo RL funcione. Tenho certeza de que você não quer ver um agente de RL tentando coisas diferentes em um carro autônomo em uma rodovia, certo? Portanto, é necessário um ambiente simulado que possa refletir corretamente o mundo real.

MDP: Seu mundo precisa formular seu problema em um MDP. Você precisa projetar o espaço de estado, o espaço de ação, a função de recompensa e assim por diante. Seu agente fará o que é recompensado sob as restrições. Você pode não obter os resultados desejados se projetar as coisas de maneira diferente.

Algoritmos: Existem diferentes algoritmos de RL que você pode escolher e perguntas a serem feitas. Você deseja descobrir diretamente a política ou deseja aprender a função de valor? Você quer ir livre de modelo ou baseado em modelo? Você precisa combinar outros tipos de rede ou métodos neurais profundos para resolver seus problemas?

Intuições de Outras Disciplinas

RL tem uma relação muito estreita com psicologia, biologia e neurociência. Se você pensar bem, o que um agente de RL faz é apenas tentativa e erro: aprende o quão bom ou ruim suas ações são baseadas nas recompensas que recebe do ambiente. E é exatamente assim que o ser humano aprende a tomar uma decisão. Além disso, o problema de exploração, o problema de cessão de recompensa/penalidade, as tentativas de modelar o ambiente também são algo que enfrentamos em nossa vida cotidiana.

A teoria da economia também pode lançar alguma luz sobre RL. Em particular, a análise da aprendizagem de reforço multi-agente (MARL) pode ser entendida a partir das perspectivas da teoria dos jogos, que é uma área de pesquisa desenvolvida por John Nash para entender as interações de agentes em um sistema. Além da teoria dos jogos, o MARL, Processo de Decisão Markov Parcialmente Observável (POMDP) ​​também pode ser útil para entender outros tópicos econômicos, como estrutura de mercado (por exemplo, monopólio, oligopólio, etc.), externalidade e assimetria de informação. 

O que a Aprendizagem Por Reforço Pode Alcançar no Futuro?

A Aprendizagem Por Reforço seria influente e impactante das seguintes maneiras:

Assistência humana: Talvez seja exagero dizer que a RL pode um dia evoluir para inteligência geral artificial (AGI), mas a RL certamente tem o potencial de ajudar e trabalhar com pessoas. Imagine um robô ou um assistente virtual trabalhando com você e levando suas ações em consideração para executar ações a fim de alcançar um objetivo comum. Não seria ótimo?

Entendendo as consequências de diferentes estratégias: A vida é incrível, porque o tempo não volta e as coisas acontecem apenas uma vez. No entanto, às vezes gostaríamos de saber como as coisas poderiam ser diferentes (pelo menos a curto prazo) se eu adotasse uma ação diferente. A Croácia teria uma chance maior de ganhar a Copa do Mundo de 2018 se o treinador usasse outra estratégia? Obviamente, para conseguir isso, precisaríamos modelar perfeitamente o ambiente, as funções de transição e assim por diante e também analisar as interações entre os agentes.

As possibilidade são muitas e por isso Inteligência Artificial é um dos temas mais quentes do momento e os profissionais atentos a isso, ficarão com as melhores oportunidades. Continuaremos no próximo capítulo!

Referências:

Inteligência Artificial Aplicada a Finanças

Customizando Redes Neurais com Funções de Ativação Alternativas

What is reinforcement learning? The complete guide

Reinforcement learning

Applications of Reinforcement Learning in Real World

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 62 – O Que é Aprendizagem Por Reforço?

by

Todas as arquiteturas de Deep Learning que estudamos até aqui neste livro podem ser classificadas em duas categorias de aprendizagem de máquina (você já sabe que Deep Learning é sub-categoria de Machine Learning, que por sua vez é uma sub-categoria de Inteligência Artificial): 

  • Aprendizagem Supervisionada – quando apresentamos ao algoritmo dados de entrada e as respectivas saídas.
  • Aprendizagem Não Supervisionada – quando apresentamos somente os dados de entrada e o algoritmo descobre as saídas.

Mas existe uma terceira categoria de aprendizagem, chamada de Aprendizagem Por Reforço (ou Reinforcement Learning), muito usada em Games e Robótica e que vem obtendo resultados cada vez melhores. A Aprendizagem Por Reforço é a principal técnica por trás do AlphaGo e está muito bem retratada no documentário do mesmo nome: AlphaGo.

Serão diversos capítulos dedicados a esta técnica e à sua extensão, o Deep Reinforcement Learning. Vamos começar definindo o que é Aprendizagem Por Reforço.

O Que é Aprendizagem Por Reforço?

A Aprendizagem Por Reforço é o treinamento de modelos de aprendizado de máquina para tomar uma sequência de decisões. O agente aprende a atingir uma meta em um ambiente incerto e potencialmente complexo. No aprendizado por reforço, o sistema de inteligência artificial enfrenta uma situação. O computador utiliza tentativa e erro para encontrar uma solução para o problema. Para que a máquina faça o que o programador deseja, a inteligência artificial recebe recompensas ou penalidades pelas ações que executa. Seu objetivo é maximizar a recompensa total.

Embora o Cientista de Dados ou o Engenheiro de IA defina a política de recompensa – isto é, as regras do jogo – ele não dá ao modelo nenhuma dica ou sugestão de como resolver o jogo. Cabe ao modelo descobrir como executar a tarefa para maximizar a recompensa, começando com testes totalmente aleatórios e terminando com táticas sofisticadas. Ao alavancar o poder da pesquisa e de muitas tentativas, o aprendizado por reforço é atualmente a maneira mais eficaz de sugerir a criatividade da máquina. Ao contrário dos seres humanos, a inteligência artificial pode reunir experiência de milhares de jogos paralelos se um algoritmo de aprendizado por reforço for executado em uma infraestrutura de computador suficientemente poderosa.

Exemplo:

O problema é o seguinte: Temos um agente e uma recompensa, com muitos obstáculos no meio, como nesta imagem abaixo. O agente deve encontrar o melhor caminho possível para alcançar a recompensa e quando encontrar um obstáculo, deve ser penalizado (pois ele deve escolher o caminho sem obstáculos). Com a Aprendizagem Por Reforço, podemos treinar o agente para encontrar o melhor caminho.

rl

Desafios do Aprendizado Por Reforço

O principal desafio do aprendizado por reforço está na preparação do ambiente de simulação, que depende muito da tarefa a ser executada. Quando o modelo é treinado em jogos de Xadrez, Go ou Atari, a preparação do ambiente de simulação é relativamente simples. Quando se trata de construir um modelo capaz de dirigir um carro autônomo, a construção de um simulador realista é crucial antes de deixar o carro andar na rua. O modelo precisa descobrir como frear ou evitar uma colisão em um ambiente seguro. Transferir o modelo do ambiente de treinamento para o mundo real é onde as coisas ficam complicadas.

Escalar e ajustar a rede neural que controla o agente é outro desafio. Não há como se comunicar com a rede a não ser através do sistema de recompensas e penalidades. Isso pode levar a um esquecimento catastrófico, em que a aquisição de novos conhecimentos faz com que alguns dos antigos sejam apagados da rede. Ou seja, precisamos guardar o aprendizado na “memória” do agente.

Outro desafio é alcançar um ótimo local – ou seja, o agente executa a tarefa como está, mas não da maneira ideal ou necessária. Um “saltador” pulando como um canguru em vez de fazer o que se esperava dele com pequenos saltos é um ótimo exemplo. Por fim, existem agentes que otimizarão o prêmio sem executar a tarefa para a qual foram projetados. 

O Que Distingue o Aprendizado Por Reforço do Aprendizado Profundo e do Aprendizado de Máquina?

De fato, não há uma divisão clara entre aprendizado de máquina, aprendizado profundo e aprendizado por reforço. É como uma relação paralelogramo – retângulo – quadrado, em que o aprendizado de máquina é a categoria mais ampla e o aprendizado por reforço é o mais estreito.

Da mesma forma, o aprendizado por reforço é uma aplicação especializada de técnicas de Deep Learning e Machine Learning, projetada para resolver problemas de uma maneira específica.

Embora as ideias pareçam divergir, não há uma divisão acentuada entre esses subtipos. Além disso, eles se mesclam nos projetos, pois os modelos são projetados para não se ater ao “tipo puro”, mas para executar a tarefa da maneira mais eficaz possível. Portanto, “o que distingue precisamente o aprendizado de máquina, o aprendizado profundo e o aprendizado por reforço” é, na verdade, uma pergunta difícil de responder. Mas vamos definir cada um deles!

Aprendizado de Máquina é uma forma de IA na qual os computadores têm a capacidade de melhorar progressivamente o desempenho de uma tarefa específica com dados, sem serem diretamente programados. Essa é a definição de Arthur Lee Samuel. Ele cunhou o termo “aprendizado de máquina”, do qual existem dois tipos, aprendizado de máquina supervisionado e não supervisionado.

O aprendizado de máquina supervisionado acontece quando um programador pode fornecer um rótulo para cada entrada de treinamento no sistema de aprendizado de máquina.

O aprendizado não supervisionado ocorre quando o modelo é fornecido apenas com os dados de entrada, mas sem rótulos explícitos. Ele precisa pesquisar os dados e encontrar a estrutura ou os relacionamentos ocultos. O Cientista de Dados pode não saber qual é a estrutura ou o que o modelo de aprendizado de máquina irá encontrar.

O Aprendizado Profundo consiste em várias camadas de redes neurais, projetadas para executar tarefas mais sofisticadas. A construção de modelos de aprendizado profundo foi inspirada no design do cérebro humano, mas simplificada. Os modelos de aprendizado profundo consistem em algumas camadas de rede neural que são, em princípio, responsáveis por aprender gradualmente recursos mais abstratos sobre dados específicos.

Embora as soluções de aprendizado profundo sejam capazes de fornecer resultados maravilhosos, em termos de escala, elas não são páreo para o cérebro humano. Cada camada usa o resultado de uma anterior como entrada e toda a rede é treinada como um todo. O conceito central de criar uma rede neural artificial não é novo, mas apenas recentemente o hardware moderno forneceu energia computacional suficiente para treinar efetivamente essas redes, expondo um número suficiente de exemplos. A adoção estendida trouxe estruturas como TensorFlow, Keras e PyTorch, as quais tornaram a construção de modelos de aprendizado de máquina muito mais conveniente.

O Aprendizado Por Reforço, como declarado acima, emprega um sistema de recompensas e penalidades para obrigar o computador a resolver um problema sozinho. O envolvimento humano é limitado à mudança do ambiente e ao ajuste do sistema de recompensas e penalidades. Como o computador maximiza a recompensa, ele está propenso a procurar maneiras inesperadas de fazê-lo. O envolvimento humano é focado em impedir que ele explore o sistema e motive a máquina a executar a tarefa da maneira esperada. O aprendizado por reforço é útil quando não existe uma “maneira adequada” de executar uma tarefa, mas existem regras que o modelo deve seguir para desempenhar corretamente suas tarefas. Abaixo a performance de um agente sendo treinado em um jogo clássico do Atari.

Performance inicial do agente:

breakout_0

Após 15 minutos de treinamento:

breakout_1

Após 30 minutos de treinamento:

breakout_2

Em particular, se a inteligência artificial vai dirigir um carro ou aprender a jogar alguns clássicos do Atari, pode ser considerado um marco intermediário significativo. Uma aplicação potencial do aprendizado por reforço em veículos autônomos é uma das aplicações mais trabalhadas nos dias de hoje em todo mundo. Um desenvolvedor é incapaz de prever todas as situações futuras da estrada, portanto, deixar o modelo treinar-se com um sistema de penalidades e recompensas em um ambiente variado é possivelmente a maneira mais eficaz da IA ampliar a experiência que possui e coleta e assim aprender a conduzir um veículo autônomo sem que seja explicitamente programada para isso.

Continuaremos no próximo capítulo!

Referências:

Inteligência Artificial Aplicada a Finanças

Customizando Redes Neurais com Funções de Ativação Alternativas

What is reinforcement learning? The complete guide

Reinforcement learning

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 61 – A Matemática dos Variational Autoencoders (VAEs)

by

No capítulo anterior, fornecemos a seguinte visão geral intuitiva: Os VAEs são Autoencoders que codificam entradas como distribuições em vez de pontos e cuja “organização” do espaço latente é regularizada restringindo as distribuições retornadas pelo codificador a estarem próximas de um gaussiano padrão. Neste capítulo, forneceremos uma visão matemática dos VAEs que nos permitirá justificar o termo de regularização com mais rigor. Para isso, definiremos uma estrutura probabilística clara e usaremos, em particular, a técnica de inferência variacional.

A base matemática e estatística por trás dos conceitos deste capítulo pode ser obtida na Formação Análise Estatística. 

Estrutura Probabilística e Premissas

Vamos começar definindo um modelo gráfico probabilístico para descrever nossos dados. Denotamos por x a variável que representa nossos dados e assumimos que x é gerado a partir de uma variável latente z (a representação codificada) que não é diretamente observada. Assim, para cada ponto de dados, é assumido o seguinte processo generativo de duas etapas:

  • Primeiro, uma representação latente z é amostrada da distribuição anterior p(z).
  • Segundo, os dados x são amostrados da distribuição de probabilidade condicional definido por p(x | z).

Com esse modelo probabilístico em mente, podemos redefinir nossas noções de codificador e decodificador. De fato, ao contrário de um Autoencoder simples que considera codificador e decodificador determinístico, consideraremos agora versões probabilísticas desses dois objetos. O “decodificador probabilístico” é definido naturalmente por p(x | z), que descreve a distribuição da variável decodificada dada a codificada, enquanto o “codificador probabilístico” é definido por p(z | x), que descreve a distribuição de a variável codificada, dada a decodificada.

Neste ponto, já podemos notar que a regularização do espaço latente que nos faltava em Autoencoders simples aparece naturalmente aqui na definição do processo de geração de dados: presume-se que representações codificadas z no espaço latente sigam a distribuição anterior p(z). Caso contrário, também podemos lembrar o conhecido teorema de Bayes, que faz a ligação entre o anterior p(z), a probabilidade p(x | z) e o posterior p(z | x):

form1

Vamos agora assumir que p(z) é uma distribuição gaussiana padrão e que p(x | z) é uma distribuição gaussiana cuja média é definida por uma função determinística f da variável de z e cuja matriz de covariância tem a forma de uma constante positiva c que multiplica a matriz de identidade I. Supõe-se que a função f pertence a uma família de funções denotadas F que é deixada não especificada no momento e que será escolhida posteriormente. Assim, temos:

form2

Vamos considerar, por enquanto, que f está bem definido e fixo. Em teoria, como conhecemos p(z) e p(x | z), podemos usar o Teorema de Bayes para calcular p(z | x): este é um problema clássico de inferência bayesiana. No entanto, esse tipo de computação geralmente é intratável (por causa da integral no denominador) e requer o uso de técnicas de aproximação, como inferência variacional.

Nota: Aqui podemos mencionar que p(z) e p(x | z) são ambas distribuições gaussianas, implicando que p(z | x) também deve seguir uma distribuição gaussiana. Em teoria, poderíamos “apenas” tentar expressar a média e a matriz de covariância de p(z | x) com relação às médias e às matrizes de covariância de p(z) e p(x | z). No entanto, na prática, esses valores dependem da função f que pode ser complexa e que não está definida por enquanto (mesmo que tenhamos assumido o contrário). Além disso, o uso de uma técnica de aproximação como inferência variacional torna a abordagem bastante geral e mais robusta a algumas mudanças na hipótese do modelo.

Formulação de Inferência Variacional

Em Estatística, a inferência variacional é uma técnica para aproximar distribuições complexas. A ideia é definir uma família de distribuição parametrizada (por exemplo, a família de Gaussianos, cujos parâmetros são a média e a covariância) e procurar a melhor aproximação de nossa distribuição de destino entre essa família. O melhor elemento da família é aquele que minimiza uma determinada medição de erro de aproximação (na maioria das vezes a divergência de Kullback-Leibler entre aproximação e alvo) e é encontrada por descida do gradiente sobre os parâmetros que descrevem a família. Para mais detalhes, você encontra um artigo sobe isso na seção de referências ao final do capítulo.

Aqui vamos aproximar p(z | x) por uma distribuição gaussiana q_x(z) cuja média e covariância são definidas por duas funções, g e h, do parâmetro x. Essas duas funções devem pertencer, respectivamente, às famílias de funções G e H que serão especificadas mais tarde, mas que devem ser parametrizadas. Assim, podemos denotar:

form3

Portanto, definimos dessa maneira uma família de candidatos à inferência variacional e precisamos agora encontrar a melhor aproximação entre essa família otimizando as funções g e h (de fato, seus parâmetros) para minimizar a divergência de Kullback-Leibler entre a aproximação e o alvo p(z | x). Em outras palavras, estamos procurando a aproximação ideal g* e h* de modo que:

 

form4

 

Na penúltima equação, podemos observar a troca existente – ao aproximar-se do p(z | x) posterior – entre maximizar a probabilidade das “observações” (maximização da probabilidade logarítmica esperada para o primeiro termo) e permanecer próximo à distribuição anterior (minimização da divergência de KL entre q_x(z) e p(z), para o segundo termo). Essa troca é natural para o problema de inferência bayesiana e expressa o equilíbrio que precisa ser encontrado entre a confiança que temos nos dados e a confiança que temos no passado.

Até agora, assumimos a função f conhecida e fixa e mostramos que, com tais premissas, podemos aproximar o p(z | x) posterior usando a técnica de inferência variacional. No entanto, na prática, essa função f, que define o decodificador, não é conhecida e também precisa ser escolhida. Para fazer isso, lembre-se de que nosso objetivo inicial é encontrar um esquema de codificação e decodificação com desempenho, cujo espaço latente seja regular o suficiente para ser usado para fins generativos. Se a regularidade é regida principalmente pela distribuição anterior assumida no espaço latente, o desempenho do esquema geral de codificação / decodificação depende muito da escolha da função f.

De fato, como p(z | x) pode ser aproximado (por inferência variacional) de p(z) e p(x | z) e como p(z) é um gaussiano padrão simples, as duas únicas alavancas que temos à nossa disposição em nosso modelo para fazer otimizações são o parâmetro c (que define a variância da probabilidade) e a função f (que define a média da probabilidade).

Portanto, vamos considerar que, como discutimos anteriormente, podemos obter para qualquer função f em F (cada uma definindo um decodificador probabilístico diferente p(x | z)) a melhor aproximação de p(z | x), denotada q*_x(z) Apesar de sua natureza probabilística, estamos procurando um esquema de codificação-decodificação o mais eficiente possível e, em seguida, queremos escolher a função f que maximize a probabilidade logarítmica esperada de x dado z quando z é amostrado de q*_x(z) Em outras palavras, para uma dada entrada x, queremos maximizar a probabilidade de ter x̂ = x quando amostramos z da distribuição q*_x(z) e depois amostramos x̂ da distribuição p(x | z). Assim, procuramos o f* ideal para que:

form5

onde q*_x (z) depende da função f e é obtido como descrito anteriormente. Reunindo todas as peças, estamos procurando as aproximações f*,  g* e h* ideais para que:

 

form6

 

Podemos identificar nesta função objetivo os elementos introduzidos na descrição intuitiva dos VAEs dados no capítulo anterior: o erro de reconstrução entre x e f(z) e o termo de regularização dado pela divergência KL entre q_x(z) e p(z) ) (que é um gaussiano padrão). Também podemos notar a constante c que regula o equilíbrio entre os dois termos anteriores. Quanto maior c for, mais assumimos uma alta variação em torno de f(z) para o decodificador probabilístico em nosso modelo e, portanto, mais favorecemos o termo de regularização sobre o termo de reconstrução (e o oposto se c for baixo).

Trazendo Redes Neurais Para o Modelo

Até o momento, definimos um modelo probabilístico que depende de três funções, f, g e h, e expressamos, usando inferência variacional, o problema de otimização a ser resolvido para obter f*, g* e h* que ofereçam o melhor esquema de codificação-decodificação com este modelo. Como não podemos otimizar facilmente todo o espaço de funções, restringimos o domínio de otimização e decidimos expressar f, g e h como redes neurais. Assim, F, G e H correspondem, respectivamente, às famílias de funções definidas pelas arquiteturas de rede e a otimização é feita sobre os parâmetros dessas redes. 

Na prática, g e h não são definidos por duas redes completamente independentes, mas compartilham uma parte de sua arquitetura e seus pesos, de modo que temos:

 

form7

 

Como isso define a matriz de covariância de q_x(z), h(x) deve ser uma matriz quadrada. Entretanto, para simplificar o cálculo e reduzir o número de parâmetros, assumimos que nossa aproximação de p(z | x), q_x(z), é uma distribuição gaussiana multidimensional com matriz de covariância diagonal (assunção de independência de variáveis). Com essa suposição, h(x) é simplesmente o vetor dos elementos diagonais da matriz de covariância e, então, tem o mesmo tamanho de g(x). No entanto, reduzimos dessa maneira a família de distribuições que consideramos para inferência variacional e, portanto, a aproximação de p(z | x) obtida pode ser menos precisa.

form8

Ao contrário da parte do codificador que modela p(z | x) e para a qual consideramos um gaussiano com média e covariância que são funções de x(g e h), nosso modelo assume para p(x | z) um gaussiano com covariância. A função f da variável z que define a média desse gaussiano é modelada por uma rede neural e pode ser representada da seguinte forma:

form9

A arquitetura geral é então obtida concatenando o codificador e as partes do decodificador. No entanto, ainda precisamos ter muito cuidado com a maneira como coletamos amostras da distribuição retornada pelo codificador durante o treinamento. O processo de amostragem deve ser expresso de forma a permitir que o erro seja retropropagado pela rede. Um truque simples, chamado truque de reparametrização, é usado para tornar possível a descida do gradiente, apesar da amostragem aleatória que ocorre na metade da arquitetura e consiste em usar o fato de que se z é uma variável aleatória após uma distribuição gaussiana com média g(x) e com covariância h(x), pode ser expresso como:

form10

form11

Finalmente, a função objetivo da arquitetura de Autoencoder Variacional obtida dessa maneira é dada pela última equação da subseção anterior, na qual a expectativa teórica é substituída por uma aproximação de Monte-Carlo mais ou menos precisa que consiste, na maioria das vezes, em um sorteio único. Assim, considerando essa aproximação e denotando C = 1 / (2c), recuperamos a função de perda derivada intuitivamente na seção anterior, composta por um termo de reconstrução, um termo de regularização e uma constante para definir os pesos relativos desses dois termos.

form12

Autoencoders Variacionais (VAEs) são Autoencoders que resolvem o problema da irregularidade do espaço latente, fazendo com que o codificador retorne uma distribuição sobre o espaço latente em vez de um único ponto e adicionando à função de perda um termo de regularização sobre a distribuição retornada para garantir uma melhor organização do espaço latente assumindo um modelo probabilístico simples para descrever nossos dados, a função de perda bastante intuitiva dos VAEs, composta por um termo de reconstrução e um termo de regularização, pode ser cuidadosamente derivada, usando em particular a técnica estatística de inferência variacional (daí o nome Autoencoder “Variacional”).

Para concluir, podemos destacar que, durante os últimos anos, as GANs se beneficiaram de muito mais contribuições científicas do que os VAEs. Entre outras razões, o maior interesse demonstrado pela comunidade por GANs pode ser parcialmente explicado pelo maior grau de complexidade na base teórica dos VAEs (modelo probabilístico e inferência variacional) em comparação à simplicidade do conceito de treinamento adversário que rege os GANs. Com este capítulo, esperamos que tenhamos compartilhado intuições valiosas e fortes fundamentos teóricos para tornar os VAEs mais acessíveis aos recém-chegados. No entanto, agora que discutimos em profundidade os dois, resta uma pergunta … qual arquitetura você achou mais interessante, GANs ou VAEs?

No próximo capítulo começamos a estudar a Aprendizagem Por Reforço! Até lá.

Referências:

Formação Análise Estatística

Customizando Redes Neurais com Funções de Ativação Alternativas

Autoencoders – Unsupervised Learning

Bayesian inference problem, MCMC and variational inference

Understanding Variational Autoencoders (VAEs)

Deep inside: Autoencoders

Deep Learning — Different Types of Autoencoders

Contractive Auto-Encoders – Explicit Invariance During Feature Extraction

Stacked Denoising Autoencoders: Learning Useful Representations in a Deep Network with a Local Denoising Criterion

Introduction to Autoencoders

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Deep Learning Book

Capítulo 60 – Variational Autoencoders (VAEs) – Definição, Redução de Dimensionalidade, Espaço Latente e Regularização

by

Nos últimos anos, modelos generativos baseados em aprendizado profundo ganharam cada vez mais interesse devido a (e implicando) algumas melhorias surpreendentes em Inteligência Artificial. Contando com uma enorme quantidade de dados, arquiteturas de rede bem projetadas e técnicas de treinamento inteligentes, os modelos generativos profundos demonstraram uma capacidade incrível de produzir peças de conteúdo altamente realistas de vários tipos, como imagens, textos e sons. Entre esses modelos, duas famílias principais se destacam e merecem uma atenção especial: Redes Adversárias Generativas (GANs) e Autoencoders Variacionais (VAEs). O primeiro já estudamos e agora estudaremos o segundo.

Em um capítulo anterior, discutimos em profundidade as Redes Adversárias Generativas (GANs) e mostramos, em particular, como o treinamento antagônico pode opor duas redes, um gerador e um discriminador, para pressionar ambas a melhorar iteração após iteração. Apresentamos agora, neste capítulo, outro tipo de modelo generativo profundo: Autoencoders Variacionais (VAEs – Variational Autoencoders).

Em resumo, um VAE é um Autoencoder cuja distribuição de codificações é regularizada durante o treinamento, a fim de garantir que seu espaço latente tenha boas propriedades, o que nos permite gerar novos dados. Além disso, o termo “variacional” vem da estreita relação que existe entre a regularização e o método de inferência variacional em Estatística. 

Mas o conceito por trás dos VAEs também pode levantar muitas questões. Qual é o espaço latente e por que regularizá-lo? Como gerar novos dados a partir dos VAEs? Qual é a ligação entre VAEs e inferência variacional? Para descrever os VAEs da melhor maneira possível, tentaremos responder a todas essas perguntas (e muitas outras!) e fornecer a você o máximo de informação e conhecimento possível (variando de intuições básicas a detalhes matemáticos mais avançados). Assim, o objetivo deste capítulo não é apenas discutir as noções fundamentais dos Variational Autoencoders (VAEs), mas também construir passo a passo e começar desde o início o raciocínio que leva a essas noções (como sempre fazemos em nossos cursos na Data Science Academy). E vamos começar com o conceito de redução de dimensionalidade.

O Que é Redução de Dimensionalidade?

No aprendizado de máquina, a redução de dimensionalidade é o processo de redução do número de recursos (atributos) que descrevem alguns dados. Essa redução é feita por seleção (apenas alguns recursos existentes são conservados) ou por extração (um número reduzido de novos recursos é criado com base nos recursos antigos) e pode ser útil em muitas situações que exigem dados de baixa dimensionalidade (visualização de dados, armazenamento, computação pesada, etc…). Embora existam muitos métodos diferentes de redução de dimensionalidade, podemos definir uma estrutura global que seja compatível com a maioria desses métodos.

Primeiro, vamos codificar o processo que produz a representação de “novos recursos” a partir da representação de “recursos antigos” (por seleção ou por extração) e decodificar o processo inverso. A redução de dimensionalidade pode então ser interpretada como compactação de dados, onde o codificador compacta os dados (do espaço inicial para o espaço codificado, também chamado de espaço latente) enquanto o decodificador os descompacta. Obviamente, dependendo da distribuição inicial dos dados, da dimensão do espaço latente e da definição do codificador, essa compactação pode ser perdida, o que significa que uma parte da informação é perdida durante o processo de codificação e não pode ser recuperada durante a decodificação.

reduc

O principal objetivo de um método de redução de dimensionalidade é encontrar o melhor par codificador / decodificador entre uma determinada família. Em outras palavras, para um determinado conjunto de codificadores e decodificadores possíveis, estamos procurando o par que mantém o máximo de informações ao codificar e, portanto, tem o mínimo de erro de reconstrução ao decodificar. Se denotarmos respectivamente E e D as famílias de codificadores e decodificadores que estamos considerando, o problema da redução de dimensionalidade pode ser escrito:

form1

Onde:

form2

define a medida do erro de reconstrução entre os dados de entrada x e os dados codificados e decodificados d (e (x)). 

Análise de Componentes Principais (PCA) e Autoencoders

Um dos primeiros métodos que vêm à mente quando se fala em redução de dimensionalidade é a análise de componentes principais (PCA). Para mostrar como ele se encaixa na estrutura que acabamos de descrever e criar o link para os Autoencoders, vamos dar uma visão geral de como o PCA funciona, deixando a maioria dos detalhes de lado (caso queira estudar o PCA em detalhes e na prática, há um capítulo inteiro dedicado a esta técnica em Matemática Para Data Science) .

A ideia do PCA é construir novos recursos independentes, que são combinações lineares dos novos recursos antigos e, de modo que as projeções dos dados no subespaço definido por esses novos recursos sejam o mais próximo possível dos dados iniciais (em termos de distância euclidiana). Em outras palavras, o PCA está procurando o melhor subespaço linear do espaço inicial (descrito por uma base ortogonal de novos recursos), de modo que o erro de aproximar os dados por suas projeções nesse subespaço seja o menor possível.

Traduzido em nossa estrutura global, procuramos um codificador na família E das matrizes n_e por n_d (transformação linear) cujas linhas são ortonormais (independência de recursos) e pelo decodificador associado entre a família D de matrizes n_d por n_e. Pode-se mostrar que os autovetores unitários correspondentes aos n_e maiores autovalores (em norma) da matriz de características de covariância são ortogonais (ou podem ser escolhidos assim) e definem o melhor subespaço da dimensão n_e para projetar dados com erro mínimo de aproximação. Assim, esses n_e autovetores podem ser escolhidos como nossos novos recursos e, portanto, o problema de redução de dimensão pode ser expresso como um problema de autovalor / autovetor. Além disso, também pode ser mostrado que, nesse caso, a matriz decodificadora é a transposta da matriz codificadora (se esses conceitos de Matemática parecem estranhos a você recomendamos Matemática Para Data Science).

Os Autoencoders são em essência, redes neurais para redução de dimensionalidade. A ideia geral dos Autoencoders é bastante simples e consiste em definir um codificador e um decodificador como redes neurais e aprender o melhor esquema de codificação-decodificação usando um processo de otimização iterativo. Assim, a cada iteração, alimentamos a arquitetura do autoencoder (o codificador seguido pelo decodificador) com alguns dados, comparamos a saída decodificada com os dados iniciais e retropropagamos o erro na arquitetura para atualizar os pesos das redes.

Assim, intuitivamente, a arquitetura geral do autoencoder (codificador + decodificador) cria um gargalo de dados que garante que apenas a parte estruturada principal da informação possa passar e ser reconstruída. Observando nossa estrutura geral, a família E dos codificadores considerados é definida pela arquitetura da rede do codificador, a família D dos decodificadores considerados é definida pela arquitetura da rede do decodificador e a busca do codificador e decodificador que minimiza o erro de reconstrução é feita por descida do gradiente sobre os parâmetros dessas redes.

autoencoder

Vamos primeiro supor que nossas arquiteturas de codificador e decodificador tenham apenas uma camada sem não linearidade (autoencoder linear). Esse codificador e decodificador são transformações lineares simples que podem ser expressas como matrizes. Em tal situação, podemos ver um vínculo claro com o PCA no sentido de que, assim como o PCA, estamos procurando o melhor subespaço linear para projetar dados com o mínimo de perda de informações possível ao fazê-lo. As matrizes de codificação e decodificação obtidas com o PCA definem naturalmente uma das soluções que gostaríamos de alcançar por descida do gradiente, mas devemos destacar que essa não é a única. De fato, várias bases podem ser escolhidas para descrever o mesmo subespaço ideal e, portanto, vários pares de codificador / decodificador podem fornecer o erro de reconstrução ideal. Além disso, para autoencoders lineares e, ao contrário do PCA, os novos recursos não precisam ser independentes (sem restrições de ortogonalidade nas redes neurais).

Agora, vamos supor que o codificador e o decodificador sejam profundos e não lineares. Nesse caso, quanto mais complexa a arquitetura, mais o autoencoder pode prosseguir para uma alta redução de dimensionalidade, mantendo baixa a perda de reconstrução. Intuitivamente, se nosso codificador e nosso decodificador tiver graus de liberdade suficientes, podemos reduzir qualquer dimensionalidade inicial para 1. De fato, um codificador com “poder infinito” poderia teoricamente pegar nossos N pontos de dados iniciais e codificá-los como 1, 2, 3, … até N (ou mais geralmente, como N inteiro no eixo real) e o decodificador associado pode fazer a transformação reversa, sem perda durante o processo.

Aqui, porém, devemos ter duas coisas em mente. Primeiro, uma importante redução de dimensionalidade sem perda de reconstrução costuma ter um preço: a falta de estruturas interpretáveis ​​e exploráveis ​​no espaço latente (falta de regularidade). Segundo, na maioria das vezes, o objetivo final da redução da dimensionalidade não é apenas reduzir o número de dimensões dos dados, mas reduzir esse número de dimensões, mantendo a maior parte das informações da estrutura de dados nas representações reduzidas. Por essas duas razões, a dimensão do espaço latente e a “profundidade” dos autoencoders (que definem o grau e a qualidade da compressão) devem ser cuidadosamente controladas e ajustadas, dependendo do objetivo final da redução da dimensionalidade.

Variational Autoencoders (VAEs)

No capítulo 58 introduzimos o conceito de Autoencoders, que são arquiteturas de codificador-decodificador que podem ser treinadas por descida do gradiente. Vamos agora fazer o link com o problema de geração de conteúdo, ver as limitações dos Autoencoders em sua forma atual para esse problema e introduzir os Autoencoders Variacionais.

Limitações de Autoencoders para Geração de Conteúdo

Nesse ponto, uma pergunta natural que vem à mente é “qual é o link entre os Autoencoders e a geração de conteúdo?”. De fato, uma vez que o Autoencoder foi treinado, temos um codificador e um decodificador, mas ainda não há uma maneira real de produzir qualquer novo conteúdo. À primeira vista, poderíamos ficar tentados a pensar que, se o espaço latente for regular o suficiente (bem “organizado” pelo codificador durante o processo de treinamento), poderíamos pegar um ponto aleatoriamente nesse espaço latente e decodificá-lo para obter um novo conteúdo. O decodificador agiria mais ou menos como o gerador de uma Rede Adversária Generativa .

vae

No entanto, a regularidade do espaço latente para Autoencoders é um ponto difícil que depende da distribuição dos dados no espaço inicial, da dimensão do espaço latente e da arquitetura do codificador. Portanto, é bastante difícil (se não impossível) garantir, a priori, que o codificador organize o espaço latente de maneira inteligente, compatível com o processo generativo que acabamos de descrever.

Para ilustrar esse ponto, vamos considerar o exemplo no qual descrevemos um codificador e um decodificador suficientemente poderosos para colocar N dados de treinamento inicial no eixo real (cada ponto de dados sendo codificado como um valor real) e decodificá-los sem nenhum perda de reconstrução. Nesse caso, o alto grau de liberdade do Autoencoder que possibilita a codificação e decodificação sem perda de informações (apesar da baixa dimensionalidade do espaço latente) leva a uma super adaptação severa, o que implica que alguns pontos do espaço latente fornecerão conteúdo sem sentido uma vez decodificado. Se esse exemplo unidimensional tiver sido voluntariamente escolhido para ser extremo, podemos notar que o problema da regularidade espacial latente dos Autoencoders é muito mais geral do que isso e merece uma atenção especial.

vae2

Ao pensar nisso por um minuto, essa falta de estrutura entre os dados codificados no espaço latente é bastante normal. De fato, o Autoencoder é treinado apenas para codificar e decodificar com o mínimo de perdas possível, independentemente da organização do espaço latente. Portanto, se não tomarmos cuidado com a definição da arquitetura, é natural que, durante o treinamento, a rede aproveite todas as possibilidades de sobreajuste para realizar sua tarefa da melhor forma possível … a menos que a regularizemos explicitamente!

Definição de Autoencoders Variacionais

Portanto, para poder usar o decodificador de nosso autoencoder para fins generativos, precisamos ter certeza de que o espaço latente é regular o suficiente. Uma solução possível para obter essa regularidade é introduzir regularização explícita durante o processo de treinamento. Assim, como mencionamos brevemente na introdução deste capítulo, um autoencoder variacional pode ser definido como um autoencoder cujo treinamento é regularizado para evitar sobreajuste e garantir que o espaço latente tenha boas propriedades que possibilitem processos generativos.

Assim como um autoencoder padrão, um autoencoder variacional é uma arquitetura composta por um codificador e um decodificador, treinada para minimizar o erro de reconstrução entre os dados decodificados e os dados iniciais. No entanto, para introduzir alguma regularização do espaço latente, procedemos a uma ligeira modificação do processo de codificação / decodificação: em vez de codificar uma entrada como um único ponto, a codificamos como uma distribuição no espaço latente. O modelo é treinado da seguinte maneira:

  • Primeiro, a entrada é codificada como distribuição no espaço latente.
  • Segundo, um ponto do espaço latente é amostrado a partir dessa distribuição.
  • Terceiro, o ponto amostrado é decodificado e o erro de reconstrução pode ser calculado.
  • Finalmente, o erro de reconstrução é retropropagado pela rede.

vae3

Na prática, as distribuições codificadas são escolhidas para serem normais, de modo que o codificador possa ser treinado para retornar a média e a matriz de covariância que descrevem esses gaussianos. A razão pela qual uma entrada é codificada como uma distribuição com alguma variância em vez de um único ponto é que torna possível expressar muito naturalmente a regularização do espaço latente: as distribuições retornadas pelo codificador são impostas para estarem próximas a uma distribuição normal padrão. Veremos na próxima subseção que garantimos dessa maneira uma regularização local e global do espaço latente (local por causa do controle de variância e global por causa do controle médio).

Assim, a função de perda que é minimizada ao treinar um VAE é composta de um “termo de reconstrução” (na camada final), que tende a tornar o esquema de codificação-decodificação o mais eficiente possível e um “termo de regularização” (no camada latente), que tende a regularizar a organização do espaço latente, tornando as distribuições retornadas pelo codificador próximas a uma distribuição normal padrão. Esse termo de regularização é expresso como a divergência de Kulback-Leibler entre a distribuição retornada e uma gaussiana padrão e será mais justificado na próxima seção. Podemos notar que a divergência de Kullback-Leibler entre duas distribuições gaussianas tem uma forma fechada que pode ser expressa diretamente em termos das médias e das matrizes de covariância das duas distribuições.

vae4

Intuições Sobre a Regularização

A regularidade que se espera do espaço latente para possibilitar o processo generativo pode ser expressa por meio de duas propriedades principais: continuidade (dois pontos de fechamento no espaço latente não devem fornecer dois conteúdos completamente diferentes uma vez decodificados) e integridade (para uma distribuição escolhida , um ponto amostrado no espaço latente deve fornecer conteúdo “significativo” depois de decodificado).

O único fato de que os VAEs codificam entradas como distribuições, em vez de pontos simples, não é suficiente para garantir continuidade e integridade. Sem um termo de regularização bem definido, o modelo pode aprender, a fim de minimizar seu erro de reconstrução, “ignorar” o fato de que as distribuições são retornadas e se comportam quase como os autoencoders clássicos (levando ao super ajuste). Para fazer isso, o codificador pode retornar distribuições com pequenas variações (que tendem a ser distribuições pontuais) ou retornar distribuições com meios muito diferentes (que ficariam muito distantes um do outro no espaço latente). Nos dois casos, as distribuições são usadas da maneira errada (cancelando o benefício esperado) e a continuidade e / ou a integridade não são satisfeitas.

Portanto, para evitar esses efeitos, precisamos regularizar a matriz de covariância e a média das distribuições retornadas pelo codificador. Na prática, essa regularização é feita impondo distribuições para estar perto de uma distribuição normal padrão (centralizada e reduzida). Dessa forma, exigimos que as matrizes de covariância estejam próximas da identidade, impedindo distribuições pontuais e com a média próxima de 0, impedindo que as distribuições codificadas estejam muito distantes umas das outras.

Com esse termo de regularização, impedimos que o modelo codifique dados distantes no espaço latente e incentivamos o máximo possível as distribuições retornadas a “se sobrepor”, satisfazendo dessa maneira as condições de continuidade e integridade esperadas. Naturalmente, como em qualquer termo de regularização, isso tem o preço de um erro de reconstrução mais alto nos dados de treinamento. A troca entre o erro de reconstrução e a divergência de KL pode, no entanto, ser ajustada e veremos no próximo capítulo como a expressão emerge naturalmente de nossa derivação formal.

Para concluir, podemos observar que a continuidade e a integridade obtidas com a regularização tendem a criar um “gradiente” sobre as informações codificadas no espaço latente. Por exemplo, um ponto do espaço latente que estaria a meio caminho entre as médias de duas distribuições codificadas provenientes de diferentes dados de treinamento deve ser decodificado em algo que esteja em algum lugar entre os dados que deram a primeira distribuição e os dados que deram a segunda distribuição como pode ser amostrado pelo autoencoder em ambos os casos.

Essa é uma das arquiteturas mais avançadas de Deep Learning e para uma melhor compreensão, precisamos da nossa amiga, a Matemática. No próximo capítulo traremos um pouco da Matemática por trás dos VAEs. Até lá.

Referências:

Formação Engenheiro de Inteligência Artificial

Formação Análise Estatística

Formação Cientista de Dados

Customizando Redes Neurais com Funções de Ativação Alternativas

Autoencoders – Unsupervised Learning

Understanding Variational Autoencoders (VAEs)

Deep inside: Autoencoders

Deep Learning — Different Types of Autoencoders

Contractive Auto-Encoders – Explicit Invariance During Feature Extraction

Stacked Denoising Autoencoders: Learning Useful Representations in a Deep Network with a Local Denoising Criterion

Introduction to Autoencoders

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 58 – Introdução aos Autoencoders

by

Até aqui neste livro descrevemos arquiteturas de redes neurais profundas (Deep Learning) usadas em aprendizagem supervisionada, na qual rotulamos exemplos de treinamento, fornecendo ao algoritmo dados de entrada (X) e de saída (Y). Agora, suponha que tenhamos apenas um conjunto de exemplos de treinamento não rotulados {x1, x2, x3,…}, onde x (i) ∈ℜn. Uma rede neural Autoencoder é um algoritmo de aprendizado não supervisionado que aplica backpropagation, definindo os valores de destino como iguais às entradas. Ou seja, usa y (i) = x (i). Estudaremos essa arquitetura de Deep Learning a partir de agora.

O que são Autoencoders?

Os Autoencoders são uma técnica de aprendizado não supervisionado, na qual usamos as redes neurais para a tarefa de aprendizado de representação. Especificamente, projetaremos uma arquitetura de rede neural de modo a impor um gargalo na rede que força uma representação de conhecimento compactada da entrada original. Se os recursos de entrada fossem independentes um do outro, essa compressão e reconstrução subsequente seriam uma tarefa muito difícil. No entanto, se houver algum tipo de estrutura nos dados (ou seja, correlações entre os recursos de entrada), essa estrutura poderá ser aprendida e consequentemente aproveitada ao forçar a entrada através do gargalo da rede.

Autoencoders (AE) são redes neurais que visam copiar suas entradas para suas saídas. Eles trabalham compactando a entrada em uma representação de espaço latente e, em seguida, reconstruindo a saída dessa representação. Esse tipo de rede é composto de duas partes:

Codificador (Encoder): é a parte da rede que compacta a entrada em uma representação de espaço latente (codificando a entrada). Pode ser representado por uma função de codificação h = f (x).

Decodificador (Decoder): Esta parte tem como objetivo reconstruir a entrada da representação do espaço latente. Pode ser representado por uma função de decodificação r = g (h).

 

mushroom_encoder

 

O Autoencoder tenta aprender uma função h W, b (x) ≈ x. Em outras palavras, ele está tentando aprender uma aproximação com a função de identidade, de modo a gerar x’ semelhante a x. A função de identidade parece uma função particularmente trivial para tentar aprender; mas colocando restrições na rede, como limitando o número de unidades ocultas, podemos descobrir uma estrutura interessante sobre os dados. Como um exemplo concreto, suponha que as entradas x sejam os valores de intensidade de pixel de uma imagem 10 × 10 (100 pixels), portanto n = 100 e haja s = 50 unidades ocultas na camada L2. Observe que também temos y∈ℜ100. Como existem apenas 50 unidades ocultas, a rede é forçada a aprender uma representação “compactada” da entrada. Ou seja, dado apenas o vetor de ativações de unidades ocultas, ele deve tentar ”reconstruir” a entrada de 100 pixels x. Se a entrada fosse completamente aleatória – digamos, cada xi provém de um ID Gaussiano independente dos outros recursos, essa tarefa de compactação seria muito difícil. Mas se houver estrutura nos dados, por exemplo, se alguns dos recursos de entrada estiverem correlacionados, esse algoritmo poderá descobrir algumas dessas correlações. De fato, esse Autoencoder simples geralmente acaba aprendendo uma representação de baixa dimensão muito semelhante aos PCAs (Principal Component Analysis).

Nosso argumento acima se baseava no número de unidades ocultas s sendo pequenas. Mas mesmo quando o número de unidades ocultas é grande (talvez até maior que o número de pixels de entrada), ainda podemos descobrir uma estrutura interessante, impondo outras restrições à rede. Em particular, se impusermos uma restrição de “esparsidade” nas unidades ocultas, o Autoencoder ainda descobrirá uma estrutura interessante nos dados, mesmo que o número de unidades ocultas seja grande.

 

autoencoders

 

Por que copiar a entrada para a saída?

Se o único objetivo dos Autoencoders fosse copiar a entrada para a saída, eles seriam inúteis. De fato, esperamos que, treinando o Autoencoder para copiar a entrada para a saída, a representação latente h tenha propriedades úteis.

Isso pode ser conseguido criando restrições na tarefa de cópia. Uma maneira de obter recursos úteis do Autoencoder é restringir h a ter dimensões menores que x; nesse caso, o Autoencoder é chamado de incompleto. Ao treinar uma representação incompleta, forçamos o Autoencoder a aprender os recursos mais importantes dos dados de treinamento. Se for dada muita capacidade ao Autoencoder, ele poderá aprender a executar a tarefa de cópia sem extrair nenhuma informação útil sobre a distribuição dos dados. Isso também pode ocorrer se a dimensão da representação latente for a mesma que a entrada e, no caso de excesso de conclusão, em que a dimensão da representação latente for maior que a entrada.

Nesses casos, mesmo um codificador linear e um decodificador linear podem aprender a copiar a entrada na saída sem aprender nada útil sobre a distribuição de dados. Idealmente, alguém poderia treinar qualquer arquitetura de Autoencoder com sucesso, escolhendo a dimensão do código e a capacidade do codificador e decodificador com base na complexidade da distribuição a ser modelada.

Para que são usados ​​os Autoencoders?

Atualmente, o denoising de dados (remoção de ruídos) e a redução de dimensionalidade para visualização de dados são considerados duas principais aplicações práticas interessantes de Autoencoders. Com restrições de dimensionalidade e esparsidade apropriadas, os Autoencoders podem aprender projeções de dados mais interessantes que o PCA ou outras técnicas básicas.

Os Autoencoders aprendem automaticamente a partir de exemplos de dados. Isso significa que é fácil treinar instâncias especializadas do algoritmo que terão bom desempenho em um tipo específico de entrada e que não requer nenhuma nova engenharia de recursos, apenas os dados de treinamento apropriados.

Outra aplicação dos Autoencoders é como tarefa preliminar ao reconhecimento de imagens com CNNs (Redes Neurais Convolucionais). Observando a imagem acima você percebe que a saída do Autoencoder é a imagem do número 4 muito mais suave. Ou seja, aplicamos os Autoencoders para remover ruído dos dados (denoising) e depois usamos a saída dos Autoencoders para treinar um modelo CNN.

Os Autoencoders são treinados para preservar o máximo de informações possível quando uma entrada é passada pelo codificador e depois pelo decodificador, mas também são treinados para fazer com que a nova representação tenha várias propriedades agradáveis. Diferentes tipos de Autoencoders visam atingir diferentes tipos de propriedades. 

Referências:

Deep Learning Para Aplicações de IA com PyTorch e Lightning

Customizando Redes Neurais com Funções de Ativação Alternativas

Autoencoders – Unsupervised Learning

Deep inside: Autoencoders

Introduction to Autoencoders

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 57 – Os Detalhes Matemáticos das GANs (Generative Adversarial Networks)

by

Neste capítulo vamos concluir nosso estudo das GANs com os detalhes matemáticos, antes de avançar para outra arquitetura de Deep Learning que estudaremos na sequência. Estamos considerando que você leu os capítulos anteriores sobre GANs.

A modelagem de redes neurais requer essencialmente definir duas coisas: uma arquitetura e uma função de perda. Já descrevemos a arquitetura de redes adversárias generativas. Consiste em duas redes:

  1. Uma rede generativa G que recebe uma entrada aleatória z com densidade p_z e retorna uma saída x_g = G (z) que deve seguir (após o treinamento) a distribuição de probabilidade alvo.
  2. Uma rede discriminativa D que recebe uma entrada x que pode ser uma entrada “verdadeira” (x_t, cuja densidade é denotada p_t) ou uma entrada “gerada” (x_g, cuja densidade p_g é a densidade induzida pela densidade p_z através de G) e que retorna a probabilidade D (x) de x para ser um dado “verdadeiro”.

Vamos agora examinar mais de perto a função de perda “teórica” das GANs. Se enviarmos ao discriminador dados “verdadeiros” e “gerados” nas mesmas proporções, o erro absoluto esperado do discriminador poderá ser expresso como:

 

form1

 

O objetivo do gerador é enganar o discriminador cujo objetivo é ser capaz de distinguir entre dados verdadeiros e dados gerados. Portanto, ao treinar o gerador, queremos maximizar esse erro enquanto tentamos minimizá-lo para o discriminador. Isso nos dá a fórmula abaixo:

form2

Para qualquer gerador G (juntamente com a densidade de probabilidade induzida p_g), o melhor discriminador possível é aquele que minimiza a integral abaixo:

 

form3

 

Para minimizar (em relação a D) essa integral, podemos minimizar a função dentro da integral para cada valor de x. Em seguida, definimos o melhor discriminador possível para um determinado gerador:

form4

(de fato, um dos melhores porque x valores tais que p_t (x) = p_g (x) podem ser manipulados de outra maneira, mas isso não importa para o que segue). Em seguida, pesquisamos G que maximiza:

 

form5

 

Parece complexo? É menos do que parece e explicamos sobre os fundamentos matemáticos por trás dessas fórmulas no curso Matemática Para Data Science. Novamente, para maximizar (em relação a G) essa integral, podemos maximizar a função dentro da integral para cada valor de x. Como a densidade p_t é independente do gerador G, não podemos fazer melhor do que definir G de modo que:

form7

Obviamente, como p_g é uma densidade de probabilidade que deve se integrar a 1, necessariamente temos o melhor G:

 

form8

 

Assim, mostramos que, em um caso ideal com gerador e discriminador de capacidade ilimitada, o ponto ideal do cenário adversário é tal que o gerador produz a mesma densidade que a densidade real e o discriminador não pode fazer melhor do que ser verdadeiro em um caso a cada dois, exatamente como a intuição nos disse. Por fim, observe também que G maximiza:

 

form6

 

Na fórmula acima vemos que G deseja maximizar a probabilidade esperada de o discriminador estar errado.

Conclusão Sobre as GANs

As GANs são bem recentes e possuem uma ideia inovadora sobre como treinar uma arquitetura de rede neural. Muitos estudos e aplicações vem sendo feitos em todo mundo e já existem até algumas aplicações comerciais usando essa arquitetura de Deep Learning. Caso queira aprender a construir GANs na prática, acesse aqui.

Pontos mais importantes sobre as GANs:

  • Computadores podem basicamente gerar variáveis ​​pseudo-aleatórias simples (por exemplo, eles podem gerar variáveis ​​que seguem muito de perto uma distribuição uniforme).
  • Existem maneiras diferentes de gerar variáveis ​​aleatórias mais complexas, incluindo a noção de “método de transformação” que consiste em expressar uma variável aleatória em função de algumas variáveis ​​aleatórias mais simples.
  • No aprendizado de máquina, os modelos generativos tentam gerar dados de uma determinada distribuição de probabilidade (complexa). Modelos generativos de aprendizado profundo são modelados como redes neurais (funções muito complexas) que recebem como entrada uma variável aleatória simples e retornam uma variável aleatória que segue a distribuição direcionada (como “método de transformação”).
  • Essas redes generativas podem ser treinadas “diretamente” (comparando a distribuição dos dados gerados com a verdadeira distribuição): esta é a ideia das redes correspondentes generativas
  • Essas redes generativas também podem ser treinadas “indiretamente” (tentando enganar outra rede treinada ao mesmo tempo para distinguir dados “gerados” de dados “verdadeiros”): essa é a ideia das redes adversas generativas.
  • Mesmo que o “hype” que rodeia os GANs seja talvez um pouco exagerado, podemos dizer que a ideia de treinamento antagônico sugerida por Ian Goodfellow e seus co-autores é realmente ótima. Essa maneira de distorcer a função de perda, passando de uma comparação direta para uma indireta, é realmente algo que pode ser muito inspirador para futuros trabalhos na área de aprendizado profundo.

Referências:

Análise Estatística Para Data Science com Linguagem Python

Customizando Redes Neurais com Funções de Ativação Alternativas

A Beginner’s Guide to Generative Adversarial Networks (GANs)

A Leap into the Future: Generative Adversarial Networks

Understanding Generative Adversarial Networks (GANs)

How A.I. Is Creating Building Blocks to Reshape Music and Art

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Deep Learning Book

Capítulo 56 – Modelos Generativos – O Diferencial das GANs (Generative Adversarial Networks)

by

Neste capítulo discutiremos o funcionamento dos modelos generativos, o principal diferencial nas GANs (Generative Adversarial Networks). Estamos considerando que você leu o capítulo anterior.

Suponha que estamos interessados ​​em gerar imagens quadradas em preto e branco de cães com um tamanho de n por n pixels. Podemos remodelar cada dado como um vetor dimensional N = n x n (empilhando colunas umas sobre as outras), de modo que uma imagem de cachorro possa ser representada por um vetor (quem sabe conseguimos criar um modelo capaz de diferenciar um Muffin de um Chihuahua).

 

dogs

 

No entanto, isso não significa que todos os vetores representem um cão que foi moldado de volta a um quadrado! Portanto, podemos dizer que os vetores dimensionais N que efetivamente geram algo que se parece com um cachorro são distribuídos de acordo com uma distribuição de probabilidade muito específica em todo o espaço vetorial dimensional N (alguns pontos desse espaço provavelmente representam cães, enquanto é improvável para alguns outros). No mesmo espírito, existe, nesse espaço vetorial dimensional N, distribuições de probabilidade para imagens de gatos, pássaros e assim por diante.

Então, o problema de gerar uma nova imagem do cão é equivalente ao problema de gerar um novo vetor após a “distribuição de probabilidade do cão” no espaço vetorial dimensional N. De fato, estamos enfrentando um problema de gerar uma variável aleatória com relação a uma distribuição de probabilidade específica (lembra do que discutimos no capítulo anterior?).

Neste ponto, podemos mencionar duas coisas importantes. Primeiro, a “distribuição de probabilidade canina” que mencionamos é uma distribuição muito complexa em um espaço muito grande. Segundo, mesmo se pudermos assumir a existência de tal distribuição subjacente (na verdade existem imagens que se parecem com cachorro e outras que não), obviamente não sabemos como expressar explicitamente essa distribuição. Os dois pontos anteriores dificultam bastante o processo de geração de variáveis ​​aleatórias a partir dessa distribuição. Vamos tentar resolver esses dois problemas a seguir.

Nosso primeiro problema ao tentar gerar nossa nova imagem de cachorro é que a “distribuição de probabilidade do cachorro” no espaço vetorial dimensional N é muito complexa e não sabemos como gerar diretamente variáveis ​​aleatórias complexas. No entanto, como sabemos muito bem como gerar N variáveis ​​aleatórias uniformes não correlacionadas, poderíamos fazer uso do método de transformação. Para fazer isso, precisamos expressar nossa variável aleatória N dimensional como resultado de uma função muito complexa aplicada a uma variável aleatória N dimensional simples!

Aqui, podemos enfatizar o fato de que encontrar a função de transformação não é tão simples quanto tomar a inversa de forma fechada da Função de Distribuição Cumulativa (que obviamente não sabemos) como fizemos ao descrever o método de transformação inversa no capítulo anterior. A função de transformação não pode ser expressa explicitamente e, então, precisamos aprender com os dados (essa é uma das razões pelas quais treinamos um modelo de Machine Learning e esse conceito é estudado em detalhes aqui).

Em seguida, a ideia é modelar a função de transformação por uma rede neural que tome como entrada uma variável aleatória uniforme N dimensional simples e que retorne como saída outra variável aleatória N dimensional que deve seguir, após o treinamento, a “distribuição de probabilidade canina” correta . Depois que a arquitetura da rede foi projetada, ainda precisamos treiná-la. Nas próximas duas seções, discutiremos duas maneiras de treinar essas redes generativas, incluindo a ideia de treinamento antagônico por trás das GANs!

 

model1

 

Redes de Correspondência Generativa (Generative Matching Networks)

Obs: a denominação de “redes de correspondência generativa” não é padrão. No entanto, podemos encontrar na literatura, por exemplo, “Redes de correspondência de momentos generativos” ou também “Redes de correspondência de recursos generativos”. Só queremos aqui usar uma denominação um pouco mais geral para o que descrevemos abaixo.

Treinando Modelos Generativos

Até agora, mostramos que nosso problema de gerar uma nova imagem de cachorro pode ser reformulado em um problema de gerar um vetor aleatório no espaço vetorial dimensional N que segue a “distribuição de probabilidade canina” e sugerimos o uso de um método de transformação , com uma rede neural para modelar a função de transformação.

Agora, ainda precisamos treinar (otimizar) a rede para expressar a função de transformação correta. Para isso, podemos sugerir dois métodos diferentes de treinamento: um direto e um indireto. O método de treinamento direto consiste em comparar as distribuições de probabilidade verdadeira e gerada e retropropagar a diferença (o erro) através da rede. Essa é a ideia que governa as redes de correspondência generativa (GMNs – Generative Matching Networks)).

Para o método de treinamento indireto, não comparamos diretamente as distribuições verdadeiras e geradas. Em vez disso, treinamos a rede generativa, fazendo com que essas duas distribuições passem por um ajuste escolhido de forma que o processo de otimização da rede generativa em relação à tarefa ajustada imponha que a distribuição gerada esteja próxima da verdadeira distribuição. Essa última ideia é a que está por trás das Redes Adversárias Generativas (GANs) que apresentaremos na próxima seção. Mas, por enquanto, vamos começar com o método direto e as GMNs.

Comparando duas distribuições de probabilidade com base em amostras

Como mencionado, a ideia das GMNs é treinar a rede generativa comparando diretamente a distribuição gerada com a verdadeira. No entanto, não sabemos como expressar explicitamente a verdadeira “distribuição de probabilidade de cães” e também podemos dizer que a distribuição gerada é complexa demais para ser expressa explicitamente. Portanto, comparações baseadas em expressões explícitas não são possíveis. Logo, se tivermos uma maneira de comparar distribuições de probabilidade com base em amostras, podemos usá-la para treinar a rede. De fato, temos uma amostra de dados verdadeiros e podemos, a cada iteração do processo de treinamento, produzir uma amostra de dados gerados.

Embora, em teoria, qualquer distância (ou medida de similaridade) capaz de comparar efetivamente duas distribuições baseadas em amostras possa ser usada, podemos mencionar, em particular, a abordagem da Discrepância Média Máxima (MMD). O MMD define uma distância entre duas distribuições de probabilidade que podem ser calculadas (estimadas) com base em amostras dessas distribuições. Embora não esteja totalmente fora do escopo deste capítulo, decidimos não gastar muito mais tempo descrevendo o MMD. No entanto, caso você queira mais detalhes sobre isso, recomendamos esses 3 papers abaixo:

Learning features to compare distributions

A Kernel Method for the Two-Sample-Problem

A Kernel Two-Sample Test

Retropropagação do erro de correspondência de distribuição

Assim, uma vez que definimos uma maneira de comparar duas distribuições com base em amostras, podemos definir o processo de treinamento da rede generativa em GMNs. Dada uma variável aleatória com distribuição de probabilidade uniforme como entrada, queremos que a distribuição de probabilidade da saída gerada seja a “distribuição de probabilidade do cão”. A ideia das GMNs é otimizar a rede repetindo as seguintes etapas:

  • Gerar algumas entradas uniformes.
  • Fazer essas entradas passarem pela rede e coletar as saídas geradas.
  • Comparar a verdadeira “distribuição de probabilidade de cães” e a gerada com base nas amostras disponíveis (por exemplo, calculando a distância MMD entre a amostra de imagens reais de cães e a amostra de imagens geradas).
  • Usar retropropagação para fazer uma etapa de descida de gradiente para diminuir a distância (por exemplo, MMD) entre distribuições verdadeiras e geradas.

Conforme descrito acima, ao seguir estas etapas, aplicamos uma descida do gradiente na rede com uma função de perda que é a distância entre as distribuições verdadeiras e as distribuições geradas na iteração atual.

O método de treinamento “indireto”

A abordagem “direta” apresentada acima compara diretamente a distribuição gerada com a verdadeira ao treinar a rede generativa. A brilhante ideia que governa as GANs consiste em substituir essa comparação direta por uma indireta que assume a forma de uma tarefa ajustada sobre essas duas distribuições.

O treinamento da rede generativa é então realizado com relação a essa tarefa, de modo que força a distribuição gerada a se aproximar cada vez mais da distribuição verdadeira.

A tarefa ajustada das GANs é uma tarefa de discriminação entre amostras verdadeiras e geradas. Ou poderíamos dizer uma tarefa de “não discriminação”, pois queremos que a discriminação falhe o máximo possível. Portanto, em uma arquitetura GAN, temos um discriminador, que coleta amostras de dados verdadeiros e gerados e tenta classificá-los da melhor maneira possível, e um gerador treinado para enganar o discriminador o máximo possível. Vamos ver em um exemplo simples porque as abordagens diretas e indiretas que mencionamos devem, em teoria, levar ao mesmo gerador ideal.

O caso ideal: gerador e discriminador perfeitos

Para entender melhor por que treinar um gerador para enganar um discriminador levará ao mesmo resultado que treinar diretamente o gerador para corresponder à distribuição de destino, vamos dar um exemplo unidimensional simples. Esquecemos, por enquanto, como o gerador e o discriminador são representados e os consideramos como noções abstratas (que serão especificadas na próxima subseção). Além disso, ambos são supostos “perfeitos” (com capacidades infinitas) no sentido de que não são limitados por nenhum tipo de modelo (parametrizado).

Suponha que tenhamos uma distribuição verdadeira, por exemplo, um gaussiano unidimensional e que desejemos um gerador que faça amostras dessa distribuição de probabilidade. O que chamamos de método de treinamento “direto” consistiria em ajustar iterativamente o gerador (iterações de descida de gradiente) para corrigir a diferença / erro medido entre distribuições verdadeiras e geradas. Por fim, supondo que o processo de otimização seja perfeito, devemos terminar com a distribuição gerada que corresponda exatamente à verdadeira distribuição.

 

norm

 

Para a abordagem “indireta”, devemos considerar também um discriminador. Presumimos por enquanto que esse discriminador é um tipo de oráculo que sabe exatamente quais são as distribuições verdadeira e gerada e que é capaz, com base nessas informações, de prever uma classe (“verdadeira” ou “gerada”) para qualquer ponto. Se as duas distribuições estiverem distantes, o discriminador será capaz de classificar facilmente e com um alto nível de confiança a maioria dos pontos que apresentamos. Se queremos enganar o discriminador, precisamos aproximar a distribuição gerada da verdadeira. O discriminador terá mais dificuldade em prever a classe quando as duas distribuições serão iguais em todos os pontos: nesse caso, para cada ponto, haverá chances iguais de ser “verdadeiro” ou “gerado” e, em seguida, o discriminador poderá ” fazer melhor do que ser verdadeiro em um caso em dois em média.

 

norm2

 

Nesse ponto, parece legítimo se perguntar se esse método indireto é realmente uma boa ideia. De fato, parece ser mais complicado (temos que otimizar o gerador com base em uma tarefa ajustada, em vez de diretamente nas distribuições) e requer um discriminador que consideramos aqui como um determinado oráculo, mas que, na realidade, não é conhecido. Nem perfeito. Para o primeiro ponto, a dificuldade de comparar diretamente duas distribuições de probabilidade com base em amostras contrabalança a aparente maior complexidade do método indireto. Para o segundo ponto, é óbvio que o discriminador não é conhecido. No entanto, pode ser aprendido!

A aproximação: redes neurais adversárias

Vamos agora descrever a forma específica que assume o gerador e o discriminador na arquitetura das GANs. O gerador é uma rede neural que modela uma função de transformação. Ele assume como entrada uma variável aleatória simples e deve retornar, uma vez treinada, uma variável aleatória que segue a distribuição de destino. Como é muito complicado e desconhecido, decidimos modelar o discriminador com outra rede neural. Essa rede neural modela uma função discriminativa. Ele toma como entrada um ponto (no nosso exemplo de cachorro, um vetor dimensional N) e retorna como saída a probabilidade desse ponto ser “verdadeiro”.

Observe que o fato de impormos agora um modelo parametrizado para expressar tanto o gerador quanto o discriminador (em vez das versões idealizadas na subseção anterior) não tem, na prática, um grande impacto no argumento / intuição teórica acima: apenas trabalhamos em alguns espaços parametrizados em vez de espaços completos ideais e, portanto, os pontos ideais que devemos alcançar no caso ideal podem ser vistos como “arredondados” pela capacidade de precisão dos modelos parametrizados.

Uma vez definidas, as duas redes podem ser treinadas em conjunto (ao mesmo tempo) com objetivos opostos:

  • O objetivo do gerador é enganar o discriminador; portanto, a rede neural generativa é treinada para maximizar o erro de classificação final (entre dados verdadeiros e gerados).
  • O objetivo do discriminador é detectar dados falsos gerados, para que a rede neural discriminativa seja treinada para minimizar o erro de classificação final.

Portanto, a cada iteração do processo de treinamento, os pesos da rede generativa são atualizados para aumentar o erro de classificação (subida do gradiente de erro sobre os parâmetros do gerador), enquanto os pesos da rede discriminativa são atualizados para diminuir esse erro (descida do gradiente de erro sobre os parâmetros do discriminador).

Esses objetivos opostos e a noção implícita de treinamento antagônico das duas redes explicam o nome de “redes adversárias”: ambas as redes tentam se derrotar e, ao fazê-lo, estão cada vez melhor. A competição entre elas faz com que essas duas redes “progridam” com relação a seus respectivos objetivos. Do ponto de vista da teoria dos jogos, podemos pensar nessa configuração como um jogo minimax para dois jogadores, em que o estado de equilíbrio corresponde à situação em que o gerador produz dados a partir da distribuição exata e onde o discriminador prediz “verdadeiro” ou “gerado” com probabilidade 1/2 para qualquer ponto que receber.

Os modelos GAN estão entre os mais avançados em Deep Learning e a ideia por trás da sua concepção é simples e brilhante.

Agora sim, estamos prontos para compreender a Matemática que faz tudo isso acontecer!

Está gostando do Deep Learning Book? Então ajude a continuarmos esse trabalho e compartilhe o Deep Learning Book entre seus amigos e rede de contatos.

Até o próximo capítulo!

Referências:

Formação Engenheiro de Inteligência Artificial

Customizando Redes Neurais com Funções de Ativação Alternativas

A Beginner’s Guide to Generative Adversarial Networks (GANs)

A Leap into the Future: Generative Adversarial Networks

Understanding Generative Adversarial Networks (GANs)

How A.I. Is Creating Building Blocks to Reshape Music and Art

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 55 – Geração de Variáveis Aleatórias – Uma das Bases dos Modelos Generativos em GANs (Generative Adversarial Networks)

by

Neste capítulo discutiremos o processo de geração de variáveis aleatórias a partir de uma determinada distribuição, tema importante para compreender o funcionamento dos modelos generativos das GANs e nos próximos capítulos veremos os detalhes de funcionamento dos modelos generativos e os detalhes matemáticos das GANs. Estamos considerando que você leu o capítulo anterior.

Variáveis ​​aleatórias uniformes podem ser geradas pseudo-aleatoriamente

Vamos começar discutindo o processo de geração de variáveis ​​aleatórias. Veremos alguns métodos existentes e, mais especificamente, o método de transformação inversa que permite gerar variáveis ​​aleatórias complexas a partir de variáveis ​​aleatórias uniformes simples. Embora tudo isso possa parecer um pouco distante do nosso assunto, GANs, veremos no próximo capítulo o vínculo profundo que existe com os modelos generativos. Se o conceito de Estatística for algo que você esteja vendo pela primeira vez, a DSA oferece cursos completos de Estatística e Matemática na Formação Análise Estatística.

Uma variável aleatória é uma variável quantitativa, cujo resultado (valor) depende de fatores aleatórios. Um exemplo de uma variável aleatória é o resultado do lançamento de um dado que pode resultar em qualquer número entre 1 e 6. Embora possamos conhecer os seus possíveis resultados, o resultado em si depende de fatores de sorte (álea). Uma variável aleatória pode ser uma medição de um parâmetro que pode gerar valores diferentes. O conceito de variável aleatória é essencial em Estatística e em outros métodos quantitativos para a representação de fenômenos incertos. Este conceito é estudado em detalhes no curso Análise Estatística Para Data Science com Linguagem R.

As variáveis aleatórias podem ser classificadas em variáveis aleatórias discretas, contínuas e mistas.

Os computadores são fundamentalmente determinísticos. Portanto, é teoricamente impossível gerar números realmente aleatórios (a pergunta “o que realmente é aleatoriedade?” é algo difícil de responder). No entanto, é possível definir algoritmos que geram sequências de números cujas propriedades estão muito próximas das propriedades das sequências teóricas de números aleatórios. Em particular, um computador é capaz, usando um gerador de números pseudo-aleatórios, de gerar uma sequência de números que segue aproximadamente uma distribuição aleatória uniforme entre 0 e 1. O caso uniforme é muito simples, no qual variáveis ​​aleatórias mais complexas podem ser construídas.

Variáveis ​​aleatórias expressas como resultado de uma operação ou processo

Existem diferentes técnicas que visam gerar variáveis ​​aleatórias mais complexas. Entre elas, podemos encontrar, por exemplo, método de transformação inversa, amostragem por rejeição, algoritmo Metropolis-Hastings entre outros. Todos esses métodos se baseiam em diferentes truques matemáticos que consistem principalmente em representar a variável aleatória que queremos gerar como resultado de uma operação (sobre variáveis ​​aleatórias mais simples) ou de um processo.

A amostragem por rejeição expressa a variável aleatória como resultado de um processo que consiste em amostrar não da distribuição complexa, mas de uma distribuição simples bem conhecida e para aceitar ou rejeitar o valor amostrado, dependendo de alguma condição. Repetindo esse processo até que o valor amostrado seja aceito, podemos mostrar que, com a condição correta de aceitação, o valor que será efetivamente amostrado seguirá a distribuição correta.

No algoritmo Metropolis-Hastings, a ideia é encontrar uma Cadeia de Markov (MC – Markov Chain) de modo que a distribuição estacionária dessa MC corresponda à distribuição da qual gostaríamos de amostrar nossa variável aleatória. Uma vez encontrada essa MC, podemos simular uma trajetória longa o suficiente sobre ela para considerar que atingimos um estado estacionário e, em seguida, o último valor que obtemos dessa maneira pode ser considerado como extraído da distribuição de interesse.

Não iremos mais adiante nos detalhes da amostragem por rejeição e do Metropolis-Hastings, porque esses métodos não são os que nos levarão à noção por trás das GANs. No entanto, vamos nos concentrar um pouco mais no método de transformação inversa.

O método de transformação inversa

A ideia do método de transformação inversa é simplesmente representar nossa “complexa” variável aleatória como resultado de uma função aplicada a um variável aleatória uniforme, que nós sabemos como gerar.

Consideramos abaixo um exemplo unidimensional. Seja X uma variável aleatória complexa da qual queremos amostrar e U seja uma variável aleatória uniforme sobre [0,1] que sabemos como amostrar. Lembramos que uma variável aleatória é totalmente definida por sua Função de Distribuição Cumulativa (CDF). O CDF de uma variável aleatória é uma função do domínio de definição da variável aleatória até o intervalo [0,1] e definido, em uma dimensão, de modo que:

 

form1

 

No caso particular de nossa variável aleatória uniforme U, temos:

 

form2

 

Por uma questão de simplicidade, vamos supor aqui que a função CDF_X é inversível e seu inverso é indicado por:

 

form3

 

(o método pode ser facilmente estendido ao caso não inversível usando o inverso generalizado da função, mas não é realmente o ponto principal em que queremos focar aqui). Então, se definirmos:

 

form4

 

temos:

 

form5

 

Como podemos ver, Y e X têm o mesmo CDF e depois definem a mesma variável aleatória. Assim, definindo Y como acima (em função de uma variável aleatória uniforme), conseguimos definir uma variável aleatória com a distribuição alvo.

Para resumir, o método de transformação inversa é uma maneira de gerar uma variável aleatória que segue uma determinada distribuição, fazendo uma variável aleatória uniforme passar por uma “função de transformação” bem projetada (CDF inverso). Essa noção de “método de transformação inversa” pode, de fato, ser estendida à noção de “método de transformação” que consiste, de maneira mais geral, em gerar variáveis ​​aleatórias em função de algumas variáveis ​​aleatórias mais simples (não necessariamente uniformes e, em seguida, a função de transformação é não mais o CDF inverso). Conceitualmente, o objetivo da “função de transformação” é deformar / remodelar a distribuição de probabilidade inicial: a função de transformação começa de onde a distribuição inicial é muito alta em comparação com a distribuição de destino e a coloca onde é muito baixa. Foi exatamente isso que pensou o criador do modelo GAN e muitos consideram o conceito como uma espécie de “hack” na teoria estatística, o que gerou o modelo GAN.

Observe a ilustração do método de transformação inversa abaixo. Em azul: a distribuição uniforme em [0,1]. Em laranja: a distribuição gaussiana (normal) padrão. Em cinza: o mapeamento da distribuição uniforme para a gaussiana (CDF inverso).

 

dist

 

Compreendeu o conceito? Isso é o que está por trás dos modelos generativos nas GANs, que veremos no próximo capítulo!

Referências:

Análise Estatística Para Data Science com Linguagem Python

Customizando Redes Neurais com Funções de Ativação Alternativas

A Beginner’s Guide to Generative Adversarial Networks (GANs)

A Leap into the Future: Generative Adversarial Networks

Understanding Generative Adversarial Networks (GANs)

How A.I. Is Creating Building Blocks to Reshape Music and Art

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

 

Deep Learning Book

Capítulo 53 – Matemática na GRU, Dissipação e Clipping do Gradiente

by

A capacidade da rede GRU de manter dependências ou memória de longo prazo decorre dos cálculos na célula na GRU para produzir o estado oculto. As LSTMs têm dois estados diferentes passados entre as células – o estado da célula e o estado oculto, que carregam a memória de longo e curto prazo, respectivamente – as GRUs têm apenas um estado oculto transferido entre as etapas do tempo. Esse estado oculto é capaz de manter as dependências de longo e curto prazo ao mesmo tempo, devido aos mecanismos de restrição (portões) e cálculos pelos quais o estado oculto e os dados de entrada passam.

 

gruxlstm

 

A célula GRU contém apenas dois portões: o portão de atualização e o portão de redefinição. Assim como os portões das LSTMs, os portões na GRU são treinados para filtrar seletivamente qualquer informação irrelevante, mantendo o que é útil. Esses portões são essencialmente vetores contendo valores entre 0 e 1 que serão multiplicados com os dados de entrada e/ou estado oculto. Um valor 0 nos vetores indica que os dados correspondentes no estado de entrada ou oculto não são importantes e, portanto, retornarão como zero. Por outro lado, um valor 1 no vetor significa que os dados correspondentes são importantes e serão usados.

Usaremos os termos gate e vetor de forma intercambiável para o restante deste capítulo, pois eles se referem à mesma coisa.

A estrutura de uma unidade GRU é mostrada abaixo.

 

 

gru1

 

 

Embora a estrutura possa parecer bastante complicada devido ao grande número de conexões, o mecanismo por trás dela pode ser dividido em três etapas principais.

Reset Gate

Na primeira etapa, criamos o portão de redefinição (reset gate). Essa porta é derivada e calculada usando o estado oculto da etapa anterior e os dados de entrada na etapa atual.

Matematicamente, isso é conseguido multiplicando o estado oculto anterior e a entrada atual com seus respectivos pesos e somando-os antes de passar a soma através de uma função sigmóide. A função sigmoide transformará os valores entre 0 e 1, permitindo que o portão filtre entre as informações menos importantes e mais importantes nas etapas subsequentes. A fórmula matemática é representada abaixo:

form1

Quando toda a rede é treinada através de backpropagation, os pesos na equação serão atualizados de forma que o vetor aprenda a reter apenas os recursos úteis.

O estado oculto anterior será primeiro multiplicado por um peso treinável e passará por uma multiplicação por elementos (produto Hadamard) com o vetor de redefinição. Esta operação decidirá quais informações serão mantidas nas etapas anteriores, juntamente com as novas entradas. Ao mesmo tempo, a entrada atual também será multiplicada por um peso treinável antes de ser somada com o produto do vetor de redefinição e do estado oculto anterior acima. Por fim, uma função tanh de ativação não linear será aplicada ao resultado final para obter r na equação abaixo.

form2

Update Gate

Em seguida, temos o portão de atualização (update gate). Assim como o reset gate, o update gate é calculado usando o estado oculto anterior e os dados de entrada atuais.

Os vetores Update e Reset gate são criados usando a mesma fórmula, mas os pesos multiplicados pela entrada e pelo estado oculto são exclusivos para cada portão, o que significa que os vetores finais para cada portão são diferentes. Isso permite que os portões sirvam a seus propósitos específicos.

form3

O vetor Update será submetido a multiplicação por elementos com o estado oculto anterior para obter u em nossa equação abaixo, que será usada para calcular nossa saída final posteriormente.

O vetor Update também será usado em outra operação posteriormente ao obter nossa saída final. O objetivo do update gate aqui é ajudar o modelo a determinar quanto das informações passadas armazenadas no estado oculto anterior precisam ser retidas para o futuro.

Combinando as Saídas

Na última etapa, reutilizaremos o portal Update e obteremos o estado oculto atualizado.

Desta vez, pegaremos a versão inversa em elementos do mesmo vetor Update (1 – Update gate) e faremos uma multiplicação em elementos com a nossa saída do reset gate, r. O objetivo desta operação é o gate Update determinar qual parte das novas informações deve ser armazenada no estado oculto.

Por fim, o resultado das operações acima será resumido com a nossa saída do portão Update na etapa anterior, u. Isso nos dará nosso novo e atualizado estado oculto.

form5

Podemos usar esse novo estado oculto como nossa saída para esse intervalo de tempo, passando-o por uma camada de ativação linear.

Solução do Problema de Dissipação/Explosão do Gradiente

Vimos os portões em ação. Sabemos como eles transformam nossos dados. Agora, vamos revisar seu papel geral no gerenciamento da memória da rede e falar sobre como eles resolvem o problema de dissipação/explosão do gradiente.

Como vimos nos mecanismos acima, o Reset Gate é responsável por decidir quais partes do estado oculto anterior devem ser combinadas com a entrada atual para propor um novo estado oculto.

E o Update Gate é responsável por determinar quanto do estado oculto anterior deve ser retido e qual parte do novo estado oculto proposto (derivado do Reset Gate) deve ser adicionado ao estado oculto final. Quando o Update Gate é multiplicado pela primeira vez com o estado oculto anterior, a rede escolhe quais partes do estado oculto anterior ele manterá em sua memória enquanto descarta o restante. Posteriormente, ele corrige as partes ausentes das informações quando usa o inverso do gate Update para filtrar o novo estado oculto proposto a partir do Reset Gate.

Isso permite que a rede retenha dependências de longo prazo. O Update Gate pode optar por manter a maioria das memórias anteriores no estado oculto se os valores do vetor Update estiverem próximos de 1 sem recalcular ou alterar todo o estado oculto.

O problema de dissipação/explosão do gradiente ocorre durante a propagação de retorno (backpropagation) ao treinar a RNN, especialmente se a RNN estiver processando longas sequências ou tiver várias camadas. O erro do gradiente calculado durante o treinamento é usado para atualizar o peso da rede na direção certa e na magnitude certa. No entanto, esse gradiente é calculado com a regra da cadeia (chain rule), começando no final da rede. Portanto, durante o backpropagation, os gradientes sofrerão continuamente multiplicações de matrizes e encolherão ou explodirão exponencialmente por sequências longas. Ter um gradiente muito pequeno significa que o modelo não atualiza seus pesos de maneira eficaz, enquanto gradientes extremamente grandes fazem com que o modelo seja instável.

Os portões nas LSTM e GRUs ajudam a resolver esse problema devido ao componente aditivo dos portões de atualização. Enquanto as RNNs tradicionais sempre substituem todo o conteúdo do estado oculto a cada etapa, as LSTMs e GRUs mantêm a maior parte do estado oculto existente enquanto adicionam novo conteúdo sobre ele. Isso permite que os erros dos gradientes sejam propagados de volta sem desaparecer ou explodir muito rapidamente devido às operações de adição.

Clipping (Recorte) do Gradiente

Embora LSTMs e GRUs sejam as correções mais usadas para o problema acima, outra solução para o problema de explosão de gradientes é o clipping do gradiente. 

O clipping do gradiente é mais comum em redes neurais recorrentes. Quando os gradientes estão sendo propagados no tempo, eles podem desaparecer porque são continuamente multiplicados por números menores que um. Isso é chamado de problema de dissipação do gradiente, podendo ser resolvido por LSTMs e GRUs e, se você estiver usando uma rede profunda feed-forward, isso é resolvido por conexões residuais. Por outro lado, você também pode ter  explosão dos gradientes. É quando eles se tornam exponencialmente grandes por serem multiplicados por números maiores que 1. O clipping do gradiente cortará os gradientes entre dois números para impedir que eles fiquem muito grandes.

O clipping define um valor limite definido nos gradientes, o que significa que, mesmo se um gradiente aumentar além do valor predefinido durante o treinamento, seu valor ainda será limitado ao limite definido. Dessa forma, a direção do gradiente permanece inalterada e apenas a magnitude do gradiente é alterada.

Até o próximo capítulo!

Referências:

Formação Engenheiro de Inteligência Artificial

Customizando Redes Neurais com Funções de Ativação Alternativas

Understanding GRU Networks

Illustrated Guide to LSTM’s and GRU’s: A step by step explanation

Gated Recurrent Unit (GRU) 

A Recursive Recurrent Neural Network for Statistical Machine Translation

Sequence to Sequence Learning with Neural Networks

Recurrent Neural Networks Cheatsheet

On the difficulty of training recurrent neural networks

A Beginner’s Guide to LSTMs and Recurrent Neural Networks

Long Short-Term Memory (LSTM): Concept

Recurrent Neural Networks Tutorial, Part 1 – Introduction to RNNs

Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 50 – A Matemática da Dissipação do Gradiente e Aplicações das RNNs

by

No Capítulo 34 nós discutimos sobre o problema da dissipação do gradiente e a dificuldade em treinar as redes neurais artificiais. Com as RNNs esse problema é ainda mais acentuado e por isso vamos agora estudar A Matemática da Dissipação do Gradiente e Aplicações das RNNs e compreender matematicamente porque o problema acontece.

Mencionamos anteriormente que as RNNs têm dificuldades em aprender dependências de longo alcance – interações entre palavras que estão separadas por vários passos, por exemplo. Isso é problemático porque o significado de uma frase em português é geralmente determinado por palavras que não são muito próximas: “O homem que usava uma peruca entrou no bar”. A frase é realmente sobre um homem entrando em um bar, não sobre a peruca. Mas é improvável que uma RNN simples seja capaz de capturar essas informações. Para entender porque, vamos dar uma olhada mais de perto no gradiente que calculamos no capítulo anterior:

 

form1

 

Observe que:

form2

 

é uma regra de cadeia em si! Por exemplo:

 

form3

 

Observe também que, como estamos tomando a derivada de uma função vetorial em relação a um vetor, o resultado é uma matriz (chamada de matriz jacobiana) cujos elementos são todos derivadas pointwise. Podemos reescrever o gradiente acima da seguinte forma:

 

form4

 

Acontece (esse paper explica isso em detalhes) que a norma (na álgebra linear, análise funcional e áreas relacionadas da matemática, uma norma é uma função que atribui um comprimento ou tamanho estritamente positivo a cada vetor em um espaço vetorial – exceto para o vetor zero, ao qual é atribuído um comprimento de zero), que você pode pensar como um valor absoluto, da matriz jacobiana acima tem um limite superior de 1. Isso porque a nossa função de ativação tanh (ou sigmóide) mapeia todos os valores em um intervalo entre -1 e 1, e a derivada é limitada por 1 (1/4 no caso de sigmoide) também:

 

tanh

 

Você pode ver que as funções tanh e sigmoid têm derivadas de 0 em ambas as extremidades, onde se aproximam de uma linha plana. Quando isso acontece, dizemos que os neurônios correspondentes estão saturados. Eles têm um gradiente nulo e conduzem outros gradientes nas camadas anteriores para 0. Assim, com valores pequenos nas multiplicações de matriz e múltiplas matrizes (t-k em particular) os valores de gradiente estão diminuindo exponencialmente rápido, desaparecendo completamente após alguns passos de tempo.

Contribuições gradientes de etapas “longínquas” se tornam zero e o estado nessas etapas não contribui para o que a rede está aprendendo: a rede acaba não aprendendo dependências de longo alcance. Dissipações do gradiente não são exclusivos das RNNs e também acontecem em Redes Neurais Profundas Feedforward. Mas as RNNs tendem a ser muito profundas (tão profundas quanto a duração da sentença, em um problema de Processamento de Linguagem Natural por exemplo), o que torna o problema muito mais comum.

É fácil imaginar que, dependendo de nossas funções de ativação e parâmetros de rede, poderíamos obter explosão em vez de dissipação de gradientes, se os valores da matriz Jacobiana forem grandes. Na verdade, isso é chamado de problema de explosão do gradiente. A razão pela qual as dissipações do gradiente receberam mais atenção do que as explosões é dupla. Por um lado, explosão de gradientes são óbvias. Seus gradientes se tornarão NaN (não um número) e seu programa falhará.

Em segundo lugar, recortar os gradientes em um limiar pré-definido é uma solução muito simples e eficaz para evitar a explosão dos gradientes. As dissipações dos gradientes são mais problemáticas porque não são óbvias quando ocorrem ou é mais complicado lidar com elas.

Felizmente, existem algumas maneiras de combater o problema da dissipação do gradiente. A inicialização adequada da matriz W pode reduzir o efeito do problema. Ou seja, aplicamos regularização. Uma solução mais interessante é usar as funções de ativação ReLU em vez de tanh ou sigmóide. A derivada ReLU é uma constante de 0 ou 1, por isso não é tão provável que sofra de dissipação do gradiente.

Uma solução ainda mais popular é usar as arquiteturas Long Short-Term Memory (LSTM) ou Gated Recurrent Unit (GRU). As LSTMs foram propostas pela primeira vez em 1997 e são os modelos talvez mais amplamente usados em Processamento de Linguagem Natural atualmente. As GRUs, propostas pela primeira vez em 2014, são versões simplificadas das LSTMs. Ambas as arquiteturas RNN foram explicitamente projetadas para lidar com dissipação do gradiente e aprender eficientemente dependências de longo alcance. Vamos cobrir as duas arquiteturas nos próximos capítulos.

Mas o que podemos fazer com as RNNs?

As RNNs mostraram grande sucesso em muitas tarefas de Processamento de Linguagem Natural. Neste ponto, devo mencionar que os tipos de RNN mais usados são as LSTMs, que são muito melhores na captura de dependências de longo prazo do que as RNNs em sua arquitetura padrão. Mas não se preocupe, as LSTMs são essencialmente a mesma coisa que as RNNs, mas apenas têm uma maneira diferente de computar o estado oculto. Cobriremos as LSTMs com mais detalhes no próximo capítulo. Aqui estão alguns exemplos de aplicações de RNNs em Processamento de Linguagem Natural (o que não é uma lista definitiva).

Modelagem de Linguagem e Geração de Texto

Dada uma sequência de palavras, queremos prever a probabilidade de cada palavra dada às palavras anteriores. Os Modelos de Linguagem nos permitem medir a probabilidade de uma sentença, que é uma entrada importante para a Tradução Automática (já que as sentenças de alta probabilidade estão normalmente corretas). Um efeito colateral de poder prever a próxima palavra é que obtemos um modelo generativo, que nos permite gerar um novo texto por amostragem a partir das probabilidades de saída. E dependendo de quais são nossos dados de treinamento, podemos gerar todos os tipos de coisas.

Em Modelagem de Linguagem, nossa entrada é tipicamente uma sequência de palavras (codificadas como vetores únicos), e nossa saída é a sequência de palavras previstas. Ao treinar a rede, definimos ot = x{t + 1}, pois queremos que a saída na etapa t seja a próxima palavra real.

Machine Translation

A tradução automática é semelhante à modelagem de linguagem, pois nossa entrada é uma sequência de palavras em nosso idioma de origem (por exemplo português). Queremos produzir uma sequência de palavras em nosso idioma de destino (por exemplo, inglês). A principal diferença é que nossa saída só é iniciada depois de termos visto a entrada completa, porque a primeira palavra de nossas sentenças traduzidas pode exigir informações capturadas da sequência de entrada completa.

Reconhecimento de Fala

Dada uma sequência de entrada de sinais acústicos de uma onda sonora, podemos prever uma sequência de segmentos fonéticos juntamente com suas probabilidades.

Gerar Descrições de Imagens

Juntamente com as redes neurais convolucionais, as RNNs foram usados como parte de um modelo para gerar descrições de imagens não rotuladas. É incrível como isso parece funcionar. O modelo combinado alinha as palavras geradas com os recursos encontrados nas imagens.

Continuamos no próximo capítulo.

Referências:

Matemática Para Data Science

A Recursive Recurrent Neural Network for Statistical Machine Translation

Sequence to Sequence Learning with Neural Networks

Recurrent Neural Networks Cheatsheet

On the difficulty of training recurrent neural networks

A Beginner’s Guide to LSTMs and Recurrent Neural Networks

Recurrent Neural Networks Tutorial, Part 1 – Introduction to RNNs

Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

Recurrent neural network based language model

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Capítulo 49 – A Matemática do Backpropagation Through Time (BPTT)

by

Estudamos no capítulo anterior as Redes Neurais Recorrentes. Mas para que elas funcionem, o algoritmo de treinamento precisa de um pequeno ajuste, uma vez que esse tipo de rede possui o que podemos chamar de “memória” durante seu treinamento. E o que faz isso acontecer é A Matemática do Backpropagation Through Time (BPTT), assunto deste capítulo do Deep Learning Book.

Um Pouco Mais Sobre as RNNs

A ideia por trás dos RNNs é fazer uso de informações sequenciais. Em uma rede neural tradicional, assumimos que todas as entradas (e saídas) são independentes umas das outras. Mas para muitas tarefas isso é uma ideia muito ruim. Se você quiser prever a próxima palavra em uma frase, é melhor saber quais palavras vieram antes dela. As RNNs são chamadas de recorrentes porque executam a mesma tarefa para todos os elementos de uma sequência, com a saída sendo dependente dos cálculos anteriores. Outra maneira de pensar sobre RNNs é que elas têm uma “memória” que captura informações sobre o que foi calculado até agora. Em teoria, RNNs podem fazer uso de informações em sequências arbitrariamente longas, mas, na prática, limitam-se a olhar para trás apenas alguns passos (mais sobre isso adiante). Aqui está o que uma RNN típica parece:

rnn

O diagrama acima mostra uma RNN sendo “desenrolada” ou “desdobrada” (termo unfolded em inglês) em uma rede completa. Ao desenrolar, simplesmente queremos dizer que escrevemos a rede para a sequência completa. Por exemplo, se a sequência que nos interessa é uma sentença de 5 palavras, a rede seria desdobrada em uma rede neural de 5 camadas, uma camada para cada palavra. As fórmulas que governam o cálculo que acontece em uma RNN são as seguintes:

1. xt é a entrada no passo de tempo t. Por exemplo, x1 poderia ser um vetor one-hot correspondente à segunda palavra de uma sentença.

2. st é o estado oculto no passo de tempo t. É a “memória” da rede. O termo st é calculado com base no estado oculto anterior e a entrada na etapa atual através da fórmula: st = f(Uxt + Wst-1). A função geralmente é uma não-linearidade, como tanh ou ReLU. Já s -1, que é necessário para calcular o primeiro estado oculto, é tipicamente inicializado com zero.

3. ot é a saída na etapa t. Por exemplo, se quiséssemos prever a próxima palavra em uma frase, seria um vetor de probabilidades em todo o nosso vocabulário. ot = softmax(Vst).

Há algumas coisas a serem observadas aqui:

Você pode pensar no estado oculto st como a memória da rede. st captura informações sobre o que aconteceu em todas as etapas de tempo anteriores. A saída na etapa ot é calculada exclusivamente com base na memória no tempo t. É um pouco mais complicado na prática, porque normalmente não é possível capturar informações de muitas etapas de tempo anteriores.

Ao contrário de uma rede neural profunda tradicional, que usa parâmetros diferentes em cada camada, uma RNN compartilha os mesmos parâmetros (U, V, W acima) em todas as etapas. Isso reflete o fato de que estamos executando a mesma tarefa em cada etapa, apenas com entradas diferentes. Isso reduz muito o número total de parâmetros que precisamos aprender.

O diagrama acima tem saídas em cada etapa de tempo, mas dependendo da tarefa, isso pode não ser necessário. Por exemplo, ao prever o sentimento de uma frase, podemos nos preocupar apenas com a saída final, não com o sentimento após cada palavra. Da mesma forma, podemos não precisar de entradas em cada etapa de tempo. A principal característica de uma RNN é seu estado oculto, que captura algumas informações sobre uma sequência.

E o Backpropagation?

Lembre-se, o objetivo das redes neurais recorrentes é classificar com precisão uma entrada sequencial (por exemplo, dada uma frase, prever o sentimento ou mesmo a próxima palavra). Contamos com a retropropagação (backpropagation) do erro e o gradiente descendente para fazê-lo.

A retropropagação em redes feedforward retrocede do erro final através das saídas, pesos e entradas de cada camada oculta, atribuindo a esses pesos a responsabilidade por uma parte do erro calculando suas derivadas parciais – ∂E / ∂w, ou a relação entre suas taxas de mudança. Essas derivações são então usadas por nossa regra de aprendizado, gradiente descendente, para ajustar os pesos para cima ou para baixo, qualquer que seja a direção que diminua o erro. Já estudamos isso nos capítulos anteriores aqui do Deep Learning Book.

As redes recorrentes dependem de uma extensão da retropropagação, chamada Backpropagation Through Time, ou BPTT. O tempo, neste caso, é simplesmente expresso por uma série ordenada e bem definida de cálculos, ligando um passo de tempo ao seguinte, o que significa que toda a retropropagação precisa funcionar.

Redes neurais, sejam elas recorrentes ou não, são simplesmente funções compostas aninhadas como f(g(h(x))). A adição de um elemento de tempo apenas estende a série de funções para as quais calculamos derivadas com a regra da cadeia (chain rule). Matemática pura!

A Matemática do Backpropagation Through Time (BPTT)

Por falar em Matemática, vamos compreender o BPTT através de fórmulas e alguns gráficos. Para as devidas referências, sempre consulte as notas ao final do capítulo.

Considere que estamos criando uma rede neural recorrente que seja capaz de prever a próxima palavra em um texto, o que pode ser útil em aplicações de IA para criar petições e assim ajudar advogados a automatizar o trabalho. Algo que já é feito pelo ROSS, o Robô Advogado.

Vamos começar com a equação básica de uma Rede Neural Recorrente:

form1

Também definimos nossa perda, ou erro, como a perda de entropia cruzada, dada por:

form2

Aqui, yt é a palavra correta no momento do passo t, e y^t é nossa previsão. Normalmente, tratamos a sequência completa (sentença) como um exemplo de treinamento, portanto, o erro total é apenas a soma dos erros em cada etapa de tempo (palavra).

rnn-bptt1

Lembre-se de que nosso objetivo é calcular os gradientes do erro em relação aos nossos parâmetros U, V e W e, em seguida, aprender bons parâmetros usando o Gradiente Descendente Estocástico. Assim como resumimos os erros, também somamos os gradientes em cada etapa de tempo para um exemplo de treinamento:

 

form3

 

Para calcular esses gradientes, usamos a regra de diferenciação da cadeia. Esse é o algoritmo de retropropagação quando aplicado para trás a partir do erro. Usaremos o E_3 como exemplo, apenas para trabalhar com números concretos.

 

form4

 

Acima, z3 = Vs3 e a última linha é o produto externo de dois vetores. Não se preocupe se você não seguir os passos acima, nós pulamos vários passos e você pode tentar calcular essas derivadas você mesmo (bom exercício!). O ponto que estou tentando transmitir é que

 

latex

 

depende apenas dos valores no momento atual, yˆ3, y3, s3. Se você tem estes valores, calculando o gradiente para V é uma multiplicação de matriz simples. Mas a história é diferente para W (e para U):

 

latex (1)

 

Para entender porque, escrevemos a regra da cadeia, como acima:

 

form5

 

Agora, note que s3 = tanh(Uxt + Ws2) depende de s2, que depende de W e s1, e assim por diante. Então, se pegarmos a derivada em relação a W, não podemos simplesmente tratar s2 como uma constante! Precisamos aplicar a regra da cadeia novamente e o que realmente temos é o seguinte:

 

form6

 

Somamos as contribuições de cada passo de tempo para o gradiente. Em outras palavras, como W é usado em todas as etapas até a saída que nos interessa, precisamos retroceder gradientes na rede de t = 3 até t = 0:

rnn-bptt-with-gradients

Observe que isso é exatamente o mesmo que o algoritmo de retropropagação padrão que usamos nas Redes Neurais Profundas da Feedforward. A principal diferença é que resumimos os gradientes para W em cada etapa de tempo. Em um rede neural tradicional, não compartilhamos parâmetros entre camadas, portanto, não precisamos somar nada. Mas, na minha opinião, o BPTT é apenas um nome sofisticado para retropropagação padrão em uma RNN “desenrolada”. Assim como com Backpropagation, você pode definir um vetor delta que você repassa, por exemplo:

 

form7

 

Aqui um exemplo de como seria a implementação do BPTT em Python:

bptt

 

Isso também deve lhe dar uma ideia do motivo pelo qual as RNNs são difíceis de treinar: as sequências (frases) podem ser bastante longas, talvez 20 palavras ou mais, e, portanto, você precisa retroceder através de várias camadas. Na prática, muitas pessoas truncam a retropropagação em poucos passos. Mas isso é assunto para o próximo capítulo! Até lá.

Referências:

Matemática Para Data Science

Recurrent Neural Networks Cheatsheet

A Beginner’s Guide to LSTMs and Recurrent Neural Networks

Recurrent Neural Networks Tutorial, Part 1 – Introduction to RNNs

Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients

Train longer, generalize better: closing the generalization gap in large batch training of neural networks

Practical Recommendations for Gradient-Based Training of Deep Architectures

Gradient-Based Learning Applied to Document Recognition

Neural Networks & The Backpropagation Algorithm, Explained

Neural Networks and Deep Learning

The Elements of Statistical Learning: Data Mining, Inference, and Prediction, Second Edition

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Deep Learning Book

Início

by

Olá, Seja Bem-Vindo ao Deep Learning Book Brasil.

Esta é uma iniciativa da Data Science Academy, com o objetivo de ajudar a difundir uma das tecnologias mais revolucionárias do nosso tempo, Deep Learning. Como existe pouco material em português, esperamos que este livro online, em português e gratuito, o ajude a compreender um pouco melhor o que é a tecnologia e como ela pode ser usada na construção de aplicações de Inteligência Artificial.

Este livro vai abordar desde o básico em redes neurais artificias, modelos Perceptron e Multilayer Perceptron, passando pelo processo de treinamento com Backpropagation, até arquiteturas avançadas de Deep Learning, como Redes Neurais Convolucionais, Redes Neurais Recorrentes, Autoencoders, Generative Adversarial Network, Deep Reinforcement Learning e o estado da arte, Transformers.

Além disso, também abordaremos regras gerais de aprendizado de máquina, válidas para qualquer modelo de Machine Learning. E teremos ainda Álgebra Linear e Estatística.

São 100 capítulos, publicados no formato de posts, tudo 100% em português. Desta forma, esperamos contribuir para o crescimento do Deep Learning e Inteligência Artificial no Brasil.

Nos acompanhe nesta incrível jornada! Em Português, Online e Gratuito. Clique aqui para começar a leitura pelo capítulo 1.

Equipe DSA

www.datascienceacademy.com.br

Paginação de posts

  • Previous
  • 1
  • 2
  • 3

Capítulos Recentes

  • Capítulo 35 – A Matemática do Problema de Dissipação do Gradiente em Deep Learning
  • Capítulo 34 – O Problema da Dissipação do Gradiente
  • Capítulo 33 – Por que as Redes Neurais Profundas São Difíceis de Treinar?
  • Capítulo 32 – Como Uma Rede Neural Artificial Encontra a Aproximação de Uma Função
  • Capítulo 31 – As Redes Neurais Artificiais Podem Computar Qualquer Função?
  • Capítulo 30 – Variações do Stochastic Gradient Descent – Hessian Optimization e Momentum
  • Capítulo 29 – Definindo o Tamanho do Mini-Batch
  • Capítulo 28 – Usando Early Stopping Para Definir o Número de Épocas de Treinamento
  • Capítulo 27 – A Taxa de Aprendizado de Uma Rede Neural
  • Capítulo 26 – Como Escolher os Hiperparâmetros de Uma Rede Neural

Buscar

Podcast DSA

© 2025 Data Science Academy - www.datascienceacademy.com.br