Skip to content

Deep Learning Book

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

Deep Learning Book

Em Português, Online e Gratuito

Deep Learning Book

Capítulo 17 – Cross-Entropy Cost Function

by

Quando um jogador de tênis está aprendendo a praticar o esporte, ele geralmente passa a maior parte do tempo desenvolvendo o movimento do corpo. Apenas gradualmente ele desenvolve as tacadas, aprende a movimentar a bola com precisão para a quadra adversária e com isso vai construindo sua técnica, que se aprimora à medida que ele pratica. De maneira semelhante, até agora nos concentramos em entender o algoritmo de retropropagação (backpropagation), a base para aprender a maioria das atividades em redes neurais. A partir de agora, estudaremos um conjunto de técnicas que podem ser usadas para melhorar nossa implementação do backpropagation e, assim, melhorar a maneira como nossas redes aprendem.

As técnicas que desenvolveremos incluem: uma melhor escolha de função de custo, conhecida como função de custo de entropia cruzada (ou Cross-Entropy Cost Function); quatro métodos de “regularização” (regularização de L1 e L2, dropout e expansão artificial dos dados de treinamento), que melhoram nossas redes para generalizar além dos dados de treinamento; um método melhor para inicializar os pesos na rede; e um conjunto de heurísticas para ajudar a escolher bons hyperparâmetros para a rede. Também vamos analisar várias outras técnicas com menos profundidade. As discussões são em grande parte independentes umas das outras e, portanto, você pode avançar se quiser. Também implementaremos muitas das técnicas em nosso código e usaremos para melhorar os resultados obtidos no problema de classificação de dígitos manuscritos estudado nos capítulos anteriores.

Naturalmente, estamos cobrindo apenas algumas das muitas técnicas que foram desenvolvidas para uso em redes neurais. A filosofia é que o melhor acesso à multiplicidade de técnicas disponíveis é o estudo aprofundado de algumas das mais importantes. Dominar essas técnicas importantes não é apenas útil por si só, mas também irá aprofundar sua compreensão sobre quais problemas podem surgir quando você usa redes neurais. Isso deixará você bem preparado para aprender rapidamente outras técnicas, conforme necessário.

A Função de Custo

A maioria de nós acha desagradável estar errado. Logo depois de começar a aprender piano, minha filha fez sua primeira apresentação diante de uma platéia. Ela estava nervosa e começou a tocar a peça com uma oitava muito baixa. Ela ficou confusa e não pôde continuar até que alguém apontasse o erro. Ela ficou muito envergonhada. Ainda que desagradável, também aprendemos rapidamente quando estamos decididamente errados. Você pode apostar que a próxima vez que ela se apresentou diante de uma platéia, ela começou na oitava correta! Em contraste, aprendemos mais lentamente quando nossos erros são menos bem definidos.

Idealmente, esperamos que nossas redes neurais aprendam rapidamente com seus erros. Mas é isso que acontece na prática? Para responder a essa pergunta, vamos dar uma olhada em um exemplo simples. O exemplo envolve um neurônio com apenas uma entrada:

 

neuron

 

Nós vamos treinar esse neurônio para fazer algo ridiculamente fácil: obter a entrada 1 e gerar a saída 0. Claro, essa é uma tarefa tão trivial que poderíamos facilmente descobrir um peso apropriado e um viés (bias) de forma manual, sem usar um algoritmo de aprendizado. No entanto, vai nos ajudar a compreender melhor o processo de usar gradiente descendente para tentar aprender um peso e viés. Então, vamos dar uma olhada em como o neurônio aprende.

Para tornar as coisas definitivas, escolhemos o peso inicial como 0.6 e o ​​viés inicial como 0.9. Estas são escolhas genéricas usadas como um lugar para começar a aprender, eu não as escolhi para serem especiais de alguma forma. A saída inicial do neurônio é 0.82, então um pouco de aprendizado será necessário antes que nosso neurônio se aproxime da saída desejada 0,0.

No gráfico abaixo, podemos ver como o neurônio aprende uma saída muito mais próxima de 0.0. Durante o treinamento, o modelo está realmente computando o gradiente, e usando o gradiente para atualizar o peso e o viés, e exibir o resultado. A taxa de aprendizado é η = 0.15, o que acaba sendo lento o suficiente para que possamos acompanhar o que está acontecendo, mas rápido o suficiente para que possamos obter um aprendizado substancial em apenas alguns segundos. O custo é a função de custo quadrático, C, apresentada nos capítulos anteriores. Vou lembrá-lo da forma exata da função de custo em breve.

 

train

 

Como você pode ver, o neurônio aprende um peso e um viés que diminui o custo e dá uma saída do neurônio de cerca de 0.09 (Epoch, ou Época em português, é o número de passadas que nosso modelo faz pelos dados. A cada passada, os pesos são atualizados, o aprendizado ocorre e o custo, ou a taxa de erros, diminui). Isso não é exatamente o resultado desejado, 0.0, mas é muito bom.

Suponha, no entanto, que, em vez disso, escolhamos o peso inicial e o viés inicial como 2.0. Nesse caso, a saída inicial é 0.98, o que é muito ruim. Vamos ver como o neurônio aprende a gerar 0 neste caso:

 

train2

 

Embora este exemplo use a mesma taxa de aprendizado (η = 0.15), podemos ver que a aprendizagem começa muito mais devagar. De fato, nas primeiras 150 épocas de aprendizado, os pesos e vieses não mudam muito. Então o aprendizado entra em ação e, como em nosso primeiro exemplo, a saída do neurônio se aproxima rapidamente de 0.0.

Esse comportamento é estranho quando comparado ao aprendizado humano. Como eu disse no começo deste capítulo, muitas vezes aprendemos mais rápido quando estamos muito errados sobre algo. Mas acabamos de ver que nosso neurônio artificial tem muita dificuldade em aprender quando está muito errado – muito mais dificuldade do que quando está apenas um pouco errado. Além do mais, verifica-se que esse comportamento ocorre não apenas neste exemplo, mas em redes mais gerais. Por que aprender tão devagar? E podemos encontrar uma maneira de evitar essa desaceleração?

Para entender a origem do problema, considere que nosso neurônio aprende mudando o peso e o viés a uma taxa determinada pelas derivadas parciais da função custo, ∂C/∂w e ∂C/∂b. Então, dizer “aprender é lento” é realmente o mesmo que dizer que essas derivadas parciais são pequenas. O desafio é entender por que eles são pequenas. Para entender isso, vamos calcular as derivadas parciais. Lembre-se de que estamos usando a função de custo quadrático, que é dada por:

cost

onde a é a saída do neurônio quando a entrada de treinamento x = 1 é usada, e y = 0 é a saída desejada correspondente. Para escrever isso mais explicitamente em termos de peso e viés, lembre-se que a = σ(z), onde z = wx + b. Usando a regra da cadeia para diferenciar em relação ao peso e viés, obtemos:

 

cost2

 

onde substitui x = 1 e y = 0. Para entender o comportamento dessas expressões, vamos olhar mais de perto o termo σ ′ (z) no lado direito. Lembre-se da forma da função σ:

 

sig

 

Podemos ver neste gráfico que quando a saída do neurônio é próxima de 1, a curva fica muito plana, e então σ ′ (z) fica muito pequeno. As equações acima então nos dizem que ∂C/∂w e ∂C/∂b ficam muito pequenos. Esta é a origem da desaceleração da aprendizagem. Além do mais, como veremos mais adiante, a desaceleração do aprendizado ocorre basicamente pelo mesmo motivo em redes neurais mais genéricas, não apenas neste exemplo simples.

A Função de Custo de Entropia Cruzada

Como podemos abordar a desaceleração da aprendizagem? Acontece que podemos resolver o problema substituindo o custo quadrático por uma função de custo diferente, conhecida como entropia cruzada. Para entender a entropia cruzada, vamos nos afastar um pouco do nosso modelo super-simples. Vamos supor que estamos tentando treinar um neurônio com diversas variáveis de entrada, x1, x2,…, pesos correspondentes w1, w2,… e um viés, b:

 

neuron2

 

A saída do neurônio é, naturalmente, a = σ(z), onde z = ∑jwjxj + b é a soma ponderada das entradas. Nós definimos a função de custo de entropia cruzada para este neurônio assim:

 

entropy

 

onde n é o número total de itens de dados de treinamento, a soma é sobre todas as entradas de treinamento x, e y é a saída desejada correspondente. Não é óbvio que a expressão anterior resolva o problema de desaceleração do aprendizado. De fato, francamente, nem é óbvio que faz sentido chamar isso de uma função de custo! Antes de abordar a desaceleração da aprendizagem, vamos ver em que sentido a entropia cruzada pode ser interpretada como uma função de custo.

Duas propriedades em particular tornam razoável interpretar a entropia cruzada como uma função de custo. Primeiro, não é negativo, isto é, C > 0. Para visualizar isso, observe na fórmula anterior que: (a) todos os termos individuais na soma são negativos, já que ambos os logaritmos são de números no intervalo de 0 a 1; e (b) há um sinal de menos na frente da soma.

Segundo, se a saída real do neurônio estiver próxima da saída desejada para todas as entradas de treinamento x, então a entropia cruzada será próxima de zero. Para ver isso, suponha, por exemplo, que y = 0 e a ≈ 0 para alguma entrada x. Este é um caso quando o neurônio está fazendo um bom trabalho nessa entrada. Vemos que o primeiro termo (na fórmula acima) para o custo, desaparece, desde que y = 0, enquanto o segundo termo é apenas −ln (1 − a) ≈ 0. Uma análise semelhante é válida quando y = 1 e a ≈ 1. E assim, a contribuição para o custo será baixa, desde que a saída real esteja próxima da saída desejada.

Em suma, a entropia cruzada é positiva e tende a zero, à medida que o neurônio melhora a computação da saída desejada, y, para todas as entradas de treinamento, x.

Essas são as duas propriedades que esperamos intuitivamente para uma função de custo. De fato, ambas as propriedades também são satisfeitas pelo custo quadrático. Portanto, isso é uma boa notícia para a entropia cruzada. Mas a função custo de entropia cruzada tem o benefício de que, ao contrário do custo quadrático, evita o problema de desaceleração do aprendizado. Para ver isso, vamos calcular a derivada parcial do custo de entropia cruzada em relação aos pesos. Substituímos a = σ (z) na fórmula acima e aplicamos a regra da cadeia duas vezes, obtendo:

 

form1

 

Colocando tudo em um denominador comum e simplificando, isso se torna:

 

form2

 

Usando a definição da função sigmóide, σ (z) = 1 / (1 + ez), e um pouco de álgebra, podemos mostrar que σ (z) = σ (z) (1 − σ (z)). Vemos que os termos σ′ (z) e σ (z) (1 − σ (z)) se cancelam na equação acima, e simplificando torna-se:

 

form3

 

Esta é uma bela expressão. Ela nos diz que a taxa na qual o peso aprende é controlada por σ (z) −y, ou seja, pelo erro na saída. Quanto maior o erro, mais rápido o neurônio aprenderá. Isso é exatamente o que nós esperamos intuitivamente. Em particular, evita a lentidão de aprendizado causada pelo termo σ′ (z) na equação análoga para o custo quadrático. Quando usamos a entropia cruzada, o termo σ′ (z) é cancelado e não precisamos mais nos preocupar em ser pequeno. Este cancelamento é o milagre especial assegurado pela função de custo de entropia cruzada. Na verdade, não é realmente um milagre. Como veremos mais adiante, a entropia cruzada foi especialmente escolhida por ter apenas essa propriedade.

De maneira semelhante, podemos calcular a derivada parcial para o viés. Eu não vou passar por todos os detalhes novamente, mas você pode facilmente verificar que:

form4

 

Novamente, isso evita a lentidão de aprendizado causada pelo termo σ′ (z) na equação análoga para o custo quadrático.

Agora vamos retornar ao exemplo do início deste capítulo, e explorar o que acontece quando usamos a entropia cruzada em vez do custo quadrático. Para nos reorientarmos, começaremos com o caso em que o custo quadrático foi bom, com peso inicial de 0.6 e viés inicial de 0.9. Veja o que acontece quando substituímos o custo quadrático pela entropia cruzada:

 

train3

 

Como era de se esperar, o neurônio aprende perfeitamente bem neste caso, assim como fez anteriormente. E agora vamos olhar para o caso em que nosso neurônio ficou preso antes, com o peso e o viés ambos começando em 2.0:

 

train4

 

Sucesso! Desta vez, o neurônio aprendeu rapidamente, exatamente como esperávamos. Se você observar atentamente, pode ver que a inclinação da curva de custo era muito mais íngreme inicialmente do que a região plana inicial na curva correspondente para o custo quadrático. É essa inclinação que a entropia cruzada nos ajuda a resolver, impedindo-nos de ficar presos exatamente quando esperamos que nosso neurônio aprenda mais depressa, ou seja, quando o neurônio começa errado.

Eu não disse qual taxa de aprendizado foi usada nos exemplos que acabei de ilustrar. Anteriormente, com o custo quadrático, usamos η = 0.15. Deveríamos ter usado a mesma taxa de aprendizado nos novos exemplos? De fato, com a mudança na função de custo, não é possível dizer precisamente o que significa usar a “mesma” taxa de aprendizado; é uma comparação de maçãs e laranjas. Para ambas as funções de custo, simplesmente experimentei encontrar uma taxa de aprendizado que possibilitasse ver o que está acontecendo. Se você ainda estiver curioso, aqui está o resumo: usei η = 0.005 nos exemplos que acabei de fornecer.

Você pode contestar que a mudança na taxa de aprendizado torna os gráficos acima sem sentido. Quem se importa com a rapidez com que o neurônio aprende, quando a nossa escolha de taxa de aprendizado foi arbitrária, para começar ?! Mas essa objeção não procede. O ponto dos gráficos não é sobre a velocidade absoluta de aprendizagem. É sobre como a velocidade do aprendizado muda. Em particular, quando usamos o custo quadrático, a aprendizagem é mais lenta quando o neurônio está inequivocamente errado do que é mais tarde durante o treinamento, à medida que o neurônio se aproxima da saída correta; enquanto o aprendizado de entropia cruzada é mais rápido quando o neurônio está inequivocamente errado. Essas declarações não dependem de como a taxa de aprendizado é definida.

Estamos estudando a entropia cruzada para um único neurônio. No entanto, é fácil generalizar a entropia cruzada para redes multicamadas de muitos neurônios. Em particular, suponha que y = y1, y2,… são os valores desejados nos neurônios de saída, ou seja, os neurônios na camada final, enquanto aL1, aL2,… são os valores reais de saída. Então nós definimos a entropia cruzada por:

 

cost

 

Isso é o mesmo que nossa expressão anterior, exceto que agora nós temos o ∑j somando todos os neurônios de saída. Não vou explicitamente trabalhar com uma derivação, mas deve ser plausível que o uso da expressão anterior evite uma desaceleração na aprendizagem em muitas redes de neurônios.

A propósito, estou usando o termo “entropia cruzada” de uma maneira que confundiu alguns dos primeiros leitores, já que parece superficialmente entrar em conflito com outras fontes. Em particular, é comum definir a entropia cruzada para duas distribuições de probabilidade, pj e qj, como ∑jpjlnqj. Esta definição pode ser conectada a fórmula da entropia para um neurônio mostrada anteriormente, se tratarmos um único neurônio sigmóide como saída de uma distribuição de probabilidade que consiste na ativação a do neurônio ae seu complemento 1 − a.

No entanto, quando temos muitos neurônios sigmoides na camada final, o vetor aLj de ativações não costuma formar uma distribuição de probabilidade. Como resultado, uma definição como ∑jpjlnqj não faz sentido, já que não estamos trabalhando com distribuições de probabilidade. Em vez disso, você pode pensar na fórmula da entropia para múltiplos neurônios como um conjunto somado de entropias cruzadas por neurônio, com a ativação de cada neurônio sendo interpretada como parte de uma distribuição de probabilidade de dois elementos. Sim, eu sei que isso não é simples.

Nesse sentido, a fórmula da entropia para múltiplos neurônios é uma generalização da entropia cruzada para distribuições de probabilidade.

Quando devemos usar a entropia cruzada em vez do custo quadrático? De fato, a entropia cruzada é quase sempre a melhor escolha, desde que os neurônios de saída sejam neurônios sigmóides. Para entender por que, considere que, quando estamos configurando a rede, normalmente inicializamos os pesos e vieses usando algum tipo de aleatoriedade. Pode acontecer que essas escolhas iniciais resultem na rede sendo decisivamente errada para alguma entrada de treinamento – isto é, um neurônio de saída terá saturado próximo de 1, quando deveria ser 0, ou vice-versa. Se estamos usando o custo quadrático que irá desacelerar a aprendizagem, ele não vai parar de aprender completamente, já que os pesos continuarão aprendendo com outras entradas de treinamento, mas é obviamente indesejável.

Construir aplicações de IA é uma habilidade com demanda cada vez maior no mercado.

Até o próximo capítulo!

Referências:

Dot Product 

Neural Networks & The Backpropagation Algorithm, Explained

Derivada

Machine Learning

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

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Redes Neurais, princípios e práticas

Deep Learning Book

Capítulo 16 – Algoritmo Backpropagation em Python

by

Depois de compreender como funciona o backpropagation, podemos agora entender o código usado em alguns capítulos anteriores para implementar o algoritmo (o qual vamos reproduzir aqui). 

Em nosso código nós temos os métodos update_mini_batch e backprop da classe Network. Em particular, o método update_mini_batch atualiza os pesos e bias da rede calculando o gradiente para o mini_batch atual de exemplos (dados) de treinamento:

 

metodo1

 

A maior parte do trabalho é feita pela linha:

delta_nabla_b, delta_nabla_w = self.backprop (x, y)

que usa o método backprop para descobrir as derivadas parciais ∂Cx / ∂blj e ∂Cx / ∂wljk. Isso invoca o algoritmo de backpropagation, que é uma maneira rápida de calcular o gradiente da função de custo. Portanto, update_mini_batch funciona simplesmente calculando esses gradientes para cada exemplo de treinamento no mini_batch e, em seguida, atualizando self.weights e self.biases adequadamente. Há uma pequena mudança – usamos uma abordagem ligeiramente diferente para indexar as camadas. Essa alteração é feita para aproveitar um recurso do Python, ou seja, o uso de índices de lista negativa para contar para trás a partir do final de uma lista, por exemplo, lst[-3] é a terceira última entrada em uma lista chamada lst. O código para backprop está abaixo, junto com algumas funções auxiliares, que são usadas para calcular a função σ, a derivada σ′ e a derivada da função de custo. Com essas inclusões, você deve ser capaz de entender o código de maneira independente:

 

backprop

 

Observe o método backprop. Começamos inicalizando as matrizes de pesos (nabla_w) e bias (nabla_b) com zeros. Essas  matrizes serão alimentadas com valores durante o processo de treinamento. Isso é o que a rede neural artificial efetivamente aprende. Depois de inicializar alguns objetos, temos um loop for para cada valor de b e w (que a esta altura você já sabe se trata de bias e pesos, respectivamente). Neste loop, usamos a função np.dot do Numpy para a multiplicação entre matrizes e adição do bias, colocamos o resultado na lista z e fazemos uma chamada à função de ativação Sigmóide. Ao final deste loop, teremos a lista com todas as ativações e finalizamos a passada para a frente.

Na passada para trás (Backward Pass) calculamos as derivadas e fazemos as multiplicações de matrizes mais uma vez (o funcionamento de redes neurais artificiais é baseado em um conceito elementar da Álgebra Linear, a multiplicação de matrizes). Repare que chamamos o método Transpose() para gerar a transposta da matriz e assim ajustar as dimensões antes de efetuar os cálculo. Por fim, retornamos bias e pesos.

Em que sentido backpropagation é um algoritmo rápido?

Para responder a essa pergunta, vamos considerar outra abordagem para calcular o gradiente. Imagine que é o início da pesquisa de redes neurais. Talvez seja a década de 1950 ou 1960, e você é a primeira pessoa no mundo a pensar em usar gradiente descendente para o aprendizado! Mas, para que a ideia funcione, você precisa de uma maneira de calcular o gradiente da função de custo. Você volta ao seu conhecimento de cálculo e decide se pode usar a regra da cadeia (chain rule) para calcular o gradiente. Mas depois de brincar um pouco, a álgebra parece complicada e você fica desanimado. Então você tenta encontrar outra abordagem. Você decide considerar o custo como uma função apenas dos pesos C = C(w) (voltaremos ao bias em um momento). Você numera os pesos w1, w2,… e deseja computar ∂C / ∂wj para um peso específico wj. Uma maneira óbvia de fazer isso é usar a aproximação

form

onde ϵ> 0 é um pequeno número positivo e ej é o vetor unitário na direção j. Em outras palavras, podemos estimar ∂C / ∂wj calculando o custo C para dois valores ligeiramente diferentes de wj e, em seguida, aplicando a equação. A mesma ideia nos permitirá calcular as derivadas parciais ∂C / ∂b em relação aos vieses (bias).

Essa abordagem parece muito promissora. É simples conceitualmente e extremamente fácil de implementar, usando apenas algumas linhas de código. Certamente, parece muito mais promissor do que a ideia de usar a regra da cadeia para calcular o gradiente!

Infelizmente, embora essa abordagem pareça promissora, quando você implementa o código, ele fica extremamente lento. Para entender porque, imagine que temos um milhão de pesos em nossa rede. Então, para cada peso distinto wj, precisamos computar C (w + ϵej) para calcular ∂C / ∂wj. Isso significa que, para calcular o gradiente, precisamos computar a função de custo um milhão de vezes diferentes, exigindo um milhão de passos para frente pela rede (por exemplo, treinamento). Precisamos calcular C(w) também, em um total de um milhão de vezes e em uma única passada pela rede.

O que há de inteligente no backpropagation é que ele nos permite calcular simultaneamente todas as derivadas parciais ∂C / ∂wj usando apenas uma passagem direta pela rede, seguida por uma passagem para trás pela rede. Grosso modo, o custo computacional do passe para trás é quase o mesmo que o do forward. Isso deve ser plausível, mas requer algumas análises para fazer uma declaração cuidadosa. É plausível porque o custo computacional dominante no passe para frente é multiplicado pelas matrizes de peso, enquanto no passo para trás é multiplicado pelas transpostas das matrizes de peso. Obviamente, essas operações têm um custo computacional similar. E assim, o custo total da retropropagação (backpropagation) é aproximadamente o mesmo que fazer apenas duas passagens pela rede. Compare isso com o milhão e um passe para frente que precisávamos para a abordagem que descrevi anteriormente. E assim, embora a retropropagação pareça superficialmente mais complexa do que a abordagem anterior, é na verdade muito, muito mais rápida.

Essa aceleração foi amplamente apreciada em 1986 e expandiu enormemente a gama de problemas que as redes neurais poderiam resolver. Isso, por sua vez, causou uma onda de pessoas usando redes neurais. Claro, a retropropagação não é uma panacéia. Mesmo no final da década de 1980, as pessoas enfrentavam limites, especialmente quando tentavam usar a retropropagação para treinar redes neurais profundas, ou seja, redes com muitas camadas ocultas. Mais adiante, no livro, veremos como os computadores modernos e algumas novas ideias inteligentes tornam possível usar a retropropagação para treinar redes neurais bem profundas.

Seu trabalho agora é estudar e compreender cada linha de código usada em nossa rede de amostra. Esse código é bem simples e o objetivo é mostrar a você como as coisas funcionam programaticamente. Ainda vamos treinar nossa rede, avaliar seu desempenho, otimizar algumas operações e compreender outros conceitos básicos. Temos muito mais vindo por aí! Até o próximo capítulo!

Referências:

Machine Learning

Dot Product 

How the backpropagation algorithm works

Delta Rule

An overview of gradient descent optimization algorithms

Neural Networks & The Backpropagation Algorithm, Explained

Derivada

Machine Learning

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

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Redes Neurais, princípios e práticas

An overview of gradient descent optimization algorithms

Optimization: Stochastic Gradient Descent

Gradient Descent vs Stochastic Gradient Descent vs Mini-Batch Learning

Deep Learning Book

Capítulo 14 – Algoritmo Backpropagation Parte 1 – Grafos Computacionais e Chain Rule

by

No último capítulo, vimos como as redes neurais podem aprender seus pesos e bias usando o algoritmo de gradiente descendente. Houve, no entanto, uma lacuna na nossa explicação: não discutimos como calcular o gradiente da função de custo. Neste capítulo, explicaremos sobre um algoritmo usado para calcular esses gradientes, um algoritmo conhecido como backpropagation. Como esse tema é a essência do treinamento de redes neurais, vamos dividí-lo em dois capítulos. Vamos começar com Algoritmo Backpropagation Parte 1 – Grafos Computacionais e Chain Rule.

O backpropagation é indiscutivelmente o algoritmo mais importante na história das redes neurais – sem backpropagation, seria quase impossível treinar redes de aprendizagem profunda da forma que vemos hoje. O backpropagation pode ser considerado a pedra angular das redes neurais modernas e consequentemente do Deep Learning.

O algoritmo backpropagation foi originalmente introduzido na década de 1970, mas sua importância não foi totalmente apreciada até um famoso artigo de 1986 de David Rumelhart, Geoffrey Hinton e Ronald Williams. Esse artigo descreve várias redes neurais em que o backpropagation funciona muito mais rapidamente do que as abordagens anteriores de aprendizado, possibilitando o uso de redes neurais para resolver problemas que antes eram insolúveis.

O backpropagation é o algoritmo-chave que faz o treinamento de modelos profundos algo computacionalmente tratável. Para as redes neurais modernas, ele pode tornar o treinamento com gradiente descendente até dez milhões de vezes mais rápido, em relação a uma implementação ingênua. Essa é a diferença entre um modelo que leva algumas horas ou dias para treinar e e outro que poderia levar anos (sem exagero).

Além de seu uso em Deep Learning, o backpropagation é uma poderosa ferramenta computacional em muitas outras áreas, desde previsão do tempo até a análise da estabilidade numérica. De fato, o algoritmo foi reinventado pelo menos dezenas de vezes em diferentes campos. O nome geral, independente da aplicação, é “diferenciação no modo reverso”.

Fundamentalmente, backpropagation é uma técnica para calcular derivadas rapidamente (não sabe o que é derivada? Consulte o link para um excelente vídeo em português explicando esse conceito em detalhes nas referências ao final deste capítulo). E é um truque essencial, não apenas em Deep Learning, mas em uma ampla variedade de situações de computação numérica. E para compreender backpropagation de forma efetiva, vamos primeiro compreender o conceito de grafo computacional e chain rule.

Grafo Computacional

Grafos computacionais são uma boa maneira de pensar em expressões matemáticas. O conceito de grafo foi introduzido por Leonhard Euler em 1736 para tentar resolver o problema das Pontes de Konigsberg. Grafos são modelos matemáticos para resolver problemas práticos do dia a dia, com várias aplicações no mundo real tais como: circuitos elétricos, redes de distribuição, relações de parentesco entre pessoas, análise de redes sociais, logística, redes de estradas, redes de computadores e muito mais. Grafos são muito usados para modelar problemas em computação.

Um Grafo é um modelo matemático que representa relações entre objetos. Um grafo G = (V, E) consiste de um conjunto de vértices V (também chamados de nós), ligados por um conjunto de bordas ou arestas E. Para aprender sobre grafos em mais detalhes, clique aqui.

Por exemplo, considere a expressão:

 

e = (a + b) ∗ (b + 1)

 

Existem três operações: duas adições e uma multiplicação. Para facilitar a compreensão sobre isso, vamos introduzir duas variáveis intermediárias c e d para que a saída de cada função tenha uma variável. Nós agora temos:

 

c = a+b
d = b+1
e = c∗d

 

Para criar um grafo computacional, fazemos cada uma dessas operações nos nós, juntamente com as variáveis de entrada. Quando o valor de um nó é a entrada para outro nó, uma seta vai de um para outro e temos nesse caso um grafo direcionado.

 

tree-def

 

Esses tipos de grafos surgem o tempo todo em Ciência da Computação, especialmente ao falar sobre programas funcionais. Eles estão intimamente relacionados com as noções de grafos de dependência e grafos de chamadas. Eles também são a principal abstração por trás do popular framework de Deep Learning, o TensorFlow.

Podemos avaliar a expressão definindo as variáveis de entrada para determinados valores e computando os nós através do grafo. Por exemplo, vamos definir a = 2 e b = 1:

 

tree-eval

 

A expressão, nesse exemplo, é avaliada como 6.

Derivadas em Grafos Computacionais

Se alguém quiser entender derivadas em um grafo computacional, a chave é entender as derivadas nas bordas (arestas que conectam os nós no grafo). Se a afeta diretamente c, então queremos saber como isso afeta c. Se a muda um pouco, como c muda? Chamamos isso de derivada parcial de c em relação a a.

Para avaliar as derivadas parciais neste grafo, precisamos da regra da soma e da regra do produto:

 

derivada

 

Abaixo, o grafo tem a derivada em cada borda (aresta) rotulada.

 

 tree-eval-derivs

 

 

E se quisermos entender como os nós que não estão diretamente conectados afetam uns aos outros? Vamos considerar como e é afetado por a. Se mudarmos a uma velocidade de 1, c também muda a uma velocidade de 1. Por sua vez, c mudando a uma velocidade de 1 faz com que e mude a uma velocidade de 2. Então e muda a uma taxa de 1 ∗ 2 em relação a a (analise o diagrama acima para visualizar isso).

A regra geral é somar todos os caminhos possíveis de um nó para o outro, multiplicando as derivadas em cada aresta do caminho. Por exemplo, para obter a derivada de e em relação a b, obtemos:

form

Isso explica como b afeta e através de c e também como isso afeta d.

Essa regra geral de “soma sobre caminhos” é apenas uma maneira diferente de pensar sobre a regra da cadeia multivariada ou chain rule.

Fatorando os Caminhos

O problema com apenas “somar os caminhos” é que é muito fácil obter uma explosão combinatória no número de caminhos possíveis.

 

chain-def-greek

 

No diagrama acima, existem três caminhos de X a Y, e mais três caminhos de Y a Z. Se quisermos obter a derivada ∂Z/∂X somando todos os caminhos, precisamos calcular 3 ∗ 3 = 9 caminhos:

 

form2

 

O exemplo acima só tem nove caminhos, mas seria fácil o número de caminhos crescer exponencialmente à medida que o grafo se torna mais complicado. Em vez de apenas ingenuamente somar os caminhos, seria muito melhor fatorá-los:

 

form3

 

É aí que entram a “diferenciação de modo de avanço” (forward-mode differentiation ou forward pass) e a “diferenciação de modo reverso” (reverse-mode differentiation ou backpropagation). Eles são algoritmos para calcular a soma de forma eficiente fatorando os caminhos. Em vez de somar todos os caminhos explicitamente, eles calculam a mesma soma de forma mais eficiente, mesclando os caminhos juntos novamente em cada nó. De fato, os dois algoritmos tocam cada borda exatamente uma vez!

A diferenciação do modo de avanço inicia em uma entrada para o grafo e se move em direção ao final. Em cada nó, soma todos os caminhos que se alimentam. Cada um desses caminhos representa uma maneira na qual a entrada afeta esse nó. Ao adicioná-los, obtemos a maneira total em que o nó é afetado pela entrada, isso é a derivada.

 

chain-forward-greek

 

Embora você provavelmente não tenha pensado nisso em termos de grafos, a diferenciação no modo de avanço é muito parecida com o que você aprendeu implicitamente caso tenha feito alguma introdução a Cálculo.

A diferenciação no modo reverso, por outro lado, começa na saída do grafo e se move em direção ao início (ou seja, se retropropaga ou backpropagation). Em cada nó, ele mescla todos os caminhos originados nesse nó.

 

chain-backward-greek

 

A diferenciação do modo de avanço rastreia como uma entrada afeta todos os nós. A diferenciação no modo reverso rastreia como cada nó afeta uma saída. Ou seja, a diferenciação de modo de avanço aplica o operador ∂/∂X a cada nó, enquanto a diferenciação de modo reverso aplica o operador ∂Z/∂ a cada nó. Se isso parece o conceito de programação dinâmica, é porque é exatamente isso! (acesse um material sobre programação dinâmica nas referências ao final do capítulo)

Nesse ponto, você pode se perguntar porque alguém se importaria com a diferenciação no modo reverso. Parece uma maneira estranha de fazer a mesma coisa que o modo de avanço. Existe alguma vantagem? Vamos considerar nosso exemplo original novamente:

 

tree-eval-derivs

 

Podemos usar a diferenciação de modo de avanço de b para cima. Isso nos dá a derivada de cada nó em relação a b.

 

tree-forwradmode

 

Nós calculamos ∂e/∂b, a derivada de nossa saída em relação a um de nossos inputs. E se fizermos a diferenciação de modo reverso de e para baixo? Isso nos dá a derivada de e em relação a todos os nós:

tree-backprop

 

Quando digo que a diferenciação no modo reverso nos dá a derivada de e em relação a cada nó, eu realmente quero dizer cada nó. Temos tanto ∂e/∂a quanto ∂e/∂b, as derivadas de e em relação a ambas as entradas. A diferenciação no modo de avanço nos deu a derivada de nossa saída em relação a uma única entrada, mas a diferenciação no modo reverso nos dá todos eles.

Para este grafo, isso é apenas um fator de duas velocidades, mas imagine uma função com um milhão de entradas e uma saída. A diferenciação no modo de avanço exigiria que passássemos pelo grafo um milhão de vezes para obter as derivadas. Diferenciação no modo reverso pode fazer isso em uma só passada! Uma aceleração de um fator de um milhão é bem legal e explica porque conseguimos treinar um modelo de rede neural profunda em tempo razoável.

Ao treinar redes neurais, pensamos no custo (um valor que descreve o quanto uma rede neural é ruim) em função dos parâmetros (números que descrevem como a rede se comporta). Queremos calcular as derivadas do custo em relação a todos os parâmetros, para uso em descida do gradiente. Entretanto, muitas vezes, há milhões ou até dezenas de milhões de parâmetros em uma rede neural. Então, a diferenciação no modo reverso, chamada de backpropagation no contexto das redes neurais, nos dá uma velocidade enorme!

Existem casos em que a diferenciação de modo de avanço faz mais sentido? Sim, existem! Onde o modo reverso fornece as derivadas de uma saída em relação a todas as entradas, o modo de avanço nos dá as derivadas de todas as saídas em relação a uma entrada. Se tiver uma função com muitas saídas, a diferenciação no modo de avanço pode ser muito, muito mais rápida.

Agora faz sentido?

Quando aprendemos pela primeira vez o que é backpropagation, a reação é: “Oh, essa é apenas a regra da cadeia (chain rule)! Como demoramos tanto tempo para descobrir?”

Na época em que o backpropagation foi inventado, as pessoas não estavam muito focadas nas redes neurais feedforward. Também não era óbvio que as derivadas eram o caminho certo para treiná-las. Esses são apenas óbvios quando você percebe que pode calcular rapidamente derivadas. Houve uma dependência circular.

Treinar redes neurais com derivadas? Certamente você ficaria preso em mínimos locais. E obviamente seria caro computar todas essas derivadas. O fato é que só porque sabemos que essa abordagem funciona é que não começamos imediatamente a listar os motivos que provavelmente não funcionaria. Já sabemos que funciona, mas novas abordagens vem sendo propostas no avanço das pesquisas em Deep Learning e Inteligência Artificial.

Conclusão da Parte 1

O backpropagation também é útil para entender como as derivadas fluem através de um modelo. Isso pode ser extremamente útil no raciocínio sobre porque alguns modelos são difíceis de otimizar. O exemplo clássico disso é o problema do desaparecimento de gradientes em redes neurais recorrentes, que discutiremos mais diante neste livro.

Por fim, há uma lição algorítmica ampla a ser retirada dessas técnicas. Backpropagation e forward-mode differentiation usam um poderoso par de truques (linearização e programação dinâmica) para computar derivadas de forma mais eficiente do que se poderia imaginar. Se você realmente entende essas técnicas, pode usá-las para calcular com eficiência várias outras expressões interessantes envolvendo derivadas.

Mas este capítulo teve como objetivo apenas ajudá-lo a compreender o algoritmo, já que praticamente não existe documentação sobre isso em português. Falta ainda compreender como o backpropagation é aplicado no treinamento das redes neurais. Ansioso por isso? Então acompanhe o próximo capítulo!

Referências:

Me Salva! Cálculo – O que é uma derivada?

The Birth Of Graph Theory: Leonhard Euler And The Königsberg Bridge Problem

Learning representations by back-propagating errors

Chain Rule

Calculus on Computational Graphs: Backpropagation

How the backpropagation algorithm works

Dynamic programming

Nota: parte das imagens usadas neste capítulo foram extraídas no excelente post (citado nas referências acima) de Christopher Olah, pesquisador de Machine Learning do Google Brain, e com a devida autorização do autor.

Deep Learning Book

Capítulo 13 – Construindo Uma Rede Neural Com Linguagem Python

by

Ok. Chegou a hora. Vamos escrever um programa em linguagem Python que aprenda como reconhecer dígitos manuscritos, usando Stochastic Gradient Descent e o dataset de treinamento MNIST. Se você chegou até aqui sem ler os capítulos anteriores, então pare imediatamente, leia os últimos 12 capítulos e depois volte aqui! Não tenha pressa! Não existe atalho para o aprendizado!

 

******************************** Atenção ********************************

Este capítulo considera que você já tem o interpretador Python instalado no seu computador, seja ele com sistema operacional Windows, MacOS ou Linux. Recomendamos que você instale o Anaconda e que já possua conhecimentos em linguagem Python. Se esse não for seu caso, antes de ler este capítulo e executar os exemplos aqui fornecidos, acesse o curso gratuito Fundamentos de Linguagem Python Para Análise de Dados e Data Science.

Usaremos Python 3 e você deve construir os scripts no seu computador. Vamos começar!

*************************************************************************

 

Quando descrevemos o dataset MNIST anteriormente, dissemos que ele estava dividido em 60.000 imagens de treinamento e 10.000 imagens de teste. Essa é a descrição oficial do MNIST. Mas vamos dividir os dados de forma um pouco diferente. Deixaremos as imagens de teste como está, mas dividiremos o conjunto de treinamento MNIST de 60.000 imagens em duas partes: um conjunto de 50.000 imagens, que usaremos para treinar nossa rede neural e um conjunto separado de validação de 10.000 imagens. Não utilizaremos os dados de validação neste capítulo, porém mais tarde, aqui mesmo no livro, usaremos este dataset quando estivermos configurando certos hiperparâmetros da rede neural, como a taxa de aprendizado por exemplo. Embora os dados de validação não façam parte da especificação MNIST original, muitas pessoas usam o MNIST desta forma e o uso de dados de validação é comum em redes neurais. Quando eu me referir aos “dados de treinamento MNIST” de agora em diante, vou me referir ao nosso conjunto de dados de 50.000 imagens, e não ao conjunto de dados de 60.000 imagens. Fique atento!

Além dos dados MNIST, também precisamos de uma biblioteca Python chamada Numpy, para álgebra linear. Se você instalou o Anaconda, não precisa se preocupar, pois o Numpy já está instalado. Caso contrário, será necessário fazer a instalação do pacote.

Mas antes de carregar e dividir os dados, vamos compreender os principais recursos do nosso código para construção de uma rede neural. A peça central é uma classe chamada Network, que usamos para representar uma rede neural. Abaixo a classe Network e seu construtor:

 

 

Neste código, o parâmetro sizes contêm o número de neurônios nas respectivas camadas, sendo um objeto do tipo lista em Python. Então, por exemplo, se queremos criar um objeto da classe Network com 2 neurônios na primeira camada, 3 neurônios na segunda camada e 1 neurônio na camada final, aqui está o código que usamos para instanciar um objeto da classe Network::

 

rede1 = Network([2, 3, 1])

 

Os bias e pesos no objeto rede1 são todos inicializados aleatoriamente, usando a função Numpy np.random.randn para gerar distribuições gaussianas com 0 de média e desvio padrão 1. Esta inicialização aleatória dá ao nosso algoritmo de descida do gradiente estocástico um local para começar. Em capítulos posteriores, encontraremos melhores maneiras de inicializar os pesos e os bias. Observe que o código de inicialização de rede assume que a primeira camada de neurônios é uma camada de entrada e omite a definição de quaisquer bias para esses neurônios, uma vez que os bias são usados apenas para calcular as saídas de camadas posteriores.

Observe também que os bias e pesos são armazenados como listas de matrizes Numpy. Assim, por exemplo, rede1.weights[1] é uma matriz Numpy armazenando os pesos conectando a segunda e terceira camadas de neurônios. (Não é a primeira e segunda camadas, uma vez que a indexação da lista em Python começa em 0.) Uma vez que rede1.weights[1] é bastante detalhado, vamos apenas indicar essa matriz w. É uma matriz tal que wjk é o peso para a conexão entre o neurônio kth na segunda camada e o neurônio jth na terceira camada. Essa ordenação dos índices j e k pode parecer estranha – certamente teria mais sentido trocar os índices j e k? A grande vantagem de usar essa ordenação é que isso significa que o vetor de ativações da terceira camada de neurônios é:

 

Form

Equação 1

 

Onde, a é o vetor de ativações da segunda camada de neurônios. Para obter um a’ multiplicamos a pela matriz de peso w, e adicionamos o vetor b com os bias (se você leu os capítulos anteriores, isso não deve ser novidade agora). Em seguida, aplicamos a função σ de forma elementar a cada entrada no vetor wa + b. (Isto é chamado de vetorizar a função σ.)

Com tudo isso em mente, é fácil escrever código que computa a saída de uma instância de rede. Começamos definindo a função sigmoide:

 

 

Observe que quando a entrada z é um vetor ou uma matriz Numpy, Numpy aplica automaticamente a função sigmoid elementwise, ou seja, na forma vetorizada.

Em seguida, adicionamos um método feedforward à classe Network, que, dada a entrada a para a rede, retorna a saída corresponente. Basicamente o método feedforward aplica a Equação 1 mostrada acima, para cada camada:

 

 

A principal atividade que queremos que nossos objetos da classe Network façam é aprender. Para esse fim, criaremos um método SGD (Stochastic Gradient Descent). Aqui está o código. É um pouco misterioso em alguns lugares, mas vamos explicar em detalhes mais abaixo:

 

 

O training_data é uma lista de tuplas (x, y) que representam as entradas de treinamento e as correspondentes saídas desejadas. As variáveis epochs e mini_batch_size são o que você esperaria – o número de épocas para treinar e o tamanho dos mini-lotes a serem usados durante a amostragem, enquanto eta é a taxa de aprendizagem, η. Se o argumento opcional test_data for fornecido, o programa avaliará a rede após cada período de treinamento e imprimirá progresso parcial. Isso é útil para rastrear o progresso, mas retarda substancialmente as coisas.

O código funciona da seguinte forma. Em cada época, ele começa arrastando aleatoriamente os dados de treinamento e, em seguida, particiona-os em mini-lotes de tamanho apropriado. Esta é uma maneira fácil de amostragem aleatória dos dados de treinamento. Então, para cada mini_batch, aplicamos um único passo de descida do gradiente. Isso é feito pelo código self.update_mini_batch (mini_batch, eta), que atualiza os pesos e os bias da rede de acordo com uma única iteração de descida de gradiente, usando apenas os dados de treinamento em mini_batch. Aqui está o código para o método update_mini_batch:

 

 

A maior parte do trabalho é feita pela linha delta_nabla_b, delta_nabla_w = self.backprop (x, y). Isso invoca algo chamado algoritmo de backpropagation, que é uma maneira rápida de calcular o gradiente da função de custo. Portanto, update_mini_batch funciona simplesmente calculando esses gradientes para cada exemplo de treinamento no mini_batch e, em seguida, atualizando self.weights e self.biases adequadamente.

Abaixo você encontra o código para self.backprop, mas não estudaremos ele agora. Estudaremos em detalhes como funciona o backpropagation no próximo capítulo, incluindo o código para self.backprop. Por hora, basta assumir que ele se comporta conforme indicado, retornando o gradiente apropriado para o custo associado ao exemplo de treinamento x.

 

 

Além do self.backprop, o programa é auto-explicativo – todo o levantamento pesado é feito em self.SGD e self.update_mini_batch, que já discutimos. O método self.backprop faz uso de algumas funções extras para ajudar no cálculo do gradiente, nomeadamente sigmoid_prime, que calcula a derivada da função σ e self.cost_derivative.

A classe Network é em essência nosso algoritmo de rede neural. A partir dela criamos uma instância (como rede1), alimentamos com os dados de treinamento e realizamos o treinamento. Avaliamos então a performance da rede com dados de teste e repetimos todo o processo até alcançar o nível de acurácia desejado em nosso projeto. Quando o modelo final estiver pronto, usamos para realizar as previsões para as quais o modelo foi criado, apresentando a ele novos conjuntos de dados e extraindo as previsões. Perceba que este é um algoritmo de rede neural bem simples, mas que permite compreender como funcionam as redes neurais e mais tarde, aqui mesmo no livro, as redes neurais profundas ou Deep Learning.

No próximo capítulo vamos continuar trabalhando com este algoritmo e compreender como funciona o Backpropagation. Na sequência, vamos carregar os dados, treinar e testar nossa rede neural e então usá-la para reconhecer dígitos manuscritos. Até lá.

Referências:

MNIST

Derivada

Machine Learning

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

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning

An overview of gradient descent optimization algorithms

Optimization: Stochastic Gradient Descent

Gradient Descent vs Stochastic Gradient Descent vs Mini-Batch Learning

Deep Learning Book

Capítulo 12 – Aprendizado Com a Descida do Gradiente

by

No capítulo anterior definimos o design para a nossa rede neural e agora podemos começar o processo de aprendizado de máquina. Neste capítulo você vai compreender o que é o Aprendizado Com a Descida do Gradiente.

A primeira coisa que precisamos é um conjunto de dados para o treinamento da rede. Usaremos o conjunto de dados MNIST, que contém dezenas de milhares de imagens digitalizadas de dígitos manuscritos, juntamente com suas classificações corretas. O nome MNIST vem do fato de que é um subconjunto modificado de dois conjuntos de dados coletados pelo NIST, o Instituto Nacional de Padrões e Tecnologia dos Estados Unidos. Aqui estão algumas imagens do MNIST:

 

 

O MNIST tem duas partes. A primeira parte contém 60.000 imagens para serem usadas como dados de treinamento. Essas imagens são amostras de manuscritos escaneados de 250 pessoas, metade dos quais funcionários do Bureau do Censo dos EUA e metade dos estudantes do ensino médio. As imagens estão em escala de cinza e 28 por 28 pixels de tamanho. A segunda parte do conjunto de dados MNIST tem 10.000 imagens a serem usadas como dados de teste, também 28 por 28 pixels em escala de cinza. Usaremos os dados do teste para avaliar o quão bem a nossa rede neural aprendeu a reconhecer os dígitos. Para fazer deste um bom teste de desempenho, os dados de teste foram retirados de um conjunto diferente de 250 pessoas em relação aos dados de treinamento originais (embora ainda seja um grupo dividido entre funcionários do Census Bureau e alunos do ensino médio). Isso nos ajuda a confiar que nosso sistema pode reconhecer dígitos de pessoas cuja escrita não viu durante o treinamento.

Usaremos a notação x para indicar uma entrada (input) de treinamento. Será conveniente considerar cada entrada de treinamento x (cada imagem) como um vetor de 784 posições (28 x 28 pixels). A imagem abaixo representa como este vetor é construído:

 

 

Cada entrada no vetor representa o valor de cinza para um único pixel na imagem. Vamos indicar a saída correspondente desejada por y = y(x), onde y é um vetor com dimensão 10. Por exemplo, se uma imagem de treinamento particular, x, representa um 3, então y(x) = (0,0,0,1,0,0,0,0,0,0)T é a saída desejada da rede . Observe que T aqui é a operação de transposição, transformando um vetor de linha em um vetor comum (coluna). Vamos deixar isso mais claro. Observe a figura abaixo:

 

 

Vamos usar os pixels de imagem correspondentes ao fluxo inteiro chamado “features”. Os rótulos são One-Hot Encoded 1-hot. O rótulo que representa a classe de saída da imagem com dígito 3 torna-se “0001000000” uma vez que temos 10 classes para os 10 dígitos possíveis, onde o primeiro índice corresponde ao dígito “0” e o último corresponde ao dígito “9”.

O que queremos é um algoritmo que nos permita encontrar pesos e bias para que a saída da rede se aproxime de y(x) para todas as entradas de treinamento x. Para quantificar o quão bem estamos alcançando esse objetivo, definimos uma função de custo:

 

Função Quadrático de Custo

 

Na fórmula acima, w indica a coleta de todos os pesos na rede, b todos os bias (viés), n é o número total de entradas de treinamento, a é o vetor de saídas da rede (quando x é entrada) e a soma é sobre todas as entradas de treinamento x. Claro, a saída a depende de x, w e b, mas para manter a notação simples, eu não indiquei explicitamente essa dependência. A notação ‖v‖ apenas indica a função de comprimento usual para um vetor v. Chamaremos C a função de custo quadrático, que também é conhecido como o erro quadrático médio ou apenas o MSE (Mean Squared Error). Inspecionando a forma da função de custo quadrático, vemos que C (w, b) não é negativo, pois cada termo na soma não é negativo. Além disso, o custo C (w, b) torna-se pequeno, isto é, C (w, b) ≈ 0, precisamente quando y(x) é aproximadamente igual à saída, a, para todas as entradas de treinamento x.

Portanto, nosso algoritmo de treinamento faz um bom trabalho se ele pode encontrar pesos e bias para que C (w, b) ≈ 0. Isso significa basicamente que nosso modelo fez as previsões corretas, ou seja, cada vez que apresentamos ao modelo uma imagem com dígito 3, ele é capaz de reconhecer que se trata do número 3.

Em contraste, o algoritmo não terá boa performance, quando C (w, b) for um valor maior que 0 – isso significaria que nosso algoritmo não está conseguindo fazer as previsões, ou seja, quando apresentado a imagem com o dígito 3, ele não é capaz de prever que se trata de um número 3. Isso ocorre, porque a diferença entre o valor real da saída e o valor previsto pelo modelo, é muito alta. Assim, o objetivo do nosso algoritmo de treinamento será minimizar o custo C(w, b) em função dos pesos e dos bias. Em outras palavras, queremos encontrar um conjunto de pesos e bias que tornem o custo o menor possível. Vamos fazer isso usando um algoritmo conhecido como Descida do Gradiente (Gradient Descent).

Mas antes, uma pergunta. Por que introduzir o custo quadrático? Afinal, não nos interessamos principalmente pelo número de imagens corretamente classificadas pela rede? Por que não tentar maximizar esse número diretamente, em vez de minimizar uma medida, como o custo quadrático? O problema com isso é que o número de imagens corretamente classificadas não é uma “smooth function” dos pesos e bias na rede. Geralmente, fazer pequenas mudanças nos pesos e bias não causará nenhuma alteração no número de imagens de treinamento classificadas corretamente. Isso torna difícil descobrir como mudar os pesos e os bias para melhorar o desempenho. Se, em vez disso, usamos uma “smooth cost function”, como o custo quadrático, revela-se fácil descobrir como fazer pequenas mudanças nos pesos e nos bias para obter uma melhoria no custo. É por isso que nos concentramos primeiro na minimização do custo quadrático e somente depois examinaremos a precisão da classificação.

Mesmo considerando que queremos usar uma “smooth cost function”, você ainda pode se perguntar por que escolhemos a função quadrática. Talvez se escolhêssemos uma função de custo diferente, obteríamos um conjunto totalmente diferente de pesos e bias? Esta é uma preocupação válida e, mais tarde, revisitaremos a função de custo e faremos algumas modificações. No entanto, a função de custo quadrático mostrada anteriormente funciona perfeitamente para entender os conceitos básicos de aprendizagem em redes neurais, então ficaremos com isso por enquanto.

Recapitulando, nosso objetivo na construção de uma rede neural é encontrar pesos e bias que minimizem a função de custo quadrático C (w, b).

Descida do Gradiente

A maioria das tarefas em Machine Learning são na verdade problemas de otimização e um dos algoritmos mais usados para isso é o Algoritmo de Descida do Gradiente. Para um iniciante, o nome Algoritmo de Descida do Gradiente pode parecer intimidante, mas espero que depois de ler o que está logo abaixo, isso deixe de ser um mistério para você.

A Descida do Gradiente é uma ferramenta padrão para otimizar funções complexas iterativamente dentro de um programa de computador. Seu objetivo é: dada alguma função arbitrária, encontrar um mínimo. Para alguns pequenos subconjuntos de funções – aqueles que são convexos – há apenas um único minumum que também acontece de ser global. Para as funções mais realistas, pode haver muitos mínimos, então a maioria dos mínimos são locais. Certifique-se de que a otimização encontre o “melhor” minimum e não fique preso em mínimos sub-otimistas (um problema comum durante o treinamento do algoritmo).

Para compreender a intuição da Descida do Gradiente, vamos simplificar um pouco as coisas. Vamos imaginar que simplesmente recebemos uma função de muitas variáveis e queremos minimizar essa função. Vamos desenvolver a técnica chamada Descida do Gradiente que pode ser usada para resolver tais problemas de minimização. Então, voltaremos para a função específica que queremos minimizar para as redes neurais.

Ok, suponhamos que estamos tentando minimizar alguma função, C(v). Esta poderia ser qualquer função de valor real de muitas variáveis, onde v = v1, v2, …. Observe que eu substitui a notação w e b por v para enfatizar que esta poderia ser qualquer função – não estamos mais pensando especificamente no contexto das redes neurais apenas. Para minimizar C (v), vamos imaginar C como uma função de apenas duas variáveis, que chamaremos v1 e v2, conforme pode ser visto na figura abaixo:

Descida do Gradiente

O que queremos é encontrar onde C atinge seu mínimo global. Fica claro, que para a função traçada no gráfico acima, podemos observar facilmente o gráfico e encontrar o mínimo. Mas uma função geral, C, pode ser uma função complicada de muitas variáveis, e geralmente não será possível apenas observar o gráfico para encontrar o mínimo.

Uma maneira de atacar o problema é usar Cálculo (especificamente Álgebra Linear) para tentar encontrar o mínimo de forma analítica. Podemos calcular derivadas e depois tentar usá-las para encontrar lugares onde C é um extremum. Isso pode funcionar quando C é uma função de apenas uma ou algumas variáveis. Mas vai se transformar em um pesadelo quando tivermos muitas outras variáveis. E para as redes neurais, muitas vezes queremos muito mais variáveis – as maiores redes neurais têm funções de custo que dependem de bilhões de pesos e bias de uma maneira extremamente complicada. Usando “apenas” Cálculo para minimizar isso, não funcionará e precisamos de algo mais! Precisamos de um algoritmo de otimização capaz de minimizar C (v).

Felizmente, há uma analogia que nos ajuda a compreender como encontrar a solução. Começamos por pensar em nossa função como uma espécie de vale e imaginamos uma bola rolando pela encosta do vale, conforme pode ser visto na figura abaixo. Nossa experiência diária nos diz que a bola acabará rolando para o fundo do vale. Talvez possamos usar essa ideia como forma de encontrar um mínimo para a função? Escolheríamos aleatoriamente um ponto de partida para uma bola (imaginária), e então simularíamos o movimento da bola enquanto ela rola até o fundo do vale. Poderíamos fazer essa simulação simplesmente por derivadas de computação da função C – essas derivadas nos diriam tudo o que precisamos saber sobre a “forma” local do vale, e, portanto, como nossa bola deve rolar.

 

Representação da Descida do Gradiente (com o objetivo de minimizar a função de custo)

 

Ou seja, a Descida do Gradiente é um algoritmo de otimização usado para encontrar os valores de parâmetros (coeficientes ou se preferir w e b – weight e bias) de uma função que minimizam uma função de custo. A Descida do Gradiente é melhor usada quando os parâmetros não podem ser calculados analiticamente (por exemplo, usando álgebra linear) e devem ser pesquisados por um algoritmo de otimização.

O procedimento começa com valores iniciais para o coeficiente ou coeficientes da função. Estes poderiam ser 0.0 ou um pequeno valor aleatório (a inicialização dos coeficiente é parte crítica do processo e diversas técnicas podem ser usadas, ficando a escolha a cargo do Engenheiro de IA ou Cientista de Dados e do problema a ser resolvido com o modelo). Poderíamos iniciar assim nossos coeficientes (valores de w e b):

 

coeficiente = 0,0

 

O custo dos coeficientes é avaliado ligando-os à função e calculando o custo.

 

custo = f (coeficiente)

 

ou

 

custo = avaliar (f (coeficiente))

 

A derivada do custo é calculada. A derivada é um conceito de Cálculo e refere-se à inclinação da função em um determinado ponto. Precisamos conhecer a inclinação para que possamos conhecer a direção (sinal) para mover os valores dos coeficientes para obter um custo menor na próxima iteração.

 

delta = derivado (custo)

 

Agora que sabemos da derivada em que direção está em declive, podemos atualizar os valores dos coeficientes. Um parâmetro de taxa de aprendizagem (alfa) deve ser especificado e controla o quanto os coeficientes podem mudar em cada atualização.

 

coeficiente = coeficiente – (alfa * delta)

 

Este processo é repetido até que o custo dos coeficientes (função de custo) seja 0,0 ou próximo o suficiente de zero, indicando que as saídas da rede estão cada vez mais próximas dos valores reais (saídas desejadas).

A Descida do Gradiente é simples, mas exige que seja calculado o gradiente da função de custo ou a função que você está otimizando, mas além disso, é muito direto. Em resumo:

Você divide seus dados em amostras e a cada amostra (sample), você passa as entradas pela rede, multiplica pelos pesos, soma, e no final você vai ter sua saÍda (a previsão da rede). Você então compara a saída da sua rede com o a resposta certa, calcula o erro, e então retroage esse erro (backpropagation), ajustando os pesos de cada neurônio de cada camada. Quando você acabar de fazer a atualização dos pesos, uma nova amostra é introduzida e ela será multiplicada pelos pesos já atualizados. Esse processo de atualizar os pesos é que é chamado de “aprendizado”.

Se você observar os algoritmos mais atuais, todos trabalham dentro de um conceito relativamente novo chamado de mini-lotes (mini-batches). Para otimizar a performance, o que se faz é passar pela rede múltiplas amostras (por exemplo 128 amostras), calcular o erro médio delas e então realizar o backpropagation e a atualização dos pesos. Do ponto de vista da atualização dos pesos, 1 amostra = 128 amostras. Esse é um conceito mais novo, necessário principalmente no treinamento de grandes modelos de Deep Learning.

Em seguida, veremos como podemos usar isso em algoritmos de aprendizado de máquina.

Batch Gradient Descent em Aprendizado de Máquina

O objetivo de todos os algoritmos supervisionados de aprendizagem de máquina é estimar uma função de destino (f) que mapeia dados de entrada (X) para as variáveis ​​de saída (Y). Isso descreve todos os problemas de classificação e regressão (aprendizagem supervisionada).

Alguns algoritmos de aprendizagem de máquina têm coeficientes que caracterizam a estimativa de algoritmos para a função alvo (f). Diferentes algoritmos têm diferentes representações e diferentes coeficientes, mas muitos deles requerem um processo de otimização para encontrar o conjunto de coeficientes que resultam na melhor estimativa da função alvo. Os exemplos comuns de algoritmos com coeficientes que podem ser otimizados usando descida do gradiente são Regressão linear e Regressão logística.

A avaliação de quão próximo um modelo de aprendizagem de máquina estima a função de destino pode ser calculada de várias maneiras, muitas vezes específicas para o algoritmo de aprendizagem de máquina. A função de custo envolve a avaliação dos coeficientes no modelo de aprendizagem de máquina calculando uma previsão para o modelo para cada instância de treinamento no conjunto de dados e comparando as previsões com os valores de saída reais e calculando uma soma ou erro médio (como a Soma de Residuais Quadrados ou SSR no caso de regressão linear).

A partir da função de custo, uma derivada pode ser calculada para cada coeficiente para que ele possa ser atualizado usando exatamente a equação de atualização descrita acima.

O custo é calculado para um algoritmo de aprendizado de máquina em todo o conjunto de dados de treinamento para cada iteração do algoritmo de descida de gradiente. Uma iteração do algoritmo é chamada de um lote e esta forma de descida do gradiente é referida como descida do gradiente em lote (Batch Gradient Descent).

A descida do gradiente em lote é a forma mais comum de descida do gradiente em Machine Learning.

Stochastic Gradient Descent em Aprendizado de Máquina

A Descida do Gradiente pode ser lenta para executar em conjuntos de dados muito grandes. Como uma iteração do algoritmo de descida do gradiente requer uma previsão para cada instância no conjunto de dados de treinamento, pode demorar muito quando você tem muitos milhões de instâncias.

Em situações em que você possui grandes quantidades de dados, você pode usar uma variação da descida do gradiente chamada Stochastic Gradient Descent.

Nesta variação, o procedimento de descida do gradiente descrito acima é executado, mas a atualização para os coeficientes é realizada para cada instância de treinamento, em vez do final do lote de instâncias.

O primeiro passo do procedimento exige que a ordem do conjunto de dados de treinamento seja randomizada. Isto é, misturar a ordem que as atualizações são feitas para os coeficientes. Como os coeficientes são atualizados após cada instância de treinamento, as atualizações serão barulhentas saltando por todo o lado, e assim o custo correspondente funcionará. Ao misturar a ordem para as atualizações dos coeficientes, ela aproveita essa caminhada aleatória e evita que ela fique “distraída” ou presa.

O procedimento de atualização para os coeficientes é o mesmo que o anterior, exceto que o custo não é somado em todos os padrões de treinamento, mas sim calculado para um padrão de treinamento.

A aprendizagem pode ser muito mais rápida com descida de gradiente estocástica para conjuntos de dados de treinamento muito grandes e muitas vezes você só precisa de um pequeno número de passagens através do conjunto de dados para alcançar um conjunto de coeficientes bom o suficiente.

Ufa, você ainda está aí? Entende agora porque Cientistas de Dados e Engenheiros de IA devem ser muito bem remunerados? Eles são os “magos” que estão ajudando a transformar o mundo com Machine Learning. E este capítulo foi apenas uma breve introdução! Voltaremos a este assunto mais a frente no livro, quando estudarmos outros algoritmos.

Tenho certeza que você está ansioso para criar e treinar sua primeira rede neural. Então, não perca o próximo capítulo!

Referências:

MNIST

Derivada

Machine Learning

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

Gradient Descent For Machine Learning

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning

An overview of gradient descent optimization algorithms

Optimization: Stochastic Gradient Descent

Gradient Descent vs Stochastic Gradient Descent vs Mini-Batch Learning

Deep Learning Book

Capítulo 11 – Design De Uma Rede Neural Para Reconhecimento de Dígitos

by

Na primeira parte deste livro online, durante os 10 primeiros capítulos, definimos e estudamos o universo das redes neurais artificias. Neste ponto você já deve ter uma boa compreensão sobre que são estes algoritmos e como podem ser usados, além da importância das redes neurais para a construção de sistemas de Inteligência Artificial. Estamos prontos para iniciar a construção de redes neurais e na sequência estudaremos as arquiteturas mais avançadas. Vamos começar definindo o Design De Uma Rede Neural Para Reconhecimento de Dígitos.

Nossa primeira tarefa será construir uma rede neural para reconhecer caligrafia, ou seja, dígitos escritos à mão que foram digitalizados em imagens no computador. Por que vamos começar com este tipo de tarefa? Porque ela permite percorrer todas as etapas e procedimentos matemáticos de uma rede neural, sendo portanto uma excelente introdução. Vamos começar?

Se você acompanha os cursos na Data Science Academy já sabe que: antes de pensar em escrever sua primeira linha de código, é preciso definir claramente o problema a ser resolvido. A tecnologia existe para resolver problemas e a definição clara do objetivo é o ponto de partida de qualquer projeto de sucesso! Neste capítulo definiremos o problema a ser resolvido, nesse caso o reconhecimento de dígitos manuscritos.

Podemos dividir o problema de reconhecer os dígitos manuscritos em dois sub-problemas. Primeiro, precisamos encontrar uma maneira de quebrar uma imagem que contenha muitos dígitos em uma sequência de imagens separadas, cada uma contendo um único dígito. Por exemplo, gostaríamos de quebrar a imagem:

 

 

em seis imagens separadas:

 

 

Nós, humanos, resolvemos esse problema de segmentação com facilidade, mas é um desafio para um programa de computador dividir corretamente a imagem. Uma vez que a imagem foi segmentada, o programa precisa classificar cada dígito individual. Então, por exemplo, gostaríamos que nosso programa reconhecesse automaticamente que o primeiro dígito acima é um 5:

 

 

Vamos nos concentrar em escrever um programa para resolver o segundo problema, isto é, classificar dígitos individuais. O problema da segmentação não é tão difícil de resolver, uma vez que você tenha uma boa maneira de classificar os dígitos individuais. Existem muitas abordagens para resolver o problema de segmentação. Uma abordagem é testar muitas maneiras diferentes de segmentar a imagem, usando o classificador de dígitos individuais para marcar cada segmentação de teste. Uma segmentação de teste obtém uma pontuação alta se o classificador de dígitos individuais estiver confiante de sua classificação em todos os segmentos e uma pontuação baixa se o classificador tiver muitos problemas em um ou mais segmentos. A ideia é que, se o classificador estiver tendo problemas em algum lugar, provavelmente está tendo problemas porque a segmentação foi escolhida incorretamente. Essa ideia e outras variações podem ser usadas para resolver o problema de segmentação. Então, em vez de se preocupar com a segmentação, nos concentraremos no desenvolvimento de uma rede neural que pode resolver o problema mais interessante e difícil, ou seja, reconhecer dígitos individuais manuscritos.

Para reconhecer dígitos individuais, usaremos uma rede neural de três camadas:

 

 

A camada de entrada da rede contém neurônios que codificam os valores dos pixels de entrada. Conforme iremos discutir no próximo capítulo, nossos dados de treinamento para a rede consistirão em muitas imagens de 28 por 28 pixels de dígitos manuscritos digitalizados e, portanto, a camada de entrada contém 28 × 28 = 784 neurônios (Nota: uma imagem nada mais é do que uma matriz, nesse caso de dimensões 28×28, que iremos converter em um vetor cujo tamanho será 784, onde cada item representa um pixel na imagem). Os pixels de entrada são de escala de cinza, com um valor de 0.0 representando branco e um valor de 1.0 representando preto. Valores intermediários representam tonalidades gradualmente escurecidas de cinza.

A segunda camada da rede é uma camada oculta. Representaremos o número de neurônios nesta camada oculta por n, e vamos experimentar diferentes valores para n. O exemplo mostrado acima ilustra uma pequena camada oculta, contendo apenas n = 15 neurônios.

A camada de saída da rede contém 10 neurônios. Se o primeiro neurônio “disparar” (for ativado), ou seja, tiver uma saída ≈ 1, então isso indicará que a rede acha que o dígito é 0. Se o segundo neurônio “disparar” (for ativado), isso indicará que a rede pensa que o dígito é um 1. E assim por diante. Em resumo, vamos numerar os neurônios de saída de 0 a 9 e descobrimos qual neurônio possui o maior valor de ativação. Se esse neurônio é, digamos, neurônio número 6, então nossa rede adivinhará que o dígito de entrada era um 6. E assim por diante para os outros neurônios de saída.

Você pode se perguntar por que usamos 10 neurônios de saída. Afinal, o objetivo da rede é nos dizer qual dígito (0,1,2, …, 9) corresponde à imagem de entrada. Uma maneira aparentemente natural de fazer isso é usar apenas 4 neurônios de saída, tratando cada neurônio como assumindo um valor binário, dependendo se a saída do neurônio está mais próxima de 0 ou 1. Quatro neurônios são suficientes para codificar a resposta, desde que 2ˆ4 = 16 é mais do que os 10 valores possíveis para o dígito de entrada. Por que nossa rede deve usar 10 neurônios em vez disso? Isso não é ineficiente? A justificativa final é empírica: podemos experimentar ambos os projetos de rede, e verifica-se que, para este problema específico, a rede com 10 neurônios de saída aprende a reconhecer dígitos melhor do que a rede com 4 neurônios de saída. Mas isso ainda deixa a pergunta por que o uso de 10 neurônios de saída funciona melhor. Existe alguma heurística que nos diga com antecedência que devemos usar a codificação de 10 saídas em vez da codificação de 4 saídas?

Entender porque fazemos isso, ajuda a pensar sobre o que a rede neural está realmente fazendo. Considere primeiro o caso em que usamos 10 neurônios de saída. Vamos nos concentrar no primeiro neurônio de saída, aquele que está tentando decidir se o dígito é ou não 0. Ele faz isso pesando evidências da camada oculta dos neurônios. O que esses neurônios ocultos estão fazendo? Bem, vamos supor que o primeiro neurônio na camada oculta detecta ou não uma imagem como a seguinte:

 

 

Isso pode ser feito pesando fortemente pixels de entrada que se sobrepõem à imagem e apenas ponderam ligeiramente as outras entradas. De forma semelhante, suponhamos que o segundo, terceiro e quarto neurônios na camada oculta detectem se as seguintes imagens estão ou não presentes:

 

 

Como você pode ter adivinhado, essas quatro imagens juntas compõem a imagem 0 que vimos na linha de dígitos mostrada anteriormente:

 

 

Então, se todos os quatro neurônios ocultos estão disparando, podemos concluir que o dígito é um 0. Claro, esse não é o único tipo de evidência que podemos usar para concluir que a imagem era um 0 – podemos legitimamente obter um 0 em muitas outras maneiras (por exemplo, através de traduções das imagens acima, ou pequenas distorções). Mas parece seguro dizer que, pelo menos neste caso, concluiríamos que a entrada era um 0.

Supondo que a rede neural funciona assim, podemos dar uma explicação plausível sobre porque é melhor ter 10 saídas da rede, em vez de 4. Se tivéssemos 4 saídas, o primeiro neurônio de saída tentaria decidir o que mais um bit significativo do dígito representa. E não existe uma maneira fácil de relacionar esse bit mais significativo com formas simples, como as mostradas acima. As formas componentes do dígito estarão intimamente relacionadas com (digamos) o bit mais significativo na saída.

Isso tudo é apenas uma heurística. Nada diz que a rede neural de três camadas tem que operar da maneira que descrevemos, com os neurônios ocultos detectando formas de componentes simples. Talvez um algoritmo de aprendizado inteligente encontre alguma atribuição de pesos que nos permita usar apenas 4 neurônios de saída. Mas, usar uma boa heurística pode economizar muito tempo na concepção de boas arquiteturas de redes neurais.

Já temos então um design para a nossa rede neural. Agora precisamos definir como será o processo de aprendizagem do algoritmo, antes de começar a codificar nossa rede em linguagem Python. Usaremos o treinamento com Gradiente Descendente, assunto do próximo capítulo, que aliás eu não perderia por nada, se fosse você, pois aí está a “magia” por trás das redes neurais. Até lá!

Para acompanhar os próximos capítulos e reproduzir os exemplos, você deve ter o Anaconda Python instalado no seu computador. Acesse o capítulo 1 do curso gratuito Fundamentos de Linguagem Python Para Análise de Dados e Data Science, para aprender como instalar o Anaconda.

Referências:

Função Sigmóide

Machine Learning

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

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning (alguns trechos extraídos e traduzidos com autorização do autor Michael Nielsen)

Deep Learning Book

Capítulo 8 – Função de Ativação

by

Neste capítulo estudaremos um importante componente de uma rede neural artificial, a Função de Ativação. Este capítulo é uma introdução ao tema e voltaremos a ele mais adiante quando estudarmos as arquiteturas avançadas de Deep Learning. Este capítulo pode ser um pouco desafiador, pois começaremos a introduzir conceitos mais avançados, que serão muito úteis na sequência dos capítulos. Relaxe, faça a leitura e aprenda um pouco mais sobre redes neurais artificiais.

Antes de mergulhar nos detalhes das funções de ativação, vamos fazer uma pequena revisão do que são redes neurais artificiais e como funcionam. Uma rede neural é um mecanismo de aprendizado de máquina (Machine Learning) muito poderoso que imita basicamente como um cérebro humano aprende. O cérebro recebe o estímulo do mundo exterior, faz o processamento e gera o resultado. À medida que a tarefa se torna complicada, vários neurônios formam uma rede complexa, transmitindo informações entre si. Usando uma rede neural artificial, tentamos imitar um comportamento semelhante. A rede que você vê abaixo é uma rede neural artificial composta de neurônios interligados.

 

Neural Network

 

Os círculos negros na imagem acima são neurônios. Cada neurônio é caracterizado pelo peso, bias e a função de ativação. Os dados de entrada são alimentados na camada de entrada. Os neurônios fazem uma transformação linear na entrada pelos pesos e bias. A transformação não linear é feita pela função de ativação. A informação se move da camada de entrada para as camadas ocultas. As camadas ocultas fazem o processamento e enviam a saída final para a camada de saída. Este é o movimento direto da informação conhecido como propagação direta. Mas e se o resultado gerado estiver longe do valor esperado? Em uma rede neural, atualizaríamos os pesos e bias dos neurônios com base no erro. Este processo é conhecido como backpropagation. Uma vez que todos os dados passaram por este processo, os pesos e bias finais são usados para previsões.

Calma, calma, calma. Muita informação em um único parágrafo, eu sei! Vamos por partes. As entradas, os pesos e bias nós já discutimos nos capítulos anteriores. A função de ativação vamos discutir agora e a propagação direta e o backpropagation discutimos nos próximos capítulos!

Função de Ativação

Os algoritmos de aprendizagem são fantásticos. Mas como podemos elaborar esses algoritmos para uma rede neural artificial? Suponhamos que tenhamos uma rede de Perceptrons que gostaríamos de usar para aprender a resolver algum problema. Por exemplo, as entradas para a rede poderiam ser os dados de pixel de uma imagem digitalizada, escrita à mão, de um dígito. Gostaríamos que a rede aprendesse pesos e bias para que a saída da rede classifique corretamente o dígito. Para ver como a aprendizagem pode funcionar, suponha que façamos uma pequena alteração em algum peso (ou bias) na rede. O que queremos é que esta pequena mudança de peso cause apenas uma pequena alteração correspondente na saída da rede. Como veremos em um momento, esta propriedade tornará possível a aprendizagem. Esquematicamente, aqui está o que queremos (obviamente, esta rede é muito simples para fazer reconhecimento de escrita, mas fique tranquilo que veremos redes bem mais complexas).

 

Esquema

 

Se fosse verdade que uma pequena alteração em um peso (ou bias) fizesse com que tivéssemos apenas uma pequena alteração no resultado, então poderíamos usar esse fato para modificar os pesos e os valores de bias para que a nossa rede se comporte mais da maneira que queremos. Por exemplo, suponha que a rede classificasse equivocadamente uma imagem como “8” quando deveria ser um “9”. Podemos descobrir como fazer uma pequena mudança nos pesos e bias para que a rede fique um pouco mais próxima da classificação da imagem como “9”. E então, repetiríamos isso, mudando os pesos e os valores de bias repetidamente para produzir melhor e melhor resultado. A rede estaria aprendendo.

O problema é que isso não é o que acontece quando nossa rede contém apenas Perceptrons, conforme estudamos nos capítulos anteriores. De fato, uma pequena alteração nos pesos de um único Perceptron na rede pode, por vezes, fazer com que a saída desse Perceptron mude completamente, digamos de 0 a 1. Essa mudança pode então causar o comportamento do resto da rede mudar completamente de uma maneira muito complicada. Então, enquanto o seu “9” pode agora ser classificado corretamente, o comportamento da rede em todas as outras imagens provavelmente mudará completamente de maneira difícil de controlar. Talvez haja uma maneira inteligente de resolver esse problema. Sim, há. E é conhecida como função de ativação.

Podemos superar esse problema através da introdução de um componente matemático em nosso neurônio artificial, chamado função de ativação. As funções de ativação permitem que pequenas mudanças nos pesos e bias causem apenas uma pequena alteração no output. Esse é o fato crucial que permitirá que uma rede de neurônios artificiais aprenda.

Vejamos como isso funciona:

 

Função de Ativação

 

As funções de ativação são um elemento extremamente importante das redes neurais artificiais. Elas basicamente decidem se um neurônio deve ser ativado ou não. Ou seja, se a informação que o neurônio está recebendo é relevante para a informação fornecida ou deve ser ignorada. Veja na fórmula abaixo como a função de ativação é mais uma camada matemática no processamento.

 

Função de Ativação

 

A função de ativação é a transformação não linear que fazemos ao longo do sinal de entrada. Esta saída transformada é então enviada para a próxima camada de neurônios como entrada. Quando não temos a função de ativação, os pesos e bias simplesmente fazem uma transformação linear. Uma equação linear é simples de resolver, mas é limitada na sua capacidade de resolver problemas complexos. Uma rede neural sem função de ativação é essencialmente apenas um modelo de regressão linear. A função de ativação faz a transformação não-linear nos dados de entrada, tornando-o capaz de aprender e executar tarefas mais complexas. Queremos que nossas redes neurais funcionem em tarefas complicadas, como traduções de idiomas (Processamento de Linguagem Natural) e classificações de imagens (Visão Computacional). As transformações lineares nunca seriam capazes de executar tais tarefas.

As funções de ativação tornam possível a propagação posterior desde que os gradientes sejam fornecidos juntamente com o erro para atualizar os pesos e bias. Sem a função não linear diferenciável, isso não seria possível. Caso o termo gradiente não seja familiar, aguarde os próximos capítulos, quando vamos explicar este conceito em detalhes, visto que ele é a essência do processo de aprendizagem em redes neurais artificiais.

Mas não existe apenas um tipo de função de ativação. Na verdade existem vários, cada qual a ser usado em diferentes situações. Vamos a uma breve descrição dos tipos mais populares.

Tipos Populares de Funções de Ativação

A função de ativação é um componente matemático incluído na estrutura de redes neurais artificiais a fim de permitir a solução de problemas complexos. Existem diversos tipos de funções de ativação e esta é uma área de pesquisa ativa, à medida que a Inteligência Artificial evolui (não é maravilhoso estar participando desta evolução, que vai transformar completamente o mundo?). Vejamos quais são os tipos mais populares.

Função de Etapa Binária (Binary Step Function)

A primeira coisa que vem à nossa mente quando temos uma função de ativação seria um classificador baseado em limiar (threshold), ou seja, se o neurônio deve ou não ser ativado. Se o valor Y estiver acima de um valor de limite determinado, ative o neurônio senão deixa desativado. Simples! Essa seria a regra:

f(x) = 1, x>=0

f(x) = 0, x<0

A função de etapa binária é isso mesmo, extremamente simples. Ela pode ser usada ao criar um classificador binário. Quando simplesmente precisamos dizer sim ou não para uma única classe, a função de etapa seria a melhor escolha, pois ativaria o neurônio ou deixaria zero.

A função é mais teórica do que prática, pois, na maioria dos casos, classificamos os dados em várias classes do que apenas uma única classe. A função de etapa não seria capaz de fazer isso.

Além disso, o gradiente da função de etapa é zero. Isso faz com que a função de etapa não seja tão útil durante o backpropagation quando os gradientes das funções de ativação são enviados para cálculos de erro para melhorar e otimizar os resultados. O gradiente da função de etapa reduz tudo para zero e a melhoria dos modelos realmente não acontece. Lembrando, mais uma vez, que veremos em detalhes os conceitos de gradiente e backpropagation mais adiante, nos próximos capítulos!

Função Linear

Nós vimos o problema com a função step, o gradiente sendo zero, é impossível atualizar o gradiente durante a backpropagation. Em vez de uma função de passo simples, podemos tentar usar uma função linear. Podemos definir a função como:

f(x) = ax

A derivada de uma função linear é constante, isto é, não depende do valor de entrada x. Isso significa que toda vez que fazemos backpropagation, o gradiente seria o mesmo. E este é um grande problema, não estamos realmente melhorando o erro, já que o gradiente é praticamente o mesmo. E não apenas suponha que estamos tentando realizar uma tarefa complicada para a qual precisamos de múltiplas camadas em nossa rede. Agora, se cada camada tiver uma transformação linear, não importa quantas camadas nós tenhamos, a saída final não é senão uma transformação linear da entrada. Portanto, a função linear pode ser ideal para tarefas simples, onde a interpretabilidade é altamente desejada.

Sigmóide

Sigmóide é uma função de ativação amplamente utilizada. É da forma:

f (x) = 1 / (1 + e ^ -x)

Esta é uma função suave e é continuamente diferenciável. A maior vantagem sobre a função de etapa e a função linear é que não é linear. Esta é uma característica incrivelmente interessante da função sigmóide. Isto significa essencialmente que quando eu tenho vários neurônios com função sigmóide como função de ativação – a saída também não é linear. A função varia de 0 a 1 tendo um formato S.

A função essencialmente tenta empurrar os valores de Y para os extremos. Esta é uma qualidade muito desejável quando tentamos classificar os valores para uma classe específica.

A função sigmóide ainda é amplamente utilizada até hoje, mas ainda temos problemas que precisamos abordar. Com a sigmóide temos problemas quando os gradientes se tornam muito pequenos. Isso significa que o gradiente está se aproximando de zero e a rede não está realmente aprendendo.

Outro problema que a função sigmóide sofre é que os valores variam apenas de 0 a 1. Esta medida que a função sigmóide não é simétrica em torno da origem e os valores recebidos são todos positivos. Nem sempre desejamos que os valores enviados ao próximo neurônio sejam todos do mesmo sinal. Isso pode ser abordado pela ampliação da função sigmóide. Isso é exatamente o que acontece na função tanh.

Tanh

A função tanh é muito semelhante à função sigmóide. Na verdade, é apenas uma versão escalonada da função sigmóide.

Tanh (x) = 2sigmoides (2x) -1

Pode ser escrito diretamente como:

tanh (x) = 2 / (1 + e ^ (- 2x)) -1

Tanh funciona de forma semelhante à função sigmóide, mas sim simétrico em relação à origem. varia de -1 a 1.

Basicamente, soluciona o nosso problema dos valores, sendo todos do mesmo sinal. Todas as outras propriedades são as mesmas da função sigmoide. É contínuo e diferenciável em todos os pontos. A função não é linear, então podemos fazer o backpropagation facilmente nos erros.

ReLU

A função ReLU é a unidade linear rectificada. É definida como:

f(x) = max (0, x)

ReLU é a função de ativação mais amplamente utilizada ao projetar redes neurais atualmente. Primeiramente, a função ReLU é não linear, o que significa que podemos facilmente copiar os erros para trás e ter várias camadas de neurônios ativados pela função ReLU.

A principal vantagem de usar a função ReLU sobre outras funções de ativação é que ela não ativa todos os neurônios ao mesmo tempo. O que isto significa ? Se você olhar para a função ReLU e a entrada for negativa, ela será convertida em zero e o neurônio não será ativado. Isso significa que, ao mesmo tempo, apenas alguns neurônios são ativados, tornando a rede esparsa e eficiente e fácil para a computação.

Mas ReLU também pode ter problemas com os gradientes que se deslocam em direção a zero. Mas quando temos um problema, sempre podemos pensar em uma solução. Aliás, isso é o que as empresas mais procuram nos dias de hoje: “resolvedores de problemas”. Seja um e sua empregabilidade estará garantida!

Leaky ReLU

A função Leaky ReLU não passa de uma versão melhorada da função ReLU. Na função ReLU, o gradiente é 0 para x < 0, o que fez os neurônios morrerem por ativações nessa região. Leaky ReLU ajuda a resolver este problema. Em vez de definir a função Relu como 0 para x inferior a 0, definimos como um pequeno componente linear de x. Pode ser definido como:

f(x) = ax, x < 0
f(x) = x, x > = 0

O que fizemos aqui é que simplesmente substituímos a linha horizontal por uma linha não-zero, não horizontal. Aqui um é um valor pequeno como 0,01 ou algo parecido. A principal vantagem de substituir a linha horizontal é remover o gradiente zero.

Softmax

A função softmax também é um tipo de função sigmóide, mas é útil quando tentamos lidar com problemas de classificação. A função sigmóide como vimos anteriormente é capaz de lidar com apenas duas classes. O que devemos fazer quando estamos tentando lidar com várias classes? Apenas classificar sim ou não para uma única classe não ajudaria. A função softmax transforma as saídas para cada classe para valores entre 0 e 1 e também divide pela soma das saídas. Isso essencialmente dá a probabilidade de a entrada estar em uma determinada classe. Pode ser definido como:

 

Softmax

 

Digamos, por exemplo, que temos as saídas como [1.2, 0.9, 0.75], quando aplicamos a função softmax, obteríamos [0.42, 0.31, 0.27]. Então, agora podemos usá-los como probabilidades de que o valor seja de cada classe.

A função softmax é idealmente usada na camada de saída do classificador, onde realmente estamos tentando gerar as probabilidades para definir a classe de cada entrada.

Escolhendo a Função de Ativação Correta

Ufa! Muita coisa, não? E ainda não vimos as questões matemáticas envolvidas nessas funções. Mas não tenhamos pressa, não existe atalho para o aprendizado e estudaremos tudo passo a passo, item a item, no padrão dos cursos na Data Science Academy.

Agora que já vimos tantas funções de ativação, precisamos de alguma lógica/heurística para saber qual função de ativação deve ser usada em qual situação. Não há uma regra de ouro e a escolha depende do problema no qual você estiver trabalhando.

No entanto, dependendo das propriedades do problema, poderemos fazer uma melhor escolha para uma convergência fácil e rápida da rede neural.

  • Funções Sigmóide e suas combinações geralmente funcionam melhor no caso de classificadores.
  • Funções Sigmóide e Tanh às vezes são evitadas devido ao problema de Vanishing Gradient (que estudaremos no capítulo sobre redes neurais recorrentes).
  • A função ReLU é uma função de ativação geral e é usada na maioria dos casos atualmente.
  • Se encontrarmos um caso de neurônios deficientes em nossas redes, a função Leaky ReLU é a melhor escolha.
  • Tenha sempre em mente que a função ReLU deve ser usada apenas nas camadas ocultas.
  • Como regra geral, você pode começar usando a função ReLU e depois passar para outras funções de ativação no caso da ReLU não fornecer resultados ótimos.

Está começando a sentir a vibração em trabalhar com Inteligência Artificial? Então continue acompanhando, pois estamos apenas no começo! Até o próximo capítulo!

Referências:

Função Sigmóide

Machine Learning

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

Pattern Recognition and Machine Learning

Understanding Activation Functions in Neural Networks

Vanishing Gradient Problem

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning (alguns trechos extraídos e traduzidos com autorização do autor Michael Nielsen)

Deep Learning Book

Capítulo 7 – O Perceptron – Parte 2

by

O Perceptron é um modelo matemático de um neurônio biológico. Enquanto nos neurônios reais o dendrito recebe sinais elétricos dos axônios de outros neurônios, no Perceptron estes sinais elétricos são representados como valores numéricos. Nas sinapses entre dendritos e axônio, os sinais elétricos são modulados em várias quantidades. Isso também é modelado no Perceptron multiplicando cada valor de entrada por um valor chamado peso. Um neurônio real dispara um sinal de saída somente quando a força total dos sinais de entrada excede um certo limiar. Nós modelamos esse fenômeno em um Perceptron calculando a soma ponderada das entradas para representar a força total dos sinais de entrada e aplicando uma função de ativação na soma para determinar sua saída. Tal como nas redes neurais biológicas, esta saída é alimentada em outros Perceptrons. Estudamos tudo isso no capítulo anterior. Agora vamos continuar nossa discussão sobre o Perceptron compreendendo mais alguns conceitos, que serão fundamentais mais a frente quando estudarmos as arquiteturas avançadas de Deep Learning.

Antes de iniciar, vamos definir dois conceitos que você vai ver com frequência daqui em diante, vetor de entrada e vetor de pesos:

Vetor de entrada –  todos os valores de entrada de cada Perceptron são coletivamente chamados de vetor de entrada desse Perceptron. Esses são seus dados de entrada.

Vetor de pesos – de forma semelhante, todos os valores de peso de cada Perceptron são coletivamente chamados de vetor de peso desse Perceptron. Iniciamos nossa rede neural artificial com valores aleatórios de pesos e durante o treinamento a rede neural aprende os valores de peso ideais. Como veremos, existem muitas formas de realizar esse processo.

Boa parte do trabalho de uma rede neural vai girar em torno das operações algébricas entre o vetor de entrada e o vetor de pesos. Em seguida, vamos adicionando outras camadas matemáticas ou estatísticas para realizar diferentes operações, de acordo com o problema que estamos tentando resolver com o modelo de rede neural. Você vai perceber que tudo não passa de Matemática, que pode ser implementada com linguagens de programação, grandes conjuntos de dados e processamento paralelo, para formar sistemas de Inteligência Artificial.

Mas o que um Perceptron pode fazer afinal?

No capítulo anterior descrevemos os Perceptrons como um método para pesar evidências a fim de tomar decisões. Outra forma em que os Perceptrons podem ser usados é para calcular as funções lógicas elementares tais como AND, OR e NAND (caso tenha dúvidas sobre as operações lógicas, consulte as referências ao final deste capítulo). Por exemplo, suponha que tenhamos um Perceptron com duas entradas, cada uma com peso -2 e um viés de 3. Aqui está o nosso Perceptron:

 

Perceptron

 

Então vemos que a entrada 00 produziria a saída 1, uma vez que (-2) * 0 + (- 2) * 0 + 3 = 3, é positivo (resultado positivo, gera saída 1 do Perceptron, lembra do capítulo anterior?). Aqui, incluímos o símbolo * para tornar as multiplicações explícitas. Cálculos similares mostram que as entradas 01 e 10 produzem a saída 1. Mas a entrada 11 produz a saída 0, uma vez que (-2) * 1 + (- 2) * 1 + 3 = -1, é negativo. E assim nosso Perceptron implementa um “portão” NAND, ou uma operação lógica binária NAND.

O exemplo NAND mostra que podemos usar Perceptrons para calcular funções lógicas simples. Na verdade, podemos usar redes de Perceptrons para calcular qualquer função lógica. A razão é que o portão NAND é universal para computação, ou seja, podemos construir qualquer computação com portões NAND.

Uma rede de Perceptrons pode ser usada para simular um circuito contendo muitos portões NAND. E como os portões NAND são universais para a computação, segue-se que os Perceptrons também são universais para a computação. Considerando que o Perceptron é o modelo mais simples de rede neural, imagine o que pode ser feito com modelos bem mais avançados! Acertou se você pensou em Inteligência Artificial.

A universalidade computacional dos Perceptrons é simultaneamente reconfortante e decepcionante. É reconfortante porque nos diz que redes de Perceptrons podem ser tão poderosas como qualquer outro dispositivo de computação. Mas também é decepcionante, porque parece que os Perceptrons são meramente um novo tipo de portão NAND. Isso não é uma grande noticia!

No entanto, a situação é melhor do que esta visão sugere. Acontece que podemos conceber algoritmos de aprendizado que podem ajustar automaticamente os pesos e os vieses de uma rede de neurônios artificiais. Este ajuste ocorre em resposta a estímulos externos, sem intervenção direta de um programador. Esses algoritmos de aprendizagem nos permitem usar neurônios artificiais de uma maneira que é radicalmente diferente dos portões lógicos convencionais. Em vez de colocar explicitamente um circuito de NAND e outros portões, nossas redes neurais podem simplesmente aprender a resolver problemas, às vezes problemas em que seriam extremamente difíceis de projetar diretamente usando um circuito convencional de lógica.

Operações Lógicas e Regiões Linearmente Separáveis

Conforme mencionado acima, um Perceptron calcula a soma ponderada dos valores de entrada. Por simplicidade, suponhamos que existem dois valores de entrada, x e y para um certo Perceptron P. Vamos definir os pesos de x e y, como sendo A e B, respectivamente. A soma ponderada pode ser representada como: A x + B y.

Uma vez que o Perceptron produz um valor não-zero somente quando a soma ponderada excede um certo limite C, pode-se escrever a saída deste Perceptron da seguinte maneira:

Regra Perceptron

Considerando que A x + B y > C e A x + B y < C são as duas regiões no plano xy separadas pela linha A x + B y + C = 0, e se considerarmos ainda a entrada (x, y) como um ponto em um plano, então o Perceptron realmente nos diz qual região no plano a que esse ponto pertence. Tais regiões, uma vez que são separadas por uma única linha, são chamadas de regiões linearmente separáveis.

Um único Perceptron consegue resolver somente funções linearmente separáveis. Em funções não linearmente separáveis, o Perceptron não consegue gerar um hiperplano, esta linha nos gráficos abaixo, para separar os dados. A questão é que no mundo real raramente os dados são linearmente separáveis, fazendo com o que o Perceptron não seja muito útil para atividades práticas (mas sendo ideal para iniciar o estudo em redes neurais artificiais). E como separamos os dados não linearmente separáveis? Continue acompanhando este livro e você irá descobrir.

Linear e Não-Linear

Mas ainda assim o Perceptron tem sua utilidade, porque resulta em algumas funções lógicas, como os operadores booleanos AND, OR e NOT, que são linearmente separáveis, isto é, eles podem ser realizadas usando um único Perceptron. Podemos ilustrar porque eles são linearmente separáveis ao traçar cada um deles em um gráfico:

 

Funções Lógicas

 

Nos gráficos acima, os dois eixos são as entradas que podem levar o valor de 0 ou 1 e os números no gráfico são a saída esperada para uma entrada específica. Usando um vetor de peso apropriado para cada caso, um único Perceptron pode executar todas essas funções.

No entanto, nem todos os operadores de lógica são linearmente separáveis. Por exemplo, o operador XOR não é linearmente separável e não pode ser alcançado por um único Perceptron. No entanto, esse problema poderia ser superado usando mais de um Perceptron organizado em redes neurais feed-forward, que veremos mais a frente nos próximos capítulos.

 

xor

 

Uma vez que é impossível desenhar uma linha para dividir as regiões contendo 1 ou 0, a função XOR não é linearmente separável, conforme pode ser visto no gráfico acima.

Agora fica mais fácil compreender porque precisamos de arquiteturas mais avançadas de redes neurais artificiais, uma vez que temos problemas complexos no mundo real, como Visão Computacional, Processamento de Linguagem Natural, Tradução, Detecção de Fraudes, Classificação e muitos outros. E veremos essas arquiteturas em detalhes. Mas antes, precisamos falar sobre um componente fundamental das redes neurais, a Função de Ativação. Não perca o próximo capítulo. Até lá.

Referências:

Operação Lógica AND

Operação Lógica OR

Operação Lógica NAND

Operação Lógica XOR

Machine Learning

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

Pattern Recognition and Machine Learning

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning (alguns trechos extraídos e traduzidos com autorização do autor Michael Nielsen)

Deep Learning Book

Capítulo 6 – O Perceptron – Parte 1

by

Você sabe quais são as principais arquiteturas de redes neurais artificias? Não. Então analise cuidadosamente a imagem abaixo (excelente trabalho criado pela equipe do Asimov Institute, cujo link você encontra na seção de referências ao final deste capítulo):

Deep Learning Zoo

Incrível, não? São diversas arquiteturas, usadas para resolver diferentes tipos de problemas, como por exemplo as arquiteturas de redes neurais convolucionais usadas em problemas de Visão Computacional e as redes neurais recorrentes usadas em problemas de Processamento de Linguagem Natural. Estudaremos quase todas essas arquiteturas aqui neste livro. Sim, isso mesmo que você leu. Estamos apenas começando!! Caso queira aprender a construir modelos e projetos usando essas arquiteturas e trabalhando com linguagem Python, PyTorch e TensorFlow, clique aqui.

Embora todas essas arquiteturas sejam de redes neurais artificias, nem todas são de Deep Learning. O que caracteriza modelos de aprendizagem profunda, como o nome sugere, são redes neurais artificias com muitas camadas ocultas (ou intermediárias). Mas antes de chegarmos lá, precisamos passar pela arquitetura mais simples de uma rede neural artificial, o Perceptron. Como diz o ditado: “Toda grande caminhada começa pelo primeiro passo”.

O Modelo Perceptron foi desenvolvido nas décadas de 1950 e 1960 pelo cientista Frank Rosenblatt, inspirado em trabalhos anteriores de Warren McCulloch e Walter Pitts. Hoje, é mais comum usar outros modelos de neurônios artificiais, mas o Perceptron permite uma compreensão clara de como funciona uma rede neural em termos matemáticos, sendo uma excelente introdução.

Então, como funcionam os Perceptrons? Um Perceptron é um modelo matemático que recebe várias entradas, x1, x2, … e produz uma única saída binária:

Perceptron

No exemplo mostrado, o Perceptron possui três entradas: x1, x2, x3. Rosenblatt propôs uma regra simples para calcular a saída. Ele introduziu pesos, w1, w2, …, números reais expressando a importância das respectivas entradas para a saída. A saída do neurônio, 0 ou 1, é determinada pela soma ponderada, Σjwjxj, menor ou maior do que algum valor limiar (threshold). Assim como os pesos, o threshold é um número real que é um parâmetro do neurônio. Para colocá-lo em termos algébricos mais precisos:

Output

Esse é o modelo matemático básico. Uma maneira de pensar sobre o Perceptron é que é um dispositivo que toma decisões ao comprovar evidências. Deixe-me dar um exemplo. Não é um exemplo muito realista, mas é fácil de entender, e logo chegaremos a exemplos mais realistas. Suponha que o fim de semana esteja chegando e você ouviu falar que haverá um festival de queijo em sua cidade. Você gosta de queijo e está tentando decidir se deve ou não ir ao festival. Você pode tomar sua decisão pesando três fatores:

  • O tempo está bom?
  • Seu namorado ou namorada quer acompanhá-lo(a)?
  • O festival está perto de transporte público? (Você não possui um carro)

Podemos representar estes três fatores pelas variáveis binárias correspondentes x1, x2 e x3. Por exemplo, teríamos x1 = 1 se o tempo estiver bom e x1 = 0 se o tempo estiver ruim. Da mesma forma, x2 = 1 se seu namorado ou namorada quiser ir ao festival com você, e x2 = 0, se não. E similarmente para x3 e transporte público.

Agora, suponha que você adore queijo e está disposto a ir ao festival, mesmo que seu namorado ou namorada não esteja interessado e o festival fica em um lugar de difícil acesso e sem transporte público amplamente disponível. Além disso, você realmente detesta mau tempo, e não há como ir ao festival se o tempo estiver ruim. Você pode usar Perceptrons para modelar esse tipo de tomada de decisão.

Uma maneira de fazer isso é escolher um peso w1 = 6 para o tempo e w2 = 2 e w3 = 2 para as outras condições. O valor maior de w1 indica que o tempo é muito importante para você, muito mais do que se seu namorado ou namorada vai acompanhá-lo(a) ou se o festival é próximo do transporte público. Finalmente, suponha que você escolha um threshold de 5 para o Perceptron. Com essas escolhas, o Perceptron implementa o modelo de tomada de decisão desejado, produzindo 1 sempre que o tempo estiver bom e 0 sempre que o tempo estiver ruim. Não faz diferença para o resultado se seu namorado ou namorada quer ir, ou se o transporte público está acessível.

Variando os pesos e o limiar, podemos obter diferentes modelos de tomada de decisão. Por exemplo, suponha que escolhemos um threshold de 3. Então, o Perceptron decidirá que você deveria ir ao festival sempre que o tempo estiver bom ou quando o festival estiver perto do transporte público e seu namorado ou namorada estiver disposto a se juntar a você. Em outras palavras, seria um modelo diferente de tomada de decisão. Reduzir o threshold significa que você está mais propenso a ir ao festival.

Obviamente, o Perceptron não é um modelo completo de tomada de decisão humana! Mas o que o exemplo ilustra é como um Perceptron pode pesar diferentes tipos de evidências para tomar decisões. E deve parecer plausível que uma rede complexa de Perceptrons possa tomar decisões bastante sutis.

Rede

Nesta rede, a primeira coluna de Perceptrons – o que chamaremos de primeira camada de Perceptrons – está tomando três decisões muito simples, pesando a evidência de entrada. E quanto aos Perceptrons na segunda camada? Cada um desses Perceptrons está tomando uma decisão ponderando os resultados da primeira camada de tomada de decisão. Desta forma, um Perceptron na segunda camada pode tomar uma decisão em um nível mais complexo e mais abstrato do que os Perceptrons na primeira camada. E as decisões ainda mais complexas podem ser feitas pelos Perceptrons na terceira camada. Desta forma, uma rede de Perceptrons de várias camadas pode envolver-se em uma tomada de decisão sofisticada.

Aliás, quando definimos os Perceptrons, dissemos que um Perceptron possui apenas uma saída. Na rede acima, os Perceptrons parecem ter múltiplos resultados. Na verdade, eles ainda são de saída única. As setas de saída múltiplas são meramente uma maneira útil de indicar que a saída de um Perceptron está sendo usada como entrada para vários outros Perceptrons.

Vamos simplificar a maneira como descrevemos os Perceptrons. No limite de condição Σjwjxj > threshold podemos fazer duas mudanças de notação para simplificá-lo. A primeira mudança é escrever Σjwjxj como um produto (dot product), w⋅x≡Σjwjxj, onde w e x são vetores cujos componentes são os pesos e entradas, respectivamente. A segunda mudança é mover o threshold para o outro lado da equação e substituí-lo pelo que é conhecido como o viés (bias) do Perceptron, ou b ≡ -threshold. Usando o viés em vez do threshold, a regra Perceptron pode ser reescrita:

Fórmula Perceptron

Você pode pensar no viés como uma medida de quão fácil é obter o Perceptron para produzir um 1. Ou para colocá-lo em termos mais biológicos, o viés é uma medida de quão fácil é fazer com que o Perceptron dispare. Para um Perceptron com um viés realmente grande, é extremamente fácil para o Perceptron emitir um 1. Mas se o viés é muito negativo, então é difícil para o Perceptron emitir um 1. Obviamente, a introdução do viés é apenas uma pequena mudança em como descrevemos Perceptrons, mas veremos mais adiante que isso leva a outras simplificações de notação. Por isso, no restante do livro, não usaremos o threshold, usaremos sempre o viés.

Agora começa a ficar mais fácil compreender o conceito por trás das redes neurais artificiais e isso será muito útil quando estudarmos arquiteturas mais avançadas! Um Perceptron segue o modelo “feed-forward”, o que significa que as entradas são enviadas para o neurônio, processadas e resultam em uma saída. No diagrama abaixo, isso significa que a rede (um neurônio) lê da esquerda para a direita.

Neurônio

O processo de treinamento de um modelo Perceptron consiste em fazer com que o modelo aprenda os valores ideais de pesos e bias. Apresentamos ao modelo os dados de entrada e as possíveis saídas, treinamos o modelo e pesos e bias são aprendidos. Com o modelo treinado, podemos apresentar novos dados de entrada e o modelo será capaz de prever a saída. Veremos isso em breve quando criarmos nosso primeiro modelo usando linguagem Python.

Perceptron é uma rede neural de camada única e um Perceptron de várias camadas é chamado de Rede Neural Artificial. O Perceptron é um classificador linear (binário). Além disso, é usado na aprendizagem supervisionada e pode ser usado para classificar os dados de entrada fornecidos.

Mas o Perceptron tem ainda outras características importantes, como a representação de condicionais lógicos (and, or, xor), problemas com dados não linearmente separáveis e as funções de ativação. Mas esses são temas para o próximo capítulo. Até lá!

Referências:

Formação Engenheiro de IA

The Neural Network Zoo

Machine Learning

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

Pattern Recognition and Machine Learning

Redes Neurais, princípios e práticas

Neural Networks and Deep Learning (alguns trechos extraídos e traduzidos com autorização do autor Michael Nielsen)

Deep Learning Book

Capítulo 4 – O Neurônio, Biológico e Matemático

by

Para compreender a lógica de funcionamento das redes neurais, alguns conceitos básicos referentes ao funcionamento do cérebro humano e seus componentes, os neurônios, são de fundamental importância. A formação das conexões entre as células e algumas considerações sobre como se concebe teoricamente o funcionamento matemático, ajudam a entender as bases da aprendizagem de máquina e das redes neurais. Vejamos como funciona o neurônio biológico deixando Machine Learning de lado por um instante!

O Neurônio Biológico

O neurônio é a unidade básica do cérebro humano, sendo uma célula especializada na transmissão de informações, pois nelas estão introduzidas propriedades de excitabilidade e condução de mensagens nervosas. O neurônio é constituído por 3 partes principais: a soma ou corpo celular, do qual emanam algumas ramificações denominadas de dendritos, e por uma outra ramificação descendente da soma, porém mais extensa, chamada de axônio. Nas extremidades dos axônios estão os nervos terminais, pelos quais é realizada a transmissão das informações para outros neurônios. Esta transmissão é conhecida como sinapse.

 

Neurônio Biológico

Fig7 – Representação Simplificada do Neurônio Biológico

Nosso cérebro é formado por bilhões de neurônios. Mas eles não estão isolados. Pelo contrário, existem centenas de bilhões de conexões entre eles, formando uma enorme rede de comunicação, a rede neural. Cada neurônio possui um corpo central, diversos dendritos e um axônio. Os dendritos recebem sinais elétricos de outros neurônios através das sinapses, que constitui o processo de comunicação entre neurônios. O corpo celular processa a informação e envia para outro neurônio.

Observe que a soma e os dendritos formam a superfície de entrada do neurônio e o axônio a superfície de saída do fluxo de informação (esse fluxo de informação é importante para compreender o neurônio matemático daqui a pouco). A informação transmitida pelos neurônios na realidade são impulsos elétricos. O impulso elétrico é a mensagem que os neurônios transmitem uns aos outros, ou seja, é a propagação de um estímulo ao longo dos neurônios que pode ser qualquer sinal captado pelos receptores nervosos.

Os dendritos têm como função, receber informações, ou impulsos nervosos, oriundos de outros neurônios e conduzi-los até o corpo celular. Ali, a informação é processada e novos impulsos são gerados. Estes impulsos são transmitidos a outros neurônios, passando pelo axônio e atingindo os dendritos dos neurônios seguintes. O corpo do neurônio é responsável por coletar e combinar informações vindas de outros neurônios.

O ponto de contato entre a terminação axônica de um neurônio e o dendrito de outro é chamado sinapse. É pelas sinapses que os neurônios se unem funcionalmente, formando as redes neurais. As sinapses funcionam como válvulas, sendo capazes de controlar a transmissão de impulsos, isto é, o fluxo da informação entre os neurônios na rede neural. O efeito das sinapses é variável e é esta variação que dá ao neurônio capacidade de adaptação.

Sinais elétricos gerados nos sensores (retina ocular, papilas gustativas, etc…) caminham pelos axônios. Se esses sinais forem superiores a um limiar de disparo (threshold), seguem pelo axônio. Caso contrário, são bloqueados e não prosseguem (são considerados irrelevantes). A passagem desses sinais não é elétrica, mas química (através da substância serotonina). Se o sinal for superior a certo limite (threshold), vai em frente; caso contrário é bloqueado e não segue. Estamos falando aqui do neurônio biológico e preste bastante atenção a palavra threshold, pois ela é a essência do neurônio matemático.

Um neurônio recebe sinais através de inúmeros dendritos, os quais são ponderados e enviados para o axônio, podendo ou não seguir adiante (threshold). Na passagem por um neurônio, um sinal pode ser amplificado ou atenuado, dependendo do dendrito de origem, pois a cada condutor, está associado um peso pelo qual o sinal é multiplicado. Os pesos são o que chamamos de memória.

Cada região do cérebro é especializada em uma dada função, como processamento de sinais auditivos, sonoros, elaboração de pensamentos, desejos, etc… Esse processamento se dá através de redes particulares interligadas entre si, realizando processamento paralelo. Cada região do cérebro possui uma arquitetura de rede diferente: varia o número de neurônios, de sinapses por neurônio, valor dos thresholds e dos pesos, etc…Os valores dos pesos são estabelecidos por meio de treinamento recebido pelo cérebro durante a vida útil. É a memorização.

Inspirados no neurônio biológico, os pesquisadores desenvolveram um modelo de neurônio matemático que se tornou a base da Inteligência Artificial. A ideia era simples: “Se redes neurais formam a inteligência humana, vamos reproduzir isso e criar Inteligência Artificial”. E assim nasceu o neurônio matemático, o qual descrevemos abaixo.

O Neurônio Matemático

A partir da estrutura e funcionamento do neurônio biológico, pesquisadores tentaram simular este sistema em computador. O modelo mais bem aceito foi proposto por Warren McCulloch e Walter Pitts em 1943, o qual implementa de maneira simplificada os componentes e o funcionamento de um neurônio biológico. Em termos simples, um neurônio matemático de uma rede neural artificial é um componente que calcula a soma ponderada de vários inputs, aplica uma função e passa o resultado adiante.

Neste modelo de neurônio matemático, os impulsos elétricos provenientes de outros neurônios são representados pelos chamados sinais de entrada (a letra x nesse diagrama abaixo, que nada mais são do que os dados que alimentam seu modelo de rede neural artificial). Dentre os vários estímulos recebidos, alguns excitarão mais e outros menos o neurônio receptor e essa medida de quão excitatório é o estímulo é representada no modelo de Warren McCulloch e Walter Pitts através dos pesos sinápticos. Quanto maior o valor do peso, mais excitatório é o estímulo. Os pesos sinápticos são representados por wkn neste diagrama abaixo, onde k representa o índice do neurônio em questão e n se refere ao terminal de entrada da sinapse a qual o peso sináptico se refere.

A soma ou corpo da célula é representada por uma composição de dois módulos, o primeiro é uma junção aditiva, somatório dos estímulos (sinais de entrada) multiplicado pelo seu fator excitatório (pesos sinápticos), e posteriormente uma função de ativação, que definirá com base nas entradas e pesos sinápticos, qual será a saída do neurônio. O axônio é aqui representado pela saída (yk) obtida pela aplicação da função de ativação. Assim como no modelo biológico, o estímulo pode ser excitatório ou inibitório, representado pelo peso sináptico positivo ou negativo respectivamente.

Neurônio Matemático

Fig8 – Representação Simplificada do Neurônio Matemático

O modelo proposto possui uma natureza binária. Tanto os sinais de entrada quanto a saída, são valores binários. McCulloch acreditava que o funcionamento do sistema nervoso central possuía um carater binário, ou seja, um neurônio infuencia ou não outro neurônio, mas posteriormente mostrou-se que não era dessa forma.

O neurônio matemático é um modelo simplificado do neurônio biológico. Tais modelos inspirados a partir da análise da geração e propagação de impulsos elétricos pela membrana celular dos neurônios. O neurônio matemático recebe um ou mais sinais de entrada e devolve um único sinal de saída, que pode ser distribuído como sinal de saída da rede, ou como sinal de entrada para um ou vários outros neurônios da camada posterior (que formam a rede neural artificial). Os dendritos e axônios são representados matematicamente apenas pelas sinapses, e a intensidade da ligação é representada por uma grandeza denominada peso sináptico, simbolizada pela letra w. Quando as entradas, x são apresentadas ao neurônio, elas são multiplicadas pelos pesos sinápticos correspondentes, gerando as entradas ponderadas, ou seja, x1 que multiplica w1, etc… Isso descreve uma das bases matemáticas do funcionamento de uma rede neural artificial, a multiplicação de matrizes:

Matriz

Fig9 – Multiplicação de Matrizes Entre Sinais de Entrada x e Pesos Sinápticos w (versão simplificada)

O neurônio então totaliza todos os produtos gerando um único resultado. A esta função se denomina função de combinação. Este valor é então apresentado a uma função de ativação ou função de transferência, que tem, dentre outras, a finalidade de evitar o acréscimo progressivo dos valores de saída ao longo das camadas da rede, visto que tais funções possuem valores máximos e mínimos contidos em intervalos determinados. O uso de funções de transferência não-lineares torna a rede neural uma ferramenta poderosa. Sabe-se que uma rede perceptron de duas camadas com função de transferência não-linear como a função sigmóide (que veremos mais adiante), é denominada de aproximador universal.

Um neurônio dispara quando a soma dos impulsos que ele recebe ultrapassa o seu limiar de excitação chamado de threshold. O corpo do neurônio, por sua vez, é emulado por um mecanismo simples que faz a soma dos valores xi e wi recebidos pelo neurônio (soma ponderada) e decide se o neurônio deve ou não disparar (saída igual a 1 ou a 0) comparando a soma obtida ao limiar ou threshold do neurônio. A ativação do neurônio é obtida através da aplicação de uma “função de ativação”, que ativa a saída ou não, dependendo do valor da soma ponderada das suas entradas.

Note que este modelo matemático simplificado de um neurônio é estático, ou seja, não considera a dinâmica do neurônio natural. No neurônio biológico, os sinais são enviados em pulsos e alguns componentes dos neurônios biológicos, a exemplo do axônio, funcionam como filtros de frequência.

O modelo do neurônio matemático também pode incluir uma polarização ou bias de entrada. Esta variável é incluída ao somatório da função de ativação, com o intuito de aumentar o grau de liberdade desta função e, consequentemente, a capacidade de aproximação da rede. O valor do bias é ajustado da mesma forma que os pesos sinápticos. O bias possibilita que um neurônio apresente saída não nula ainda que todas as suas entradas sejam nulas. Por exemplo, caso não houvesse o bias e todas as entradas de um neurônio fossem nulas, então o valor da função de ativação seria nulo. Desta forma não poderíamos, por exemplo, fazer com o que o neurônio aprendesse a relação pertinente ao ”ou exclusivo” da lógica. Em resumo, temos esses componentes em um neurônio matemático:

Resumo do Neurônio

Fig10 – Representação do Neurônio Matemático

  • Sinais de entrada { X1, X2, …, Xn }: São os sinais externos normalmente normalizados para incrementar a eficiência computacional dos algoritmos de aprendizagem. São os dados que alimentam seu modelo preditivo.
  • Pesos sinápticos { W1, W2, …, Wn }: São valores para ponderar os sinais de cada entrada da rede. Esses valores são aprendidos durante o treinamento.
  • Combinador linear { Σ }: Agregar todos sinais de entrada que foram ponderados pelos respectivos pesos sinápticos a fim de produzir um potencial de ativação.
  • Limiar de ativação { Θ }: Especifica qual será o patamar apropriado para que o resultado produzido pelo combinador linear possa gerar um valor de disparo de ativação.
  • Potencial de ativação { u }: É o resultado obtido pela diferença do valor produzido entre o combinador linear e o limiar de ativação. Se o valor for positivo, ou seja, se u ≥ 0 então o neurônio produz um potencial excitatório; caso contrário, o potencial será inibitório.
  • Função de ativação { g }: Seu objetivo é limitar a saída de um neurônio em um intervalo valores.
  • Sinal de saída { y}: É o valor final de saída podendo ser usado como entrada de outros neurônios que estão sequencialmente interligados.

Os modelos baseados em redes neurais artificiais são os que mais ganharam atenção nos últimos anos por conseguirem resolver problemas de IA nos quais se conseguia pouco avanço com outras técnicas. A partir da concepção do neurônio matemático, várias arquiteturas e modelos com diferentes combinações entre esses neurônios, e aplicando diferentes técnicas matemáticas e estatísticas, surgiram e propiciaram a criação de arquiteturas avançadas de Deep Learning como Redes Neurais Convolucionais, Redes Neurais Recorrentes, Auto Encoders, Generative Adversarial Networks, Memory Networks, entre outras, que estudaremos ao longo deste livro online.

Referências:

Anatomia de um Neurônio

Bibliografia Machine Learning e IA

Deep Learning in Neural Networks: An Overview

Grokking Deep Learning

HAYKIN, S. Redes Neurais, princípios e práticas. Porto Alegre: Bookman, 2001.

JAIN, A. K, MAO, J., MOHIUDDIN, K.M. Artificial neural networks: a tutorial. IEEE Computer, v. 29, n. 3, p. 56-63, 1996.

 

Deep Learning Book

Capítulo 1 – Deep Learning e a Tempestade Perfeita

by

O interesse pela Aprendizagem de Máquina (Machine Learning) explodiu na última década. O mundo a nossa volta está passando por uma transformação e vemos uma interação cada vez maior das aplicações de computador com os seres humanos. Softwares de detecção de spam, sistemas de recomendação, marcação em fotos de redes sociais, assistentes pessoais ativados por voz, carros autônomos, smartphones com reconhecimento facial e muito mais.

E o interesse por Machine Learning se mostra ainda mais evidente pelo número cada vez maior de conferências, meetups, artigos, livros, cursos, buscas no Google e profissionais e empresas procurando compreender o que é e como usar aprendizagem de máquina, embora muitos ainda confundem o que podem fazer com o que desejam fazer. Não há como ficar indiferente a esta revolução trazida pela aprendizagem de máquina e, segundo o Gartner, até 2020 todos os softwares corporativos terão alguma funcionalidade ligada a Machine Learning.

Fundamentalmente, Machine Learning é a utilização de algoritmos para extrair informações de dados brutos e representá-los através de algum tipo de modelo matemático. Usamos então este modelo para fazer inferências a partir de outros conjuntos de dados. Existem muitos algoritmos que permitem fazer isso, mas um tipo em especial vem se destacando, as redes neurais artificiais.

As redes neurais artificiais não são necessariamente novas, existem pelo menos desde a década de 1950. Mas durante várias décadas, embora a arquitetura desses modelos tivesse evoluído, ainda faltavam ingredientes que fizessem os modelos realmente funcionar. E esses ingredientes surgiram quase ao mesmo tempo. Um deles você já deve ter ouvido: Big Data. O volume de dados, gerado em variedade e velocidade cada vez maiores, permite criar modelos e atingir altos níveis de precisão. Mas ainda falta um ingrediente. Faltava! Como processar grandes modelos de Machine Learning com grandes quantidades de dados? As CPUs não conseguiam dar conta do recado.

Foi quando os gamers e sua avidez por poder computacional e gráficos perfeitos, nos ajudaram a encontrar o segundo ingrediente: Programação Paralela em GPUs. As unidades de processamento gráfico, que permitem realizar operações matemáticas de forma paralela, principalmente operações com matrizes e vetores, elementos presentes em modelos de redes neurais artificias, formaram a tempestade perfeita, que permitiu a evolução na qual nos encontramos hoje: Big Data + Processamento Paralelo + Modelos de Aprendizagem de Máquina = Inteligência Artificial.

A unidade fundamental de uma rede neural artificial é um nó (ou neurônio matemático), que por sua vez é baseado no neurônio biológico. As conexões entre esses neurônios matemáticos também foram inspiradas em cérebros biológicos, especialmente na forma como essas conexões se desenvolvem ao longo do tempo com “treinamento”. Em meados da década de 1980 e início da década de 1990, muitos avanços importantes na arquitetura das redes neurais artificias ocorreram. No entanto, a quantidade de tempo e dados necessários para obter bons resultados retardou a adoção e, portanto, o interesse foi arrefecido, com o que ficou conhecimento como AI Winter (Inverno da IA).

No início dos anos 2000, o poder computacional expandiu exponencialmente e o mercado viu uma “explosão” de técnicas computacionais que não eram possíveis antes disso. Foi quando o aprendizado profundo (Deep Learning) emergiu do crescimento computacional explosivo dessa década como o principal mecanismo de construção de sistemas de Inteligência Artificial, ganhando muitas competições importantes de aprendizagem de máquina. O interesse por Deep Learning não para de crescer e hoje vemos o termo aprendizado profundo sendo mencionado com frequência cada vez maior e soluções comerciais surgindo a todo momento.

Este livro online, gratuito e em português, é uma iniciativa da Data Science Academy para ajudar aqueles que buscam conhecimento avançado e de qualidade em nosso idioma. Serão 100 capítulos, publicados no formato de posts. Desta forma, esperamos contribuir para o crescimento do Deep Learning e Inteligência Artificial no Brasil.

Nos acompanhe nesta incrível jornada!

Equipe DSA

www.datascienceacademy.com.br

 

Deep Learning Book

Capítulo 100 – Machine Learning – Guia Definitivo – Parte 10

by

Chegamos ao final do Deep Learning Book. Este é o centésimo e último capítulo deste livro online, em português, gratuito e agora com 100 capítulos!

Antes de mais nada nós da DSA gostaríamos de agradecer a você que acompanhou todo este trabalho realizado até aqui.

O Deep Learning Book nasceu do nosso inconformismo em ver pouco conhecimento sendo gerado em português sobre uma das tecnologias mais revolucionárias da história humana, a Inteligência Artificial. Este livro online, bem como os cursos gratuitos que oferecemos em nosso portal, fazem parte da nossa contribuição para ajudar a disseminar o conhecimento e a educação, tão importantes para a evolução do país.

Hoje o Deep Learning Book é uma referência em língua portuguesa, sendo usado aliás como referência em trabalhos de Mestrado e Doutorado, trabalhos de conclusão de curso de Graduação e Pós-Graduação e desde que foi lançado recebe um volume cada vez maior de acessos. Nosso objetivo vem sendo alcançado e estamos ajudando pessoas interessadas em aprender Inteligência Artificial. 

Para concluir este trabalho, vamos fazer uma revisão do processo de aprendizado de máquina com as 10 últimas regras do Guia Definitivo de Machine Learning.

E ao final do capítulo teremos uma surpresa para você.

Boa leitura.


Inteligência Artificial já está presente em nossas vidas. Observe a sua volta. Aplicações de filtro de spam, sistemas de reconhecimento facial no celular, chatbots de atendimento ao cliente, sistemas de recomendação e muito, muito mais.

Pelo menos desde a década de 50 que cientistas ao redor do mundo estão tentando reproduzir nas máquinas o que considera-se como inteligência, reproduzindo especialmente o sistema de aprendizado do cérebro humano.

Mas foi a partir do surgimento do Big Data, e em especial do processamento paralelo em GPUs, pouco mais de uma década atrás, que a Inteligência Artificial cresceu de forma exponencial, permitindo a criação de aplicações maravilhosas em áreas como Visão Computacional e Processamento de Linguagem Natural, notadamente as tarefas mais complexas de reproduzir em computadores.

E uma sub-área da IA, Machine Learning, teve os avanços mais incríveis, quando uma arquitetura em especial, Deep Learning, conseguiu obter resultados do estado da arte.

Mas se você acompanhou este livro com atenção deve ter percebido que muito do que fazemos em IA se resume a Matemática com programação de computadores, através do treinamento com muitos, muitos dados. Aplicando as mais diversas técnicas matemáticas e estatísticas, preparamos os dados, treinamos algoritmos via programação e modelos são criados para os mais devidos fins, resolvendo problemas de negócio, ajudando tomadores de decisão ou alimentando aplicações. E muito ainda está por vir, à medida que as empresas percebem os benefícios de aplicações baseadas em IA.

Aqui estão as 10 regras finais do Guia Definitivo de Machine Learning.

Regra 41: Precisamos de Dados

Você pode pensar: “Espere, isso é óbvio”. Você ficaria surpreso com a quantidade de pessoas que não compreendem que IA, Machine Learning ou Deep Learning não existem sem dados. Precisamos de dados históricos para que, através de algoritmos, possamos detectar padrões e então o modelo realizar suas previsões ou tarefa final.

Para compreender bem isso, basta fazer uma analogia com o aprendizado de uma criança. Como uma criança aprende a falar? Ouvindo sua família falar o tempo todo (a voz representa os dados nesse caso). Como uma criança aprende a escrever? Quando alguém a ensina através de exercícios (que nesse caso representam os dados). Ou seja, uma criança aprende à medida que é exposta a dados, que são processados através dos sentidos e criam no cérebro a memória que será usada pela criança durante toda a sua vida.

Se a sua empresa ainda não está cuidando dos dados com o devido valor, ela já está bem atrasada. Os dados são agora um ativo corporativo mais importante do que nunca e que permite o uso e benefícios de Inteligência Artificial.

Isso explica por que a engenharia de dados também cresceu muito nos últimos anos, uma vez que precisamos de mecanismos, sistemas e ferramentas para coletar, armazenar e processar os dados.

Regra 42: Os Dados Raramente Estarão Prontos Para Uso

E por isso a etapa de limpeza e pré-processamentos dados ainda é parte crucial do trabalho. São várias técnicas que devem ser usadas de acordo com o conjunto de dados.

Raramente os dados estarão no formato ideal para o processo de análise ou construção dos modelos. A criação de pipelines de dados é o que permite passar os dados por uma “linha de produção”, para que os dados cheguem ao seu destino em condições de serem usados. Para compreender isso faça uma analogia: O petróleo bruto poderia ser usado como combustível em um automóvel? Não. Logo, o petróleo passa a ser valioso quando é processado e gera como produto final o combustível que, aí sim, ajudará a resolver diversos problemas (embora também crie outros). Com os dados a ideia é a mesma.

Regra 43: Não Há Arquitetura Ideal em Machine Learning

Machine Learning está distante da perfeição. Cada arquitetura tem pontos fortes e fracos e nosso trabalho não é buscar perfeição e sim encontrar a melhor solução possível, uma aproximação, que será suficiente para resolver determinado problema de negócio.

Não desperdice seu tempo buscando o modelo perfeito. Mantenha o foco na solução do problema e tente encontrar o modelo que oferece a melhor aproximação com o menor esforço.

Regra 44: Machine Learning Não é Aplicação Pronta

Um equívoco muito comum cometido por iniciantes é achar que Machine Learning é uma aplicação pronta, linda e maravilhosa, que pode ser usada imediatamente. Não. Machine Learning cria um modelo e ainda precisamos dar um passo adiante e decidir como usar esse modelo.

O modelo pode ser usado via linha de comando em nossas máquinas, pode ser integrado em uma aplicação web, uma aplicação para smartphone, podemos criar uma API usando um serviço em nuvem. As opções são inúmeras, mas Machine Learning concentra o conhecimento para criação do modelo e não criação da uma aplicação completa.

Regra 45: Use Transfer Learning Sempre Que Possível

Quando seu conjunto de dados consiste em dados não estruturados, como imagens, texto ou áudio, é recomendável pegar carona em modelos pré-treinados existentes.

Para ajustar um classificador de imagens, você pode precisar de apenas 10 exemplos por classe, por exemplo. Frameworks como TensorFlow e PyTorch oferecem uma variedade de modelos pré-treinados. Você não precisa reinventar a roda ou gastar horas ou mesmo dias para treinar um modelo a partir do zero. Aprenda a trabalhar com Transfer Learning e mantenha o foco no seu objetivo. Seu objetivo não é criar modelos e sim resolver problemas de negócio. Aprenda a usar Transfer Learning.

Regra 46: Generalização Através de Regularização

Ao criar um modelo de Machine Learning queremos que ele seja generalizável, ou seja, depois de aprender com dados de treino o modelo deve ser capaz de fazer previsões ou extrair padrões em novos conjuntos de dados. Generalização significa que o modelo não deve aprender os detalhes dos dados de treino, mas sim a relação matemática geral nos dados.

Uma maneira de ajudar seu modelo a generalizar além do conjunto de treinamento é colocar penalidades no tamanho dos pesos w do seu modelo. Isso se chama regularização. Duas penalidades populares são a norma de Manhattan (ou norma L₁) e a norma euclidiana “padrão” (ou norma L₂).

Ao regularizar, verifique se todos os recursos são dimensionados para ordenar a unidade (sem dimensão) por padronização. Isso garante que a penalidade afete todos os pesos igualmente. As estimativas de Ball Park podem ser obtidas estudando dois casos de regressão linear que podem ser resolvidos de forma fechada, a saber, Regressão Lasso (isto é, L₁ regularização λ₁|w|₁ de pesos w) e Regressão de Ridge (L₂ regularização λ₂|w|²₂ de pesos W). Quando os recursos são centrados e não correlacionados, suas soluções podem ser expressas em termos da solução não penalizada.

A Regularização LASSO corta (ou trunca) todos os coeficientes não penalizados abaixo de λ₁. Um ponto de partida razoável pode, portanto, ser λ₁ = 0,1.

A Regularização Ridge, por outro lado, apenas diminui o tamanho para zero. Para escolher λ₂, você pode querer levar em consideração até que ponto seu sistema está sobreajustado (overfitting).

Uma nota de advertência: O Scikit-Learn usa convenções ligeiramente diferentes para os objetivos em Ridge e Lasso.

Regra 47: Qual o Volume de Dados Ideal Para Treinar Modelos de Machine Learning?

Não existe regra mágica, mas a figura abaixo apresenta um ponto de partida:

formula

Número de amostras (m), recursos (n) e parâmetros de modelo (d) formam a santíssima trindade do aprendizado de máquina. A maioria das regras de ouro pode ser amplamente trazida de volta a esta tríade.

Regra 48: Quantas Amostras Para Treinar Modelos de Machine Learning?

O desempenho normalmente escala como log m, onde m é o número de amostras e geralmente é limitado pelo ruído nos rótulos. Portanto, quando os dados de treinamento são rotulados por humanos, esse limite geralmente corresponde ao desempenho de nível humano. Logo, pode ser útil focar na qualidade dos dados, em vez da quantidade, conforme sugerido pelo movimento de IA centrada em dados.

Em geral, mais amostras são necessárias para problemas de regressão do que para problemas de classificação. 

Regra 49: Quantos Parâmetros?

Lembre-se de sua aula de álgebra linear lá no ensino médio, que para resolver um sistema linear com d graus de liberdade, você precisa de d restrições. Para regressão linear, cada amostra é uma restrição.

Portanto, para fixar os parâmetros d, você precisa de pelo menos tantas amostras — caso contrário, seu sistema é considerado subdeterminado. De forma mais geral, ao interpretar os parâmetros de um modelo como graus de liberdade, uma heurística comum é um sistema dez vezes sobredeterminado:

d ≤ m/10 

embora limites mais conservadores para redes neurais, como d ≤ m/50, também sejam sugeridos. Por sua vez, ter determinado o número de parâmetros, d, pode ajudá-lo a decidir se o número de recursos, n, precisa ser reduzido.

No entanto, é necessário cautela porque para muitos modelos, por exemplo, modelos probabilísticos, o número de restrições pode ser O(n) e independente do tamanho da amostra m.

Regra 50: Não Termina Aqui. Isso Foi Só o Começo

Existem 3 fases do aprendizado:

  • Fase 1 – Você não sabe o que não sabe.
  • Fase 2 – Você sabe o que não sabe.
  • Fase 3 – Você sabe o que sabe.

Ao finalizar a leitura deste livro esperamos que você tenha passado da Fase 1 para a Fase 2, quando o assunto é aprendizado de máquina.

Há muito ainda para aprender sobre Inteligência Artificial e este livro foi apenas o começo!

Sucesso na sua jornada!


E agora sua surpresa.

Para ajudar na sua capacitação estamos lançando a mais nova Formação DSA:

Formação Engenheiro de Inteligência Artificial

Um programa que traz para você as mais modernas técnicas de IA através de uma série de laboratórios práticos e projetos realmente incríveis em diferentes áreas de negócio.

Veja abaixo a sequência e descrição dos 6 cursos da Formação Engenheiro de IA:

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

Este é o ponto de partida da Formação. Aqui você aprenderá como construir modelos de Deep Learning, as principais arquiteturas, como pré-processar os dados, como otimizar os modelos e como realizar o deploy. Os frameworks PyTorch e Pytorch Lightning serão usados em Linguagem Python.

Este é um curso completo de Deep Learning, hoje a principal técnica de Inteligência Artificial, com o framework de maior sucesso da atualidade, o PyTorch. E vamos trazer também para você o Lightning, biblioteca que simplifica a forma como criamos modelos com o PyTorch aumentando a produtividade na construção dos modelos e a performance das aplicações de Inteligência Artificial.

Depois de mais de 5 anos capacitando milhares de alunos em Deep Learning através de diversos outros treinamentos, neste novo curso oferecido pela DSA você vai desenvolver suas habilidades em IA com o estado da arte em Deep Learning através de Estudos de Caso, Labs, Mini-Projetos e Projetos. 

2- Análise de Imagens com Inteligência Artificial

Aqui é onde a diversão começa. Você vai trabalhar com uma das principais áreas da Inteligência Artificial, a Visão Computacional. Através de labs e projetos de diferentes áreas, você aprenderá como construir modelos de IA capazes de detectar, classificar e segmentar imagens dos mais variados tipos.

Este curso traz para você modernas técnicas de Visão Computacional para análise de todo tipo de imagem, como imagens médicas, imagens de satélite, imagens de plantações agrícolas, imagens de objetos, imagens de pessoas para reconhecimento facial e você ainda vai aprender como criar seu próprio dataset de imagens customizado e como detectar Deep Fakes.

Visão Computacional é atualmente uma das principais áreas da Inteligência Artificial. Um conjunto de técnicas para carregar, manipular, tratar, processar, detectar, prever, segmentar e analisar imagens. E neste curso, de alto nível, vamos trazer as principais técnicas e ferramentas para você, incluindo Vision Transformers.

O curso é inteiramente orientado a projetos. Isso significa que a cada capítulo você vai trabalhar em um problema do mundo real com dados reais (disponíveis publicamente) e então vai desenvolver suas habilidades através de aulas teóricas que exploram os principais conceitos e aulas práticas que implementam a solução. E em um dos capítulos vamos ensinar como você cria seu próprio dataset de imagens customizado.

3- Processamento de Linguagem Natural com Transformers

O terceiro curso da Formação é sobre a área mais complexa da Inteligência Artificial. Pelo menos até o surgimento dos modelos Transformers, que estão revolucionando a forma como ensinamos o computador a fazer traduções de texto, reconhecer a voz humana ou classificar textos e mensagens por tópicos

Você deseja aplicar o Processamento de Linguagem Natural (PLN), com as mais modernas técnicas de IA, para resolver diferentes problemas nas áreas de Direito, Atendimento ao Cliente, Reconhecimento de Voz, Análise de Sentimento, Classificação de Texto e Detecção de Fake News? Então este curso é para você.

Este não é apenas um curso de PLN. Este curso traz para você o estado da arte em Inteligência Artificial com Transformers e aplicações práticas em diversas áreas com projetos completos, incluindo a Dorothy, o Bot Transformer que você irá construir para automatizar o atendimento ao cliente. Imperdível.

4- Análise e Previsão de Séries Temporais com Inteligência Artificial

No quarto curso da Formação você vai aplicar Inteligência Artificial em problemas de negócio que requerem análise ao longo do tempo. Os principais métodos clássicos para análise de séries temporais, também serão abordados no começo do curso.

A análise de séries temporais é provavelmente uma das mais importantes habilidades dentro do universo da Ciência de Dados. Afinal, o fator tempo é determinante em quase tudo que ocorre no mundo dos negócios.

E com os avanços das técnicas de Inteligência Artificial conseguimos construir modelos cada vez mais precisos, capazes de entregar respostas aos tomadores de decisão que podem fazer toda a diferença nas estratégias corporativas.

Este é um curso de alto nível que vai trazer para você modernas técnicas de IA aplicadas a análise e previsão de séries temporais e comparar essas técnicas com os métodos clássicos (que também são abordados no curso).

5- Cyber Security Data Science

No curso número 5 você vai aplicar técnicas de Data Science e Inteligência Artificial para resolver problemas na área de segurança cibernética. Um curso incrível não apenas para quem deseja aplicar análise de dados na área de segurança, mas também em problemas comuns na área de tecnologia, como configuração de rede, configuração de sistema operacional e segurança de acesso.

Além de conhecer as principais ameaças e riscos cibernéticos, você vai aprender quais são as estratégias ideais de segurança, como trabalhar com dados reais e como usar Ciência de Dados e IA para detectar anomalias, tentativas de invasão, ataques a bancos de dados e dispositivos IoT, e muito mais.

6- Infraestrutura Como Código com Terraform, AWS, Azure e Databricks

O sexto e último curso é a cereja do bolo. Você vai desenvolver as habilidades necessárias para criar a infraestrutura necessária para treinar seus modelos, fazer o deploy e publicar aplicações usando IaC (Infraestrutura Como Código) através do Terraform, ferramenta open-source que simplifica de forma considerável a maneira como criamos, usamos e então desfazemos a infraestrutura necessária para o trabalho com Data Science, Machine Learning e IA.

IaC (Infraestrutura Como Código) nasceu no universo DevOps, mas rapidamente chegou à área de dados para ajudar no trabalho de Engenheiros de Dados, Engenheiros de Machine Learning, Arquitetos de Dados, Cientistas de Dados e Engenheiros de IA.

Além do Terraform você vai trabalhar com AWS, Azure e Databricks através de diversos Labs e Projetos. O conhecimento que você irá adquirir neste curso vai colocá-lo muito a frente de outros profissionais do mercado, aumentando de forma considerável sua empregabilidade na área de dados, independente da sua função.

Não é incrível?

Mas espere, tem mais.

Assim como as demais Formações DSA você ainda recebe os Módulos Extras de Capacitação Profissional com os seguintes cursos de bônus:

  • Introdução à Lógica de Programação
  • Sistema Operacional Linux, Docker e Kubernetes
  • Governança de Dados
  • Empreendedorismo em Data Science, IA e Blockchain
  • Web Scraping e Análise de Dados
  • Soft Skills – Desenvolvendo Suas Habilidades Comportamentais
  • E-Gov Analytics
  • Machine Learning com JavaScript e Go
  • Data Science e Machine Learning com Linguagem Julia

A Formação está disponível em nosso portal. Confira:

Formação Engenheiro de IA

Obrigado

Equipe DSA

Machine Learning Guia Definitivo

Capítulo 93 – Machine Learning – Guia Definitivo – Parte 3

by

Nos 10 capítulos finais deste livro online vamos trazer um grande resumo sobre Machine Learning. O objetivo é fornecer uma visão clara do que é e como Machine Learning está sendo usado no dia a dia, um pouco de matemática, as principais regras e princípios. Queremos ainda que esses capítulos finais possam servir de material de referência para os alunos que estão buscando as certificações oferecidas pela DSA no Bootcamp de Certificação.

Serão 10 partes no total com um guia completo sobre Machine Learning. Aproveite a leitura para compreender de forma definitiva o que é uma das tecnologias mais incríveis do nosso tempo.

Agora, na Parte 3, um glossário com os 50 principais termos em Machine Learning.

Glossário

Os termos a seguir aparecerão repetidamente em projetos de Machine Learning (listamos em ordem de importância e similaridade e não em ordem alfabética):

1- Instância: linha, registro ou observação em seu conjunto de dados, sobre a qual você deseja fazer uma previsão. Por exemplo, cada instância pode ser um registro contendo informações sobre pacientes como idade, peso e altura e informação se o paciente desenvolveu diabetes. Queremos prever a ocorrência de diabetes com base nas características do paciente.

2- Rótulo (Label): uma resposta para uma tarefa de previsão, seja a resposta produzida por um sistema de aprendizado de máquina ou a resposta correta fornecida nos dados de treinamento. Por exemplo, o rótulo da instância definido no item anterior seria “diabetes”, indicando se o paciente desenvolveu ou não a doença.

3- Classe: uma categoria de um conjunto de valores de destino enumerados para um rótulo. Por exemplo, em um modelo de classificação binária que detecta spam, as duas classes são spam e não spam. Em um modelo de classificação multiclasse que identifica raças de cães, as classes seriam poodle, beagle, pug e assim por diante.

4- Recurso (Feature): uma propriedade de uma instância usada em uma tarefa de previsão. Por exemplo, uma instância com dados de pacientes teria um recurso indicando a idade.

5- Recurso Denso: um recurso em que a maioria dos valores é diferente de zero, normalmente um tensor de valores de ponto flutuante.

6- Recurso Esparso: vetor de recursos cujos valores são predominantemente zero ou vazios. Por exemplo, um vetor contendo um único valor 1 e um milhão de valores 0 é esparso. Como outro exemplo, as palavras em uma consulta de pesquisa também podem ser um recurso esparso – há muitas palavras possíveis em um determinado idioma, mas apenas algumas delas ocorrem em uma determinada consulta.

7- Dados Categóricos: recursos com um conjunto discreto de valores possíveis representando informação qualitativa. Por exemplo, considere um recurso categórico chamado estilo da casa, que possui um conjunto discreto de três valores possíveis: apartamento, casa e chalé.

8- Dados Numéricos: características representadas como números inteiros ou números reais. Por exemplo, em um modelo imobiliário, você provavelmente representaria o tamanho de uma casa (em metros quadrados) como dados numéricos. Representar um recurso como dados numéricos indica que os valores do recurso têm uma relação matemática entre si e possivelmente com o rótulo. 

9- Exemplo: uma instância (com seus recursos) e um rótulo.

10- Modelo: uma representação estatística de uma tarefa de previsão. Você treina um modelo em exemplos e depois usa o modelo para fazer previsões.

11- Baseline: um modelo usado como ponto de referência para comparar o desempenho de outro modelo (normalmente mais complexo). Por exemplo, um modelo de regressão logística pode servir como uma boa linha de base para um modelo de Deep Learning. Para um problema específico, a linha de base ajuda os Cientistas de Dados a quantificar o desempenho mínimo esperado que um novo modelo deve alcançar para que o novo modelo seja útil.

12- Aprendizado de Máquina Supervisionado: técnica para treinar um modelo a partir de dados de entrada e seus rótulos correspondentes. O aprendizado de máquina supervisionado é análogo a um aluno aprendendo um assunto estudando um conjunto de perguntas e suas respostas correspondentes. Depois de dominar o mapeamento entre perguntas e respostas, o aluno pode fornecer respostas para novas perguntas (nunca antes vistas) sobre o mesmo tema.

13- Aprendizado de Máquina Não Supervisionado: técnica para treinar um modelo para encontrar padrões em um conjunto de dados, normalmente um conjunto de dados não rotulado. O uso mais comum do aprendizado de máquina não supervisionado é agrupar dados em grupos de exemplos semelhantes. Por exemplo, um algoritmo de aprendizado de máquina não supervisionado pode agrupar músicas com base em várias propriedades da música. Os clusters resultantes podem se tornar uma entrada para outros algoritmos de aprendizado de máquina (por exemplo, para um serviço de recomendação de música). O clustering pode ser útil em domínios onde os rótulos verdadeiros são difíceis de obter. Por exemplo, em domínios como antiabuso e fraude, os clusters podem ajudar os humanos a entender melhor os dados. Outro exemplo de aprendizado de máquina não supervisionado é a análise de componentes principais (PCA). Por exemplo, a aplicação de PCA em um conjunto de dados contendo o conteúdo de milhões de carrinhos de compras pode revelar que carrinhos de compras contendo limões frequentemente também contêm antiácidos.

14- Métrica: medida da performance do seu modelo. Cada tipo de modelo pode ter uma ou mais métricas, que usamos para comparar a performance entre versões do modelo.

15- Função Objetivo: a fórmula matemática ou métrica que um modelo visa otimizar. Por exemplo, a função objetivo para regressão linear geralmente é o erro ao quadrado. Portanto, ao treinar um modelo de regressão linear, o objetivo é minimizar o erro quadrática. Em alguns casos, o objetivo é maximizar a função objetivo. Por exemplo, se a função objetivo é precisão, o objetivo é maximizar a precisão.

16- AUC (Área sob a Curva ROC): uma métrica de avaliação que considera todos os limites de classificação possíveis. A área sob a curva ROC é a probabilidade de um classificador estar mais confiante de que um exemplo positivo escolhido aleatoriamente é realmente positivo, do que um exemplo negativo escolhido aleatoriamente é positivo.

17- Acurácia: a fração de previsões que um modelo de classificação acertou. Em um modelo com acurácia de 82% dizemos que o modelo acerta 82 previsões a cada 100 previsões realizadas.

18- Precisão Média: uma métrica para resumir o desempenho de uma sequência classificada de resultados. A precisão média é calculada tomando a média dos valores de precisão para cada resultado relevante.

19- DataFrame: popular estrutura de dados para representar conjuntos de dados. Um DataFrame é análogo a uma tabela. Cada coluna do DataFrame tem um nome (um cabeçalho) e cada linha é identificada por um número.

20- Função de Ativação: uma função (por exemplo, ReLU ou sigmoid) que recebe a soma ponderada de todas as entradas da camada anterior em um modelo de rede neural e, em seguida, gera e passa um valor de saída (normalmente não linear) para a próxima camada.

21- Backpropagation: o algoritmo primário para executar gradiente descendente em redes neurais. Primeiro, os valores de saída de cada nó são calculados (e armazenados em cache) em uma passagem direta. Então, a derivada parcial do erro em relação a cada parâmetro é calculada em uma passagem para trás pelo grafo computacional, conforme estudado em detalhes neste livro online.

22- Batch: o conjunto de exemplos usados em uma iteração (ou seja, uma atualização de gradiente) do treinamento do modelo.

23- Batch Normalization: normalização da entrada ou saída das funções de ativação em uma camada oculta. A normalização em lote pode fornecer os seguintes benefícios: torna as redes neurais mais estáveis protegendo contra pesos discrepantes, habilita taxas de aprendizado mais altas e reduz o sobreajuste (overfitting).

24- Stochastic Gradient Descent (SGD): um algoritmo de descida de gradiente em que o tamanho do lote é um. Em outras palavras, o SGD conta com um único exemplo escolhido uniformemente de forma aleatória de um conjunto de dados para calcular uma estimativa do gradiente em cada etapa.

25- Overfitting: o overfiting (sobre ajuste) ocorre quando o modelo aprende os detalhes nos dados de treino. Não é isso que queremos em Machine Learning. Em aprendizado de máquina buscamos a criação de um modelo que aprende a generalização dos dados, para então fazer previsões com novos dados.

26- Bagging: um método para treinar um ensemble onde cada modelo constituinte é treinado em um subconjunto aleatório de exemplos de treinamento amostrados com substituição. Por exemplo, uma floresta aleatória (Random Forest) é uma coleção de árvores de decisão treinadas com bagging. O termo bagging é a abreviação de bootstrap aggregating.

27- Boosting: uma técnica de aprendizado de máquina que combina iterativamente um conjunto de classificadores simples e não muito precisos (referidos como classificadores “fracos”) em um classificador com alta precisão (um classificador “forte”), valorizando os exemplos que o modelo está classificando incorretamente no momento .

28- Bag of Words: uma representação das palavras em uma frase ou passagem, independentemente da ordem. Cada palavra é mapeada para um índice em um vetor esparso, onde o vetor tem um índice para cada palavra do vocabulário. Por exemplo, a frase “o cachorro pula” é mapeada em um vetor de características com valores diferentes de zero nos três índices correspondentes às palavras “o”, “cachorro” e “pula”.

29- Word Embedding: estrutura que representa cada palavra em um conjunto de palavras; ou seja, representando cada palavra como um vetor de valores de ponto flutuante entre 0,0 e 1,0. Palavras com significados semelhantes têm representações mais semelhantes do que palavras com significados diferentes. Por exemplo, cenoura, aipo e pepino teriam representações relativamente semelhantes, que seriam muito diferentes das representações de avião, óculos de sol e pasta de dente.

30- Inteligência Artificial: um programa ou modelo não humano que pode resolver tarefas sofisticadas. Por exemplo, um programa ou modelo que traduz texto ou um programa ou modelo que identifica doenças a partir de imagens radiológicas exibem Inteligência Artificial. Formalmente, o aprendizado de máquina é um subcampo da Inteligência Artificial. No entanto, nos últimos anos, algumas organizações começaram a usar os termos Inteligência Artificial e aprendizado de máquina de forma intercambiável.

31- Inteligência Artificial Geral: um mecanismo não humano que demonstra uma ampla gama de resolução de problemas, criatividade e adaptabilidade. Por exemplo, um programa que demonstra Inteligência Artificial Geral pode traduzir texto, compor sinfonias e se destacar em jogos que ainda não foram inventados.

32- Atenção: qualquer um de uma ampla gama de mecanismos de arquitetura de rede neural que agregam informações de um conjunto de entradas de maneira dependente de dados. Um mecanismo de atenção típico pode consistir em uma soma ponderada sobre um conjunto de entradas, onde o peso de cada entrada é calculado por outra parte da rede neural. São os blocos principais dos Transformers, estudados aqui mesmo neste livro online.

33- Recall: o recall é a medida do nosso modelo identificando corretamente os Verdadeiros Positivos. Assim, para todos os pacientes que realmente têm doença cardíaca, o recall nos diz quantos identificamos corretamente como tendo uma doença cardíaca.

34- Precisão: é a razão entre os Verdadeiros Positivos e todos os Positivos. Para nossa declaração de problema, essa seria a medida de pacientes que identificamos corretamente como tendo uma doença cardíaca entre todos os pacientes que realmente a têm.

35- Bias (ética/justiça): estereótipo, preconceito ou favoritismo em relação a algumas coisas, pessoas ou grupos em detrimento de outros. Esses vieses podem afetar a coleta e interpretação de dados, o design de um sistema e como os usuários interagem com um sistema.

36- Bias (matemática): uma interceptação ou deslocamento de uma origem. O bias (também conhecido como termo de viés) é referido como b ou w0 em modelos de aprendizado de máquina.

37- Classificação Binária: um tipo de tarefa de classificação que gera uma das duas classes mutuamente exclusivas. Por exemplo, um modelo de aprendizado de máquina que avalia mensagens de e-mail e gera “spam” ou “não spam” é um classificador binário.

38- BLEU (Bilingual Evaluation Understudy): uma pontuação entre 0,0 e 1,0, inclusive, indicando a qualidade de uma tradução entre duas línguas humanas (por exemplo, entre inglês e russo). Uma pontuação BLEU de 1,0 indica uma tradução perfeita; uma pontuação BLEU de 0,0 indica uma tradução terrível. Medida usada em modelos de Processamento de Linguagem Natural.

39- Normalização: o processo de conversão de um intervalo real de valores em um intervalo padrão de valores, normalmente -1 a +1 ou 0 a 1. Por exemplo, suponha que o intervalo natural de um determinado recurso seja de 800 a 6.000. Por meio de subtração e divisão, você pode normalizar esses valores no intervalo -1 a +1.

40- Normalização Z-score: uma técnica de normalização que substitui um valor de recurso bruto por um valor de ponto flutuante que representa o número de desvios padrão da média desse recurso.

41- Entropia Cruzada: uma generalização de Log Loss para problemas de classificação multiclasse. A entropia cruzada quantifica a diferença entre duas distribuições de probabilidade.

42- Matriz de Confusão: uma tabela NxN que agrega as suposições corretas e incorretas de um modelo de classificação. Um eixo de uma matriz de confusão é o rótulo que o modelo previu e o outro eixo é a verdade básica. N representa o número de classes. Por exemplo, N=2 para um modelo de classificação binária.

43- Validação: um processo usado, como parte do treinamento, para avaliar a qualidade de um modelo de aprendizado de máquina usando o conjunto de validação. Como o conjunto de validação é separado do conjunto de treinamento, a validação ajuda a garantir que o desempenho do modelo se generalize além do conjunto de treinamento.

44- Estacionaridade: uma propriedade de dados em um conjunto de dados, na qual a distribuição de dados permanece constante em uma ou mais dimensões. Mais comumente, essa dimensão é o tempo, o que significa que os dados que exibem estacionariedade não mudam com o tempo. Por exemplo, os dados que exibem estacionariedade não mudam de setembro a dezembro. Termo muito usado em análise de séries temporais.

45- Não Estacionaridade: uma propriedade de dados cujos valores mudam em uma ou mais dimensões, geralmente o tempo. Por exemplo, o número de maiôs vendidos em uma determinada loja demonstra não estacionaridade porque esse número varia com a estação. Como segundo exemplo, a quantidade de uma determinada fruta colhida em uma determinada região normalmente mostra uma acentuada não estacionariedade ao longo do tempo. Termo muito usado em análise de séries temporais.

46- Convergência: informalmente, muitas vezes se refere a um estado alcançado durante o treinamento no qual a perda de treinamento e a perda de validação mudam muito pouco ou nada a cada iteração após um certo número de iterações. Em outras palavras, um modelo atinge a convergência quando o treinamento adicional nos dados atuais não melhora o modelo. No aprendizado profundo, os valores de perda às vezes permanecem constantes por muitas iterações antes de finalmente descer, produzindo temporariamente uma falsa sensação de convergência.

47- Desbalanceamento de Classe: um problema de classificação binária em que os rótulos para as duas classes têm frequências significativamente diferentes. Por exemplo, um conjunto de dados de doenças em que 0,0001 dos exemplos tem rótulos positivos e 0,9999 têm rótulos negativos é um problema de desequilíbrio de classe, mas um preditor de jogo de futebol no qual 0,51 dos exemplos rotula um time vencedor e 0,49 rotula o outro time vencedor não é um problema de classe desequilibrada.

48- Limite (Threshold) de Classificação: um critério de valor escalar que é comparado com a pontuação prevista de um modelo para separar a classe positiva da classe negativa. Usado ao mapear resultados de regressão logística para classificação binária. Por exemplo, considere um modelo de regressão logística que determina a probabilidade de uma determinada mensagem de email ser spam. Se o limite de classificação for 0,9, os valores de regressão logística acima de 0,9 são classificados como spam e os abaixo de 0,9 são classificados como não spam.

49- Checkpoint: captura o estado dos parâmetros de um modelo em um determinado momento. Os pontos de verificação permitem exportar pesos de modelo ou realizar treinamento em várias sessões. Os pontos de verificação também permitem que o treinamento continue com erros anteriores.

50- Data Science Academy: maior portal da América Latina para o capacitação de alto nível em Data Science, IA, Blockchain, RPA e tecnologias relacionadas. 🙂

A partir do próximo capítulo veremos as regras para uso e aplicação de Machine Learning.

Machine Learning Guia Definitivo

Capítulo 92 – Machine Learning – Guia Definitivo – Parte 2

by

Nos 10 capítulos finais deste livro online vamos trazer um grande resumo sobre Machine Learning. O objetivo é fornecer uma visão clara do que é e como Machine Learning está sendo usado no dia a dia, um pouco de matemática, as principais regras e princípios. Queremos ainda que esses capítulos finais possam servir de material de referência para os alunos que estão buscando as certificações oferecidas pela DSA no Bootcamp de Certificação.

Serão 10 partes no total com um guia completo sobre Machine Learning. Aproveite a leitura para compreender de forma definitiva o que é uma das tecnologias mais incríveis do nosso tempo.

Agora na Parte 2, vejamos como Machine Learning está presente em diversos subcampos da Inteligência Artificial:

Processamento de Linguagem Natural

No Processamento de Linguagem Natural as máquinas aprendem a entender a linguagem natural, falada e escrita por humanos, em vez dos dados e números normalmente usados ​​para programar computadores. Isso permite que as máquinas reconheçam o idioma, o entendam e respondam a ele, bem como criem novos textos e traduzam idiomas. O Processamento de Linguagem Natural é a tecnologia por trás de chatbots e assistentes digitais como Siri ou Alexa.

Redes Neurais

As redes neurais são uma classe específica e comumente usada de algoritmos de aprendizado de máquina. As redes neurais artificiais são modeladas a partir do funcionamento do cérebro humano, no qual milhares ou milhões de nós de processamento são interconectados e organizados em camadas.

Em uma rede neural artificial, células ou nós são conectados, com cada célula processando entradas e produzindo uma saída que é enviada a outros neurônios. Os dados rotulados se movem pelos nós (estruturas matemáticas), ou células, com cada célula desempenhando uma função diferente. Em uma rede neural treinada para identificar se uma imagem contém um gato ou não, os diferentes nós avaliariam as informações e chegariam a uma saída que indica se uma imagem apresenta um gato. Os modelos de redes neurais atuais fazem isso muito bem.

Deep Learning

As redes de aprendizado profundo são redes neurais com muitas camadas. A rede com muitas camadas pode processar grandes quantidades de dados e determinar o “peso” de cada link na rede – por exemplo, em um sistema de reconhecimento de imagem, algumas camadas da rede neural podem detectar características individuais de um rosto, como olhos, nariz, ou boca, enquanto outra camada seria capaz de dizer se esses recursos aparecem de uma forma que indica um rosto. Estudamos Deep Learning ao longo deste livro online.

Assim como as redes neurais, o aprendizado profundo é modelado na maneira como o cérebro humano funciona e potencializa muitos usos do aprendizado de máquina, como veículos autônomos, chatbots e diagnósticos médicos.

O aprendizado profundo requer muito poder computacional, o que levanta preocupações sobre sua sustentabilidade econômica e ambiental.

Como as Empresas Estão Usando o Aprendizado de Máquina?

O aprendizado de máquina é o núcleo dos modelos de negócios de algumas empresas, como no caso do algoritmo de sugestões da Netflix ou do mecanismo de busca do Google. Outras empresas estão se engajando profundamente com o aprendizado de máquina, embora não seja sua principal proposta de negócios.

Outros ainda estão tentando determinar como usar o aprendizado de máquina de maneira eficiente. Um dos problemas mais difíceis no aprendizado de máquina é descobrir quais problemas podemos resolver com o aprendizado de máquina. Ainda há uma lacuna no entendimento.

Em um artigo de 2018, pesquisadores da Iniciativa do MIT sobre a Economia Digital delinearam uma pesquisa de 21 perguntas para determinar se uma tarefa é adequada para aprendizado de máquina. Os pesquisadores descobriram que nenhuma ocupação será intocada pelo aprendizado de máquina, mas é provável que nenhuma ocupação seja completamente dominada por ele. A maneira de desencadear o sucesso do aprendizado de máquina, descobriram os pesquisadores, era reorganizar os trabalhos em tarefas discretas, algumas que podem ser feitas por aprendizado de máquina e outras que exigem um humano.

As empresas já estão usando o aprendizado de máquina de várias maneiras, incluindo:

Algoritmos de recomendação. Os mecanismos de recomendação por trás das sugestões da Netflix e do YouTube, quais informações aparecem no seu feed do Facebook e recomendações de produtos, são alimentados pelo aprendizado de máquina. Os algoritmos estão tentando aprender nossas preferências. Eles querem aprender, como no Twitter, quais tweets queremos que eles nos mostrem, no Facebook, quais anúncios exibir e quais postagens ou conteúdos compartilhar conosco.

Análise de imagens e detecção de objetos. O aprendizado de máquina pode analisar imagens para obter informações diferentes, como aprender a identificar pessoas e diferenciá-las – embora os algoritmos de reconhecimento facial sejam controversos. Os usos comerciais para isso variam. Os fundos de hedge usam o aprendizado de máquina para analisar o número de carros em estacionamentos, o que os ajuda a saber como as empresas estão se saindo e fazer boas apostas.

Detecção de fraude. As máquinas podem analisar padrões, como por exemplo quanto alguém normalmente gasta ou onde costuma fazer compras, para identificar transações de cartão de crédito potencialmente fraudulentas, tentativas de login ou e-mails de spam.

Chatbots. Muitas empresas estão implantando chatbots, nos quais clientes interagem com uma máquina. Esses algoritmos usam aprendizado de máquina e Processamento de Linguagem Natural, com os bots aprendendo com registros de conversas anteriores para obter respostas apropriadas.

Carros autônomos. Grande parte da tecnologia por trás dos carros autônomos é baseada no aprendizado de máquina, em particular no aprendizado profundo (Deep Learning).

Imagiologia e diagnóstico médico. Programas de aprendizado de máquina podem ser treinados para examinar imagens médicas ou outras informações e procurar certos marcadores de doenças, como uma ferramenta que pode prever o risco de câncer com base em uma mamografia.

Como Machine Learning Funciona: Promessas e Desafios

Embora o aprendizado de máquina esteja alimentando a tecnologia que pode ajudar os trabalhadores ou abrir novas possibilidades para as empresas, há várias coisas que os líderes empresariais devem saber sobre o aprendizado de máquina e seus limites.

Explicabilidade

Uma área de preocupação é o que alguns especialistas chamam de explicabilidade, ou a capacidade de ser claro sobre o que os modelos de aprendizado de máquina estão fazendo e como eles tomam decisões. Entender por que um modelo faz o que faz é realmente uma questão muito difícil, e você sempre tem que se perguntar isso. Você nunca deve tratar isso como uma caixa preta, que vem apenas como um oráculo … sim, você deve usá-lo, mas então tente ter uma ideia de quais são as regras básicas que ele criou. E depois valide-as.

Isso é especialmente importante porque os sistemas podem ser enganados e prejudicados, ou simplesmente falhar em certas tarefas, mesmo aquelas que humanos podem executar facilmente. Por exemplo, ajustar os metadados nas imagens pode confundir os computadores – com alguns ajustes, uma máquina identifica uma foto de um cachorro como avestruz.

Houve um famoso caso em que um algoritmo de aprendizado de máquina examinando raios-X parecia superar os médicos. Mas descobriu-se que o algoritmo estava correlacionando os resultados com as máquinas que tiraram a imagem, não necessariamente a imagem em si. A tuberculose é mais comum em países em desenvolvimento, que tendem a ter máquinas mais antigas. O programa de aprendizado de máquina descobriu que, se o raio-X fosse feito em uma máquina mais antiga, o paciente era mais propenso a ter tuberculose. Ele completou a tarefa, mas não da maneira que os Cientistas de Dados pretendiam ou achariam útil.

A importância de explicar como um modelo está funcionando – e sua precisão – pode variar dependendo de como está sendo usado. Embora a maioria dos problemas possa ser resolvidos por meio de aprendizado de máquina, as pessoas devem assumir agora que os modelos funcionam apenas com cerca de 95% da precisão humana. Pode ser bom para o Cientista de Dados e o usuário se um algoritmo recomendando filmes for 95% preciso, mas esse nível de precisão não seria suficiente para um veículo autônomo ou um programa projetado para encontrar falhas graves em máquinas.

Viés e Resultados Não Intencionais

Máquinas são treinadas por humanos e preconceitos humanos podem ser incorporados em algoritmos – se informações tendenciosas ou dados que refletem desigualdades existentes forem alimentados a um programa de aprendizado de máquina, o programa aprenderá a replicá-lo e perpetuar formas de discriminação. Chatbots treinados sobre como as pessoas conversam no Twitter podem captar linguagem ofensiva e racista, por exemplo.

Em alguns casos, os modelos de aprendizado de máquina criam ou exacerbam problemas sociais. Por exemplo, o Facebook usa o aprendizado de máquina como uma ferramenta para mostrar aos usuários anúncios e conteúdo que os interessarão e os envolverão – o que pode levar a modelos que mostram às pessoas conteúdo extremo que causa polarização e disseminação de teorias da conspiração.

Maneiras de combater o preconceito no aprendizado de máquina, incluindo a verificação cuidadosa de dados de treinamento e apoio organizacional por trás de esforços éticos de Inteligência Artificial, como garantir que uma organização adote IA centrada no ser humano, a prática de buscar informações de pessoas de diferentes origens, experiências e estilos de vida quando projetar sistemas de IA. As iniciativas que trabalham nesta questão incluem o projeto Algorithmic Justice League e The Moral Machine.

Colocando o Aprendizado de Máquina Para Funcionar

Os executivos tendem a lutar para entender onde o aprendizado de máquina pode realmente agregar valor à empresa. O que é enigmático para uma empresa é essencial para outra e as empresas devem evitar tendências e encontrar casos de uso de negócios que funcionem para elas.

A maneira como o aprendizado de máquina funciona para a Amazon provavelmente não será traduzido em uma empresa de automóveis – embora a Amazon tenha encontrado sucesso com assistentes de voz, isso não significa que as empresas de automóveis devam priorizar a adição de assistentes aos carros. O mais provável é que a montadora encontre uma maneira de usar o aprendizado de máquina na linha da fábrica que economize ou ganhe muito dinheiro.

O campo de estudo em Machine Learning está se movendo rapidamente, e isso é incrível, mas torna difícil para os executivos tomar decisões e decidir quanto recursos devem ser investidos na tecnologia.

Também é melhor evitar olhar para o aprendizado de máquina como uma solução em busca de um problema. Algumas empresas podem acabar tentando fazer engenharia reversa do aprendizado de máquina em um uso comercial. Em vez de começar com foco em tecnologia, as empresas devem começar com foco em um problema de negócios ou necessidade do cliente que possa ser atendido com aprendizado de máquina.

Uma compreensão básica do aprendizado de máquina é importante mas, encontrar o uso certo de aprendizado de máquina depende, em última análise, de pessoas com diferentes conhecimentos trabalhando juntos. 

Continuamos no próximo capítulo!

Referências:

Machine Learning com R e Python

Machine Learning com Python e C++

Machine Learning, Explained

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 90 – Como Funcionam os Transformadores em Processamento de Linguagem Natural – Parte 5
  • Capítulo 89 – Como Funcionam os Transformadores em Processamento de Linguagem Natural – Parte 4
  • Capítulo 88 – Como Funcionam os Transformadores em Processamento de Linguagem Natural – Parte 3
  • Capítulo 87 – Como Funcionam os Transformadores em Processamento de Linguagem Natural – Parte 2
  • Capítulo 86 – Como Funcionam os Transformadores em Processamento de Linguagem Natural – Parte 1
  • Capítulo 85 – Transformadores – O Estado da Arte em Processamento de Linguagem Natural
  • Capítulo 84 – CLIP (Contrastive Language Image Pre-training): Conectando Texto e Imagens
  • Capítulo 83 – Liquid Neural Network – Rede Neural Líquida
  • Capítulo 82 – GPT-3 – Características e Limitações
  • Capítulo 81 – Modelos de Linguagem Como Tarefas Não Supervisionadas (GPT-2)

Buscar

Podcast DSA

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