Introdução
As funções de perda são fundamentais no treinamento de modelos de ML, e, na maioria dos projetos de aprendizado de máquina, não há como orientar seu modelo a fazer previsões corretas sem uma função de perda. Em termos simples, uma função de perda é uma função matemática ou expressão usada para medir o desempenho de um modelo em um conjunto de dados. Sabendo como bem um modelo está sendo executado the um determinado conjunto de dados dá ao desenvolvedor insights para tomar muitas decisões durante o treinamento, como usar um novo modelo mais poderoso ou até mesmo mudar a própria função de perda para um tipo diferente. Falando dos tipos de funções de perda, muitas destas funções de perda foram desenvolvidas ao longo dos anos, cada uma adequada para uso em uma tarefa de treinamento particular.
Pré-requisitos
Este artigo requer um entendimento de redes neurais. Ao nível superior, as redes neurais são compostas por nós interligados (“neurônios”) organizados em camadas. Eles aprendem e fazem previsões através de um processo chamado “treinamento”, que ajusta os pesos e bias das conexões entre os neurônios. O entendimento de redes neurais inclui o conhecimento de suas diferentes camadas (camada de entrada, camadas ocultas, camada de saída), funções de ativação, algoritmos de otimização (variações do descida do gradiente), funções de perda, etc.
Adicionalmente, a familiaridade com a sintaxe do Python e com a biblioteca PyTorch é fundamental para entender os trechos de código apresentados neste artigo.
Neste artigo, vamos explorar diferentes funções de perda que fazem parte do módulo PyTorch nn. Vamos então mergulhar mais fundo em como a PyTorch expõe essas funções de perda aos usuários como parte de sua API de módulo nn, construindo uma custom.
Com um entendimento de alto nível de que é uma função de perda, vamos explorar alguns detalhes técnicos sobre como as funções de perda funcionam.
O que são funções de perda?
Dissemos anteriormente que as funções de perda nos dizem quanto bem um modelo está em um conjunto de dados particular. Técnicamente, isso o faz medindo quão próximo o valor predito está do valor real. Quando nosso modelo está fazendo previsões muito próximas dos valores reais tanto no conjunto de treinamento quanto no de teste, isso significa que temos um modelo bastante robusto.
Embora as funções de perda nos dêem informações críticas sobre o desempenho de nosso modelo, essa não é a função primária das funções de perda, já que existem técnicas mais robustas para avaliar os nossos modelos, como a precisão e as métricas F1. A importância das funções de perda é realizada principalmente durante o treinamento, onde nudgem os pesos do nosso modelo na direção que minimiza a perda. Fazendo isso, aumentamos a probabilidade de nosso modelo fazer previsões corretas, algo que provavelmente não seria possível sem uma função de perda.
Diferentes funções de perda servem para diferentes problemas, cada uma elaborada com cuidado por pesquisadores para garantir um fluxo de gradiente estável durante o treinamento.
Em algumas situações, as expressões matemáticas das funções de perda podem ser um pouco assustadoras, e isso levou alguns desenvolvedores a tratá-las como caixas pretas. Vamos revelar algumas das funções de perda mais usadas em PyTorch mais tarde, mas antes disso, vamos olhar para como usamos funções de perda no mundo de PyTorch.
Funções de perda em PyTorch
PyTorch vem com muitas funções de perda canônicas com padrões de design simples que permitem que desenvolvedores iteriem rapidamente nestas diferentes funções de perda durante o treinamento. Todas as funções de perda do PyTorch estão embutidas no módulo nn, a classe base de todas as redes neurais do PyTorch. Isso torna a adição de uma função de perda em seu projeto tão fácil quanto adicionar uma linha de código simples. Vamos ver como adicionar uma função de perda de erro quadrático médio em PyTorch.
A função retornada acima pode ser usada para calcular quanto uma previsão está de longe do valor real usando o formato abaixo.
Agora que temos uma ideia de como usar funções de perda em PyTorch, vamos mergulhar fundo nas operações de trás das cenas de várias das funções de perda que o PyTorch oferece.
Quais funções de perda estão disponíveis em PyTorch?
Muitas destas funções de perda que o PyTorch vem com são amplamente categorizadas em 3 grupos – perda de regressão, perda de classificação e perda de classificação.
As perdas de regressão são principalmente interessadas em valores contínuos que podem assumir qualquer valor entre dois limites. Um exemplo disto seria as previsões dos preços de casas de uma comunidade.
As funções de perda de classificação lidam com valores discretos, como a tarefa de classificar um objeto como uma caixa, caneta ou garrafa.
As perdas de ranking preveem as distâncias relativas entre valores. Um exemplo disto seria a verificação de faces, onde queremos saber quais imagens de faces pertencem a uma determinada face e podemos fazer isso classificando quais faces sim e não pertencem ao original dono da face através de seu grau de aproximação relativa à imagem de scan de faces alvo.
Função de perda L1 / Erro Absoluto Médio
A função de perda L1 calcula a média absoluta do erro entre cada valor no tensor predito e o valor de referência. Primeiro, calcula a diferença absoluta entre cada valor no tensor predito e o valor de referência, e computa a soma de todos os valores retornados de cada cálculo de diferença absoluta. Finalmente, calcula a média desta soma de valores para obter a média absoluta do erro (MAE). A função de perda L1 é muito resistente ao ruído.
O valor único retornado é a perda calculada entre dois tensores com dimensões 3×5.
Erro Quadrático Médio
A taxa de Erro Quadrático Médio (MSE) tem semelhanças notáveis com a MAE. Em vez de calcular a diferença absoluta entre os valores no tensor de predição e no alvo, como é o caso com a taxa de Erro Absoluto Médio, ela calcula a diferença quadrática entre os valores no tensor de predição e no tensor de alvo. Fazendo isso, as diferenças relativamente grandes são penalizadas mais, enquanto as diferenças relativamente pequenas são penalizadas menos. A MSE é considerada menos resistente em lidar com outliers e ruído do que a MAE, no entanto.
Taxa de Perda de Cross-Entropy
A taxa de perda de cross-entropy é usada em problemas de classificação envolvendo um número de classes discretas. Ela mede a diferença entre duas distribuições de probabilidade para um determinado conjunto de variáveis aleatórias. Normalmente, quando usamos a taxa de perda de cross-entropy, a saída de nossa rede é uma camada softmax, que garante que a saída da rede neural é um valor de probabilidade (valor entre 0-1).
A camada softmax consiste em duas partes – o expoente da predição para uma classe particular.
yi é a saída da rede neural para uma classe particular. A saída desta função é um número próximo de zero, mas nunca zero, se yi for grande e negativo, e mais próximo de 1 se yi for positivo e muito grande.
A segunda parte é um valor de normalização e é usado para garantir que a saída da camada softmax seja sempre um valor de probabilidade.
Este é obtido pela soma de todos os expoentes de cada valor de classe. A equação final da softmax parece assim:
]
No módulo nn do PyTorch, a perda de cross-entropy combina a log-softmax e a perda de negativo log-likelihood (NLL) em uma única função de perda.
Note como a função de gradiente no output impresso é uma perda NLL. Isso na verdade revela que a perda de cross-entropy combina a perda NLL por trás de uma camada log-softmax.
Negativo Log-Likelihood (NLL) Loss
A função de perda NLL funciona muito similarmente à função de perda de cross-entropy. A perda de cross-entropy combina uma camada log-softmax e a perda NLL para obter o valor da perda de cross-entropy. Isso significa que a perda NLL pode ser usada para obter o valor da perda de cross-entropy colocando na última camada da rede neural uma camada log-softmax em vez de uma camada softmax normal.
Perda de Cross-Entropia Binaria
A perda de cross-entropia binaria é uma classe especial de perdas de cross-entropia usada para o problema especial de classificar pontos de dados em apenas duas classes. As etiquetas para este tipo de problema são usualmente binárias, e portanto, o nosso objetivo é empurrar o modelo a prever um número próximo de zero para uma etiqueta zero e um número próximo de um para uma etiqueta um. Normalmente, quando se usa a perda BCE para classificação binaria, a saída da rede neural é uma camada de sigmóide para garantir que a saída seja um valor próximo de zero ou um valor próximo de um.
Perda de Cross-Entropia Binária com Logits
Como mencionamos na seção anterior, a perda de cross-entropia binária normalmente é outputada com uma camada Sigmoid para garantir que a saída esteja entre 0 e 1. Uma perda de cross-entropia binária com logits combina estas duas camadas em uma camada só. De acordo com a documentação PyTorch, esta é uma versão mais numéricamente estavel, pois ela usa a trica de log-sum exp.
Perda Smooth L1
A função de perda L1 suave combina os benefícios da perda MSE e da perda MAE através de um valor heurístico beta. Este critério foi introduzido no artigo Fast R-CNN. Quando a diferença absoluta entre o valor verdadeiro e o valor predito é menor que beta, o critério usa uma diferença quadrada, muito como a perda MSE. O gráfico da perda MSE é uma curva contínua, o que significa que a gradiente em cada valor de perda varia e pode ser derivado em todo o lugar. Além disso, conforme o valor de perda diminui, o gradiente diminui, o que é conveniente durante o descida por gradientes. No entanto, para valores de perda muito altos, o gradiente explode, portanto o critério para mudar para a MAE, para a qual o gradiente é quase constante para cada valor de perda, quando a diferença absoluta torna-se maior do que beta e a possível explosão de gradiente é eliminada.
Perda de Embedding de Quebra de Ângulo
A perda de embeddings de quebra de ângulo é principalmente usada em tarefas de aprendizagem semi-supervisionada para medir a similaridade entre duas entradas. Ela é usada quando há um tensor de entrada e um tensor de rótulo contendo valores de 1 ou -1. Ela é principalmente usada em problemas envolvendo embeddings não lineares e aprendizagem semi-supervisionada.
Perda de Classificação com Margem
A perda de classificação com margem é uma das perdas de classificação que tem o objetivo principal de medir a distância relativa entre um conjunto de entradas em um conjunto de dados. A função de perda de classificação com margem recebe dois inputs e uma etiqueta que contém apenas 1 ou -1. Se a etiqueta for 1, então se assume que o primeiro input deve ter um ranking superior ao segundo input e, se a etiqueta for -1, se assume que o segundo input deve ter um ranking superior ao primeiro input. Essa relação é mostrada pela equação e pelo código abaixo.
Perda de Margem de Tripleta
Este critério mede a similaridade entre pontos de dados usando triplas de amostras de dados de treinamento. As triplas envolvidas são uma amostra de ancora, uma amostra positiva e uma amostra negativa. O objetivo é 1) minimizar a distância entre a amostra positiva e a ancora e 2) garantir que a distância entre a ancora e a amostra negativa seja maior do que a soma da margem e da distância entre a amostra positiva e a ancora. Normalmente, a amostra positiva pertence à mesma classe da ancora, mas a amostra negativa não. Portanto, usando esta função de perda, nós buscamos usar a perda de margem de tripleta para prever um valor de similaridade alta entre a ancora e a amostra positiva e um valor de similaridade baixo entre a ancora e a amostra negativa.
Perda de Embedding de Cosseno
A perda de embedding de cosseno mede a perda dada entradas x1, x2, e uma matriz de rótulo y contendo valores 1 ou -1. Ela é usada para medir o grau de similaridade ou dissimilaridade entre duas entradas.
O critério mede a similaridade calculando a distância cosseno entre os dois pontos de dados no espaço. A distância cosseno está relacionada à ángulo entre os dois pontos, o que significa que quanto menor o ângulo, mais próximos as entradas estão e portanto, mais semelhantes elas são.
Perda de Divergência de Kullback-Leibler
Dada duas distribuições, P e Q, a perda de divergência de Kullback-Leibler (KL) mede quanto informação é perdida quando P (suposto ser a distribuição verdadeira) é substituído por Q. Medindo quanto informação é perdida quando usamos Q para aproximar P, conseguimos obter a similaridade entre P e Q e, portanto, guiar nosso algoritmo a produzir uma distribuição muito próxima da distribuição verdadeira, P. A perda de informação quando Q é usada para aproximar P não é a mesma quando P é usada para aproximar Q, portanto, a divergência KL não é simétrica.
Criando Uma Função de Perda Personalizada
O PyTorch fornece-nos duas maneiras populares para construir nossa própria função de perda para nosso problema; elas são, respectivamente, usando uma implementação de classe e usando uma implementação de função. Vamos ver como podemos implementar ambos os métodos começando pela implementação de função.
Este é sem dúvida o modo mais simples de escrever sua própria função de perda personalizada. É tão fácil quanto criar uma função, passando os inputs necessários e outros parâmetros, executando alguma operação usando o core API ou o Functional API de PyTorch, e retornando um valor. Vamos ver uma demonstração com a função de perda de erro quadrático médio personalizada.
No código acima, definimos uma função de perda personalizada para calcular o erro quadrático médio dado um tensor de predição e um tensor de alvo
Nós podemos calcular a perda usando nossa função de perda personalizada e a função de perda MSE do PyTorch para observar que obtivemos os mesmos resultados.
Perda Personalizada com Classes em Python
Esta abordagem é provavelmente a maneira padrão e recomendada de definir perdas personalizadas em PyTorch. A função de perda é criada como um nó no grafo de rede neural por subclasse do módulo nn. Isso significa que nossa função de perda personalizada é exatamente o mesmo que uma camada de PyTorch, do mesmo modo que uma camada de convolução é. Vamos ver uma demonstração de como isso funciona com uma perda MSE personalizada.
Pensamentos finais
Nós discutimos muito sobre as funções de perda disponíveis em PyTorch e também mergulhamos fundo nas operações internas de quase todas estas funções de perda. Escolher a função de perda certa para um problema particular pode ser uma tarefa abrumadora. Espero que este tutorial, juntamente com a documentação oficial do PyTorch, sirva de guia quando tentando entender qual função de perda se adapta bem ao seu problema.
Source:
https://www.digitalocean.com/community/tutorials/pytorch-loss-functions