Retropropagação é uma técnica de aprendizado de máquina essencial para a otimização de redes neurais artificiais. Ela facilita o uso de algoritmos de gradiente descendente para atualizar os pesos da rede, que é como os modelos de deep learning que impulsionam a inteligência artificial (IA) moderna "aprendem".
Abreviação de "backward propagation of error" (propagação reversa de erro), é um método elegante para calcular como as alterações em qualquer um dos pesos ou vieses de uma rede neural afetarão a precisão das previsões do modelo. É essencial para o uso de aprendizado supervisionado, aprendizado semissupervisionado ou aprendizado autossupervisionado para treinar redes neurais.
Embora equivalentes e predecessores da retropropagação tenham sido propostos de forma independente em contextos variados desde a década de 1960, David E. Rumelhart, Geoffrey Hinton e Ronald J. Williams publicaram pela primeira vez o algoritmo de aprendizado formal. Seu artigo de 1986, "Learning representations by back-propagating errors", forneceu a derivação do algoritmo de retropropagação conforme usado e compreendido em um contexto moderno de aprendizado de máquina.
A lógica da retropropagação é que as camadas de neurônios em redes neurais artificiais são essencialmente uma série de funções matemáticas aninhadas. Durante o treinamento, essas equações interconectadas são aninhadas em outra função: uma "função de perda", que mede a diferença (ou "perda") entre a saída desejada (ou "verdade absoluta") para uma determinada entrada e a saída real da rede neural.
Podemos, portanto, usar a “regra da cadeia”, um princípio do cálculo diferencial que remonta ao século XVII, para calcular a taxa com que cada neurônio contribui para a perda total. Ao fazer isso, podemos calcular o impacto de alterações em qualquer variável (ou seja, em qualquer peso ou viés) dentro das equações que esses neurônios representam.
Em termos matemáticos, a retropropagação funciona de trás para frente a partir da saída para calcular com eficiência o "gradiente" da função de perda: um vetor de derivadas para cada equação na rede. Esse gradiente informa aos algoritmos de otimização, como o "gradiente descendente", quais equações devem ser ajustadas e em que direção devem ser ajustadas para reduzir a perda.
Esses três processos entrelaçados (uma função de perda que rastreia o erro do modelo em diferentes entradas, a propagação reversa desse erro para ver como diferentes partes da rede contribuem para o erro e os algoritmos de gradiente descendente que ajustam os pesos do modelo adequadamente) são como os modelos de aprendizado profundo “aprendem”. Dessa forma, a retropropagação é fundamental para treinar modelos de redes neurais, desde os perceptrons multicamadas mais básicos até as complexas arquiteturas de redes neurais profundas usadas para IA generativa.
Boletim informativo do setor
Mantenha-se atualizado sobre as tendências mais importantes e fascinantes do setor em IA, automação, dados e muito mais com o boletim informativo da Think. Consulte a declaração de privacidade da IBM.
Sua inscrição será entregue em inglês. Você pode encontrar um link para cancelar a inscrição em todos os boletins informativos. Você pode gerenciar suas inscrições ou cancelar a inscrição aqui. Consulte nossa declaração de privacidade da IBM para obter mais informações.
Como o processo de retropropagação é fundamental para a forma como as redes neurais são treinadas, uma explicação útil do processo requer um entendimento prático de como as redes neurais fazem previsões.
Mais importante ainda, é útil entender o propósito e o contexto dos "pesos" e "vieses": os parâmetros ajustáveis do modelo que são otimizados por meio de retropropagação e gradiente descendente.
As redes neurais visam imitar em linhas gerais a estrutura do cérebro humano. Elas são compostas por muitos nós (ou neurônios) interconectados, dispostos em camadas. As redes neurais fazem previsões quando os dados de entrada originais fazem uma "passagem para a frente" por toda a rede.
Os neurônios na "camada de entrada" recebem dados de entrada, geralmente como uma incorporação vetorial, com cada neurônio de entrada recebendo uma funcionalidade individual do vetor de entrada. Por exemplo, um modelo que funciona com imagens em escala de cinza de 10x10 pixels normalmente terá 100 neurônios em sua camada de entrada, com cada neurônio de entrada correspondendo a um pixel individual. Assim, as redes neurais normalmente exigem entradas de tamanho fixo, embora técnicas como agrupamento ou normalização possam fornecer alguma flexibilidade.
Em uma rede neural feedforward padrão, cada neurônio da camada de entrada é conectado a cada um dos neurônios da camada seguinte, que, por sua vez, são conectados aos neurônios da camada seguinte, e assim por diante, até a camada de saída , onde são feitas as previsões finais. As camadas intermediárias entre a camada de entrada e a camada de saída, chamadas de camadas ocultas da rede, são onde ocorre a maior parte do “aprendizado”.
Embora algumas arquiteturas especializadas de redes neurais, como a combinação de modelos especializados ou as redes neurais convolucionais, impliquem variações, adições ou exceções a esse arranjo simples, todas as redes neurais empregam essa estrutura central.
Embora cada neurônio receba entradas de cada nó da camada anterior, nem todas essas entradas recebem a mesma importância. Cada conexão entre dois neurônios recebe um "peso" único: um multiplicador que aumenta ou diminui a contribuição de um neurônio para um neurônio na camada seguinte.
Cada neurônio individual também pode receber um "viés": um valor constante adicionado à soma das entradas ponderadas dos neurônios na camada anterior.
O objetivo final da retropropagação e do gradiente descendente é calcular os pesos e os vieses que produzirão as melhores previsões do modelo. Os neurônios correspondentes a funcionalidades de dados que se correlacionam significativamente com previsões precisas recebem pesos maiores; outras conexões podem receber pesos que se aproximam de zero.
As redes neurais modernas, muitas vezes com dezenas de camadas ocultas, cada uma contendo muitos neurônios, podem incluir milhares, milhões ou (no caso da maioria dos grandes modelos de linguagem [LLMs]) bilhões desses parâmetros ajustáveis.
Cada neurônio é configurado para realizar uma operação matemática, chamada de "função de ativação", sobre a soma das entradas ponderadas de forma variável que recebe dos nós na camada anterior. As funções de ativação introduzem a "não linearidade", permitindo que o modelo capture padrões complexos nos dados de entrada e produza gradientes que podem ser otimizados. Usar apenas funções de ativação linear basicamente "colapsa" a rede neural em um modelo de regressão linear.
As funções de ativação comuns em redes neurais incluem:
Considere uma unidade oculta hipotética z, com uma função de ativação tanh e termo de viés t, na segunda camada de uma rede neural com três nós de entrada, a, b e c, em sua camada de entrada. Cada uma das conexões entre os nós de entrada e o nó z tem um peso único, w. Podemos descrever o valor de saída que o nó z passará para os neurônios na próxima camada com a equação simplificada z = tanh(waz*a + wbz*b + wcz*c + t).
O neurônio z está conectado aos neurônios na próxima camada. Portanto, essa equação para z faz parte das funções de ativação na próxima camada e, por extensão, também faz parte de todas as funções de ativação para quaisquer neurônios em qualquer camada subsequente.
Como será explicado nas seções a seguir, a retropropagação é um algoritmo notavelmente rápido e eficiente para desvendar a enorme rede de variáveis e equações interconectadas em uma rede neural.
Para ilustrar a eficiência da retropropagação, Michael Nielsen a compara a uma abordagem alternativa simples e intuitiva para calcular o gradiente da função de perda de uma rede neural em seu livro online, "Neural Networks and Deep Learning".
Como explica Nielsen, pode-se estimar facilmente o impacto das mudanças em qualquer peso específico wj na rede simplesmente completando uma passagem para a frente para dois valores ligeiramente diferentes de wj, mantendo todos os outros parâmetros inalterados e comparando a perda resultante para cada passagem. Ao formalizar esse processo em uma equação direta e implementar algumas linhas de código no Python, é possível automatizar esse processo para cada peso na rede.
Mas agora imagine que há 1 milhão de pesos em seu modelo, o que seria bastante modesto para um modelo moderno de deep learning. Para calcular o gradiente inteiro, você precisaria concluir 1.000.001 de passagens para a frente pela rede: uma para estabelecer uma linha de base e, em seguida, outra passagem para avaliar as alterações em cada um do milhão de pesos.
A retropropagação pode atingir o mesmo objetivo em duas passagens: uma passagem para a frente e uma passagem para trás.
Para simplificar uma explicação de como a retropropagação funciona, será útil primeiro revisar brevemente alguns dos principais conceitos e terminologia matemáticos.
A regra da cadeia é essencial para calcular as derivadas das funções de ativação nas redes neurais, que são compostas pelas saídas das funções de ativação de outros neurônios nas camadas anteriores.
Embora a lógica por trás da retropropagação seja relativamente simples, a matemática e a notação podem se tornar muito complexas, especialmente para aqueles que não estão familiarizados com o cálculo de variáveis.
Trabalhando para trás a partir da saída do modelo, a retropropagação aplica a "regra da cadeia" para calcular a influência das alterações em cada parâmetro da rede neural individual no erro geral das previsões do modelo.
Em termos abstratos, o objetivo da retropropagação é treinar uma rede neural para fazer melhores previsões por meio de aprendizado supervisionado. Mais fundamentalmente, o objetivo da retropropagação é determinar como os pesos e os vieses do modelo devem ser ajustados para minimizar o erro medido por uma "função de perda".
Em um nível técnico e matemático, o objetivo da retropropagação é calcular o gradiente da função de perda em relação a cada um dos parâmetros individuais da rede neural. Em termos mais simples, a retropropagação usa a regra da cadeia para calcular a taxa na qual a perda muda em resposta a qualquer alteração em um peso (ou viés) específico na rede.
De um modo geral, o treinamento de redes neurais com retropropagação envolve as seguintes etapas:
As redes neurais produzem previsões por meio de propagação para a frente. A propagação para a frente é essencialmente uma longa série de equações aninhadas, com as saídas das funções de ativação de uma camada de neurônios servindo como entradas para as funções de ativação dos neurônios na próxima camada.
O treinamento do modelo normalmente começa com uma inicialização aleatória de pesos e vieses. Os hiperparâmetros do modelo , como o número de camadas ocultas, o número de nós em cada camada e as funções de ativação para neurônios específicos, são configurados manualmente e não estão sujeitos a treinamento.
Em cada passagem para a frente, é amostrada uma entrada do conjunto de dados de treinamento. Os nós da camada de entrada recebem o vetor de entrada, e cada um passa seu valor (multiplicado por algum peso inicial aleatório) para os nós da primeira camada oculta. As unidades ocultas tomam a soma ponderada desses valores de saída como entrada para uma função de ativação, cujo valor de saída (condicionado por um peso inicial aleatório) serve como entrada para os neurônios na próxima camada. Isso continua até a camada de saída, onde ocorre uma previsão final.
Considere este exemplo simplificado de uma rede neural que classifica as entradas em uma de cinco categorias:
Em uma rede bem treinada, esse modelo produzirá consistentemente um valor de alta probabilidade para a classificação correta e produzirá valores de baixa probabilidade para as outras classificações incorretas. No entanto, essa rede neural ainda não está treinada. Neste ponto, seus pesos e vieses têm valores iniciais aleatórios e, portanto, suas previsões são geralmente imprecisas.
Após cada avanço, uma "função de perda" mede a diferença (ou "perda") entre a saída prevista do modelo para uma determinada entrada e as previsões corretas (ou "verdade absoluta") para essa entrada. Em outras palavras, mede o qunto o resultado real do modelo é diferente do resultado desejado.
No aprendizado supervisionado, que usa dados rotulados, a verdade absoluta é fornecida por anotações manuais. No aprendizado autossupervisionado, que mascara ou transforma partes de amostras de dados não rotuladas e modelos de tarefas reconstruindo-os, a amostra original serve como verdade absoluta.
O objetivo dessa função de perda é quantificar a imprecisão de uma forma que reflita adequadamente a natureza e a magnitude do erro da saída do modelo para cada entrada. Diferentes fórmulas matemáticas para perda são mais adequadas a tarefas específicas: por exemplo, variantes do erro quadrático médio funcionam bem para problemas de regressão, enquanto variantes de perda de entropia cruzada funcionam bem para classificação.
Como a função de perda recebe como input a saída de uma rede neural, e essa saída é uma função composta formada por muitas funções de ativação aninhadas de neurônios individuais, a diferenciação da função de perda envolve a diferenciação de toda a rede. Para isso, a backpropagation usa a regra da cadeia.
"Função de perda", "função de custo" ou "função de erro"?
Vale a pena notar rapidamente que, em alguns contextos, os termos função de custo ou função de erro são usados no lugar de função de perda, com "custo" ou "erro" substituindo "perda".
Embora algumas publicações sobre aprendizado de máquina atribuam nuances exclusivas a cada termo, eles geralmente são intercambiáveis.1 Uma função objetiva é um termo mais amplo para qualquer função de avaliação que desejamos minimizar ou maximizar. Função de perda, função de custo ou função de erro referem-se especificamente a termos que queremos minimizar.
Começando pela camada final, uma "passagem para trás" diferencia a função de perda para calcular como cada parâmetro individual da rede contribui para o erro geral para uma única entrada.
Voltando ao nosso exemplo anterior do modelo classificador, começaríamos com os cinco neurônios na camada final, que chamaremos de camada L. O valor softmax de cada neurônio de saída representa a probabilidade, de 1, de uma entrada pertencer a sua categoria. Em um modelo perfeitamente treinado, o neurônio que representa a classificação correta teria um valor de saída próximo a 1, e os outros neurônios teriam um valor de saída próximo a 0.
Por enquanto, vamos nos concentrar na unidade de saída que representa a previsão correta, que chamaremos de Lc.A função de ativação de Lcé uma função composta, contendo as muitas funções de ativação aninhadas de toda a rede neural, da camada de entrada até a camada de saída. Minimizar a função de perda implicaria fazer ajustes em toda a rede que trouxessem a saída a função de ativação de Lc para mais perto de 1.
Para fazer isso, precisaremos saber como qualquer alteração nas camadas anteriores alterará a saída do próprio Lc. Em outras palavras, precisaremos encontrar as derivadas parciais da função de ativação de Lc.
A saída da função de ativação de Lcdepende das contribuições que ela recebe dos neurônios na penúltima camada, que chamaremos de camada L-1. Uma maneira de alterar a saída de Lcé alterar os pesos entre os neurônios em L-1 e Lc. Ao calcular a derivada parcial de cada peso de L-1 em relação aos outros pesos, podemos ver como aumentar ou diminuir qualquer um deles trará o resultado de Lc para mais perto (ou mais longe) de 1.
Mas essa não é a única maneira de alterar a saída de Lc. As contribuições que Lc recebe de neurônios de L-1 são determinadas não apenas pelos pesos aplicados aos valores de saída de L-1, mas pelos próprios valores de saída reais (pré-peso). Os valores de saída dos neurônios de L-1 , por sua vez, são influenciados por pesos aplicados às entradas que eles recebem de L-2. Portanto, podemos diferenciar as funções de ativação em L-1 para encontrar as derivadas parciais dos pesos aplicados às contribuições de L-2. Essas derivadas parciais nos mostram como qualquer alteração em um peso de L-2 afetará as saídas em L-1, o que posteriormente afetaria o valor de saída de Lc e, assim, afetaria a função de perda.
Por essa mesma lógica, também poderíamos influenciar os valores de saída que os neurônios de L-1 recebem dos neurônios de L-2 , ao ajustar as contribuições que os neurônios de L-2 recebem dos neurônios de L-3. Então, encontramos as derivadas parciais em L-3, e assim por diante, repetindo recursivamente esse processo até alcançarmos a camada de entrada. Quando terminamos, teremos o gradiente da função de perda: um vetor de sua derivada parcial para cada parâmetro de peso e viés na rede.
Agora, concluímos uma passagem para a frente e uma passagem para trás para um único exemplo de treinamento. No entanto, nosso objetivo é treinar o modelo para generalizar bem para novas entradas. Para fazer isso, é necessário treinamento em um grande número de amostras que reflitam a diversidade e a variedade de entradas em relação às quais modelo terá a tarefa de fazer previsões após o treinamento.
Agora que temos os gradientes da função de perda em relação a cada parâmetro de peso e viés da rede, podemos minimizar a função de perda, e assim otimizar o modelo, usando o gradiente descendente para atualizar os parâmetros do modelo.
Mover para baixo —descendente— o gradiente da função de perda diminuirá a perda. Como o gradiente que calculamos durante a retropropagação contém as derivadas parciais para cada parâmetro do modelo, sabemos em qual direção "mover" cada um de nossos parâmetros para reduzir a perda.
Cada etapa reflete o “aprendizado” do modelo a partir de seus dados de treinamento. Nosso objetivo é atualizar iterativamente os pesos até atingir o gradiente mínimo. O objetivo dos algoritmos de gradiente descendente é encontrar os ajustes específicos de parâmetros que nos conduzam pelo gradiente da forma mais eficiente.
O tamanho de cada etapa é um hiperparâmetro ajustável, chamado de taxa de aprendizado. Escolher a taxa de aprendizado correta é essencial para um treinamento eficiente e eficaz.
Lembre-se de que as funções de ativação em uma rede neural são não lineares. Alguns gradientes podem ter uma forma aproximadamente em U: ao avançar em uma direção, o movimento segue descendo o gradiente, mas continuar nessa direção eventualmente faz com que o movimento passe a subir o gradiente.
Uma taxa de aprendizado baixa garante que sempre avancemos na direção correta, mas calcular tantas alterações pode ser demorado e exigir muito da computação. Uma taxa de aprendizado alta é mais eficiente computacionalmente, mas corre o risco de ultrapassar o mínimo.
Outro aspecto a considerar no gradiente descendente é a frequência com que os pesos devem ser atualizados. Uma opção é calcular os gradientes para cada exemplo no conjunto de dados de treinamento, depois tirar a média desses gradientes e usá-la para atualizar os parâmetros. O processo é repetido de forma iterativa em uma série de períodos de treinamento até que a taxa de erro se estabilize. Esse método é chamado de gradiente descendente por lote.
Quando o conjunto de dados de treinamento é muito grande, como geralmente ocorre em deep learning, o gradiente descendente por lote exige tempos de processamento excessivamente longos. Calcular gradientes para milhões de exemplos a cada iteração de atualização de pesos torna-se ineficiente. No gradiente descendente estocástico (cada período utiliza um único exemplo de treinamento por etapa. Embora a perda possa flutuar de um período para outro, ela rapidamente converge para o mínimo ao longo de várias atualizações.
O gradiente descendente por minilote representa uma abordagem intermediária. Os exemplos de treinamento são selecionados aleatoriamente em lotes de tamanho fixo, e seus gradientes são calculados e depois combinados em uma média. Isso reduz os requisitos de memória do gradiente descendente por lote e também diminui a instabilidade relativa do SGD.
Treine, valide, ajuste e implemente recursos de IA generativa, modelos de base e recursos de aprendizado de máquina com o IBM watsonx.ai, um estúdio empresarial de última geração para construtores de IA. Crie aplicações de IA em uma fração do tempo com uma fração dos dados.
Use a IA a serviço de sua empresa com a experiência e o portfólio de soluções líder do setor da IBM à sua disposição.
Reinvente os fluxos de trabalho e operações críticos adicionando IA para maximizar experiências, tomadas de decisão em tempo real e valor de negócios.
¹ "Deep Learning", Goodfellow et al, MIT Press, 2016.
IBM web domains
ibm.com, ibm.org, ibm-zcouncil.com, insights-on-business.com, jazz.net, mobilebusinessinsights.com, promontory.com, proveit.com, ptech.org, s81c.com, securityintelligence.com, skillsbuild.org, softlayer.com, storagecommunity.org, think-exchange.com, thoughtsoncloud.com, alphaevents.webcasts.com, ibm-cloud.github.io, ibmbigdatahub.com, bluemix.net, mybluemix.net, ibm.net, ibmcloud.com, galasa.dev, blueworkslive.com, swiss-quantum.ch, blueworkslive.com, cloudant.com, ibm.ie, ibm.fr, ibm.com.br, ibm.co, ibm.ca, community.watsonanalytics.com, datapower.com, skills.yourlearning.ibm.com, bluewolf.com, carbondesignsystem.com, openliberty.io