Breno

A função de perda com a verossimilhança

O que seria uma função de perda?

Seria uma função matemática que busca comparar o desempenho do modelo.

Lembremos que modelo seria a entidade de IA que realiza alguma tarefa.

A função de perda que iremos considerar aqui será o negativo do logaritmo da verossimilhança.

Então, primeiro, temos que entender o que seria a verossimilhança.

Com código, isso fica mais simples e já praticamos e manipulamos os dados, o que ajuda na compreensão.

Bom, primeiro, importemos a biblioteca do PyTorch.

import torch

A tarefa que consideramos aqui seria a predição do próximo caractere dado um caractere atual.

Então, consideremos que temos uma matriz com as probabilidades de cada par.

A matriz seria uma grade, ou pode ser pensada como uma tabela, onde cada célula indica a combinação de dois caracteres.

Por exemplo, para o nome Filipe teríamos os seguintes pares.

.F, Fi, il, li, ip, pe, e.

Esse ponto seria um caractere a mais para indicar o início de uma palavra e o final de uma palavra.

Na matriz, ou grade, ou tabela, checaríamos então os valores de cada par.

Cada valor desse seria a probabilidade do par.

No código seria simplesmente acessarmos o par pelos índices da matriz P.

prob = P[ix1, ix2]

O P seria a matriz, o ix1 seria o índice do primeiro caractere, do caractere atual, e o ix2 seria o índice do próximo caractere.

Quando multiplicamos todos os valores de todos os pares temos a verossimilhança da palavra.

Tem um detalhe importante.

A multiplicação de probabilidades daria um produto pequeno. Então, consideramos o log e sua propriedade para que então possamos calcular com soma.

log(a * b * c) = log(a) + log(b) + log(c).

No código, o PyTorch já nos dá a implementação. Ficaria então do seguinte modo.

log_prob = torch.log(prob)

E então podemos somar os valores porque estamos usando log.

log_likelihood += log_prob

A variável log_likelihood foi definida no início e ela vai somar todos os pares para todas as palavras.

Assim temos a verossimilhança que usaremos como métrica para medir o desempenho do modelo.

Mas, ainda temos mais alguns detalhes.

Que valores a verossimilhança pode assumir?

Ela pega dos valores negativos a zero. O máximo que ela pode assumir seria zero.

Então, com probabilidades altas, irá para 0.

Com probabilidades baixas, irá mais negativo.

A semântica da função de perda não gosta disso.

A semântica da função de perda indica que, quanto menor, melhor, porque está se tentando minimizá-la. Ou seja, queremos diminuir a distinção entre a resposta correta dos dados e a predição do modelo.

Assim, se considera o negativo desse valor da verossimilhança.

E, por fim, consideramos a média para não dar um valor muito grande apenas por ter muitas palavras, por exemplo.

Enfim, fica-se então do seguinte jeito.

log_likelihood = 0.0
# início do loop para todas as palavras e loop sobre todos os pares de caracteres de cada palavra.
prob = P[ix1, ix2]
log_prob = torch.log(prob)
log_likelihood += log_prob
n += 1
# fim do loop.
nll = -log_likelihood
print(f"loss {nll/n}.") # função de perda seria a nll normalizada.

Bom, com isso, aprendemos sobre essa etapa tão importante que usa-se para o aprendizado do modelo.