Introdução
As funções de perda são fundamentais na treinamento de modelos de ML, e, na maioria dos projetos de aprendizagem de máquina, não há como guiar o modelo para 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 quão bem um modelo está sendo feito em algum conjunto de dados. Sabendo quão bem um modelo está sendo feito 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 de 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 entendimento de redes neurais. Ao nível superior, as redes neurais são compostas de 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 (variantes do descida de gradiente), funções de perda, etc.
Ainda assim, a familiaridade com a sintaxe do Python e com a biblioteca PyTorch é essencial para entender os exemplos de código apresentados nesta publicação.
Neste artigo, vamos explorar diferentes funções de perda que fazem parte do módulo PyTorch nn. Vamos então mergulhar mais a 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 personalizada.
Com um entendimento de nível superior 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?
Como dissemos anteriormente, as funções de perda nos diz quanto bem um modelo está num determinado conjunto de dados. Tecnicamente, elas fazem isso medindo quão próximo o valor predito é 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 do 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 acurácia e as pontuações F. O importante das funções de perda é realizado principalmente durante o treinamento, onde nudgamos os pesos do nosso modelo na direção que minimiza a perda. Fazendo isso, aumentamos a probabilidade do 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 estavel durante o treinamento.
Às vezes, 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 do PyTorch mais tarde, mas antes disso, vamos ver como usamos funções de perda no mundo do PyTorch.
Funções de Perda no PyTorch
O PyTorch vem com muitas funções de perda canônicas com padrões de design simples que permitem que os desenvolvedores iteriem rapidamente sobre essas diferentes funções de perda durante o treinamento. Todas as funções de perda do PyTorch estão empacotadas 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 simples quanto adicionar uma linha de código. Vamos ver como adicionar uma função de perda de erro quadrático médio no PyTorch.
A função retornada acima pode ser usada para calcular quanto uma previsão está 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 PyTorch oferece.
Quais funções de perda estão disponíveis em PyTorch?
Muitas destas funções de perda que vem com PyTorch são amplamente categorizadas em 3 grupos – perda de regressão, perda de classificação e perda de classificação.
Perda de regressão são principalmente preocupadas com 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.
Funções de perda de classificação lidam com valores discretos, como a tarefa de classificar um objeto como caixa, caneta ou garrafa.
Perda de classificação prevê as distâncias relativas entre valores. Um exemplo disto seria a verificação facial, onde queremos saber quais imagens de faces pertencem a uma determinada face e consegue fazer isso classificando quais faces sim e não sim pertencem ao original dono da face através do grau de aproximação relativa à face alvo.
Função de perda L1 / Erro Absoluto Médio
A função de perda L1 calcula a média aritmética do erro absoluto entre cada valor no tensor predito e o valor alvo. Primeiro, ela calcula a diferença absoluta entre cada valor no tensor predito e o valor alvo, e computa a soma de todos os valores retornados de cada cálculo de diferença absoluta. Finalmente, ela calcula a média desta soma de valores para obter o erro absoluto médio (MAE). A função de perda L1 é muito resistente ao tratamento de ruído.
O valor único retornado é a perda calculada entre dois tensores com dimensão 3×5.
Erro Quadrático Médio
A erro quadrático médio partilha algumas 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 o erro médio absoluto, ele calcula a diferença quadrada 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. O MSE é considerado menos resistente em lidar com valores atípicos e ruído do que a MAE, no entanto.
Perda de Cross-Entropy
A 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 conjunto determinado de variáveis aleatórias. Normalmente, quando usamos a 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 se parece com isto:
]
No módulo nn do PyTorch, a perda de cross-entropia 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 na saída imprimida é uma perda NLL. Isso na verdade revela que a perda de cross-entropia combina a perda NLL por trás de uma camada log-softmax.
Perda de Negativo Log-Likelihood (NLL)
A função de perda NLL funciona muito semelhante à função de perda de cross-entropia. A perda de cross-entropia combina uma camada log-softmax e a perda NLL para obter o valor da perda de cross-entropia. Isso significa que a perda NLL pode ser usada para obter o valor de perda de cross-entropia colocando na camada de saída do neural network 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 normalmente binárias, portanto, o 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 usando 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, uma perda de cross-entropia binária é normalmente output com uma camada de sigmóide para garantir que o output esteja entre 0 e 1. Uma perda de cross-entropia binária com logits combina estas duas camadas em apenas uma camada. De acordo com a documentação de PyTorch, esta é uma versão mais numéricamente estável, pois ela usa a técnica 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 é inferior a 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 o gradiente em cada valor de perda varia e pode ser derivado em todo o lado. Além disso, conforme o valor de perda diminui, o gradiente diminui, o que é conveniente durante o descida de gradiente. No entanto, para valores de perda muito altos, o gradiente explode, portanto o critério para passar 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 explosão potencial de gradiente é eliminada.
Perda de Embedimento Hinge
A perda de embedimento hinge é usada principalmente em tarefas de aprendizado semi-supervisionado para medir a similaridade entre dois entradas. Ela é usada quando existe 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 aprendizado semi-supervisionado.
Perda de Classificação por Margem
A perda de classificação por margem é uma das perdas de classificação cujo objetivo principal, ao contrário de outras funções de perda, é medir a distância relativa entre um conjunto de entradas em um conjunto de dados. A função de perda de classificação por 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 melhor ranking do que o segundo input e, se a etiqueta for -1, se assume que o segundo input deve ter um melhor ranking do que o primeiro input. Esta relação é mostrada pela equação e pelo código abaixo.
Perda de Margem de Tripla
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) obter a distância entre a amostra positiva e a ancora o mínimo possível e 2) obter a distância entre a ancora e a amostra negativa ser maior que a soma da margem e da distância entre a amostra positiva e a ancora. Normalmente, a amostra positiva pertence à mesma classe que a ancora, mas a amostra negativa não. Portanto, usando esta função de perda, nós visamos usar a perda de margem de tripla para prever um valor alto de similaridade entre a ancora e a amostra positiva e um valor baixo de similaridade entre a ancora e a amostra negativa.
Perda de Embedding por Cosseno
A perda de embedução 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 semelhança ou dissimilaridade entre duas entradas.
O critério mede a semelhança calculando a distância cossenóide entre os dois pontos de dados no espaço. A distância cossenóide correlaciona com o â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 o nosso algoritmo para 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 nos fornece duas formas populares para construir nossa própria função de perda ajustada ao 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 a maneira mais simples de escrever sua própria função de perda personalizada. É tão fácil quanto criar uma função, passando para ela os entradas necessários e outros parâmetros, realizando alguma operação usando o core API de PyTorch ou o API Functional 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 de PyTorch para observar que obtivemos os mesmos resultados.
Custom Loss with Python Classes
Este método é provavelmente a maneira padrão e recomendada de definir perdas personalizadas em PyTorch. A função de perda é criada como um nó na gráfico 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, da mesma forma que uma camada de convolução é. Vamos ver uma demonstração de como isso funciona com uma perda MSE personalizada.
Pensamentos finais
Discutimos muito sobre as funções de perda disponíveis em PyTorch e também mergulhámos no funcionamento interno de quase todas essas funções de perda. Escolher a função de perda certa para um problema particular pode ser uma tarefa abrupta. 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