Que função de perda para tarefas de classificação multi-classe e multi-rótulo em redes neurais?

64

Estou treinando uma rede neural para classificar um conjunto de objetos em n-classes. Cada objeto pode pertencer a várias classes ao mesmo tempo (multi-classe, multi-rótulo).

Li que, para problemas com várias classes, geralmente é recomendável usar softmax e entropia cruzada categórica como a função de perda em vez de mse e entendo mais ou menos o porquê.

Para o meu problema de etiqueta múltipla, não faria sentido usar o softmax, é claro, pois cada probabilidade de classe deve ser independente da outra. Portanto, minha camada final são apenas unidades sigmóides que comprimem suas entradas em um intervalo de probabilidade de 0 a 1 para cada classe.

Agora não tenho certeza de qual função de perda devo usar para isso. Olhando para a definição de entropia cruzada categórica, acredito que não se aplicaria bem a esse problema, pois levará em conta apenas a saída de neurônios que deveria ser 1 e ignora os outros.

Parece que a entropia cruzada binária se encaixaria melhor, mas só a vejo mencionada para problemas de classificação binária com um único neurônio de saída.

Estou usando python e keras para treinamento, caso isso importe.

aKzenT
fonte
11
Eu acredito que o softmax é "unidades sigmóides que comprimem suas entradas em um intervalo de probabilidade de 0 a 1 para cada classe".
Hong Ooi
Você pode usar o softmax como sua função de perda e, em seguida, usar probabilidades para marcar vários dados.
Balboa #

Respostas:

30

Se você estiver usando o keras, basta colocar sigmoids em sua camada de saída e binary_crossentropy em sua função de custo.

Se você estiver usando o tensorflow, poderá usar sigmoid_cross_entropy_with_logits . Mas, no meu caso, essa função de perda direta não estava convergindo. Então, acabei usando perda de entropia cruzada sigmóide explícita . Você pode fazer o seu próprio neste exemplo(yln(sigmoid(logits))+(1y)ln(1sigmoid(logits)))

Sigmoide, diferentemente do softmax, não fornece distribuição de probabilidade em torno de como saída, mas probabilidades independentes.nclasses

Se em média qualquer linha tiver menos rótulos atribuídos, você poderá usar softmax_cross_entropy_with_logits porque, com essa perda enquanto as classes são mutuamente exclusivas, suas probabilidades não precisam ser. Tudo o que é necessário é que cada linha de rótulos seja uma distribuição de probabilidade válida. Caso contrário, o cálculo do gradiente estará incorreto.

Alok Nayak
fonte
Caro Alok, você pode explicar ao OP como eles usariam essa função e por que faz sentido? Como você verá no tour , as respostas apenas para links não são incentivadas no site.
Antoine Vernet
Uma breve explicação agradável pode ser visto no github keras: github.com/fchollet/keras/issues/741
Dror Hilman
11
Não é recomendável escrever sua própria função de custo ao usar entropia cruzada - isso pode estar sujeito a problemas de estabilidade numérica. Consulte github.com/tensorflow/tensorflow/issues/2462 para uma discussão.
kbrose
Uma coisa é multilabel, outra coisa é multilabel multiclass. O Sigmoid esmaga sua saída entre 0 e 1, mas o OP tem várias classes, portanto as saídas devem ser de 0 a 10. Por isso, as saídas devem parecer: [0,5,2,3,1] <--- não é isso que significa sigmoide faz.
mimoralea
devo tf.round (logits) antes de usar a função cost ou posso usar diretamente logits da camada oculta para tf.nn.sigmoid ....?
Monge
9

ATUALIZAÇÃO (18/04/18): A resposta antiga ainda se mostrou útil no meu modelo. O truque é modelar a função de partição e a distribuição separadamente, explorando assim o poder do softmax.

Considere o seu vetor de observação para conter rótulos. (1 se a amostra i contiver o rótulo m, 0 caso contrário). Portanto, o objetivo seria modelar a matriz por amostra. Portanto, o modelo avalia . Considere expandir para obter duas propriedades:ymyim=δimF(yi,xi)=logP(yi|xi)yim=ZP(ym)

  1. Função de distribuição:mP(ym)=1
  2. Função de partição: estima o número de etiquetasZ

Então é uma questão de modelar os dois separadamente. A função de distribuição é melhor modelada com uma camada softmax , e a função de partição pode ser modelada com uma unidade linear (na prática, eu a recortei como . Modelagem mais sofisticada como a unidade de Poisson provavelmente funcionaria melhor). Em seguida, você pode optar por aplicar a perda distribuída (KL na distribuição e MSE na partição) ou pode tentar a seguinte perda no produto.max(0.01,output)

Na prática, a escolha do otimizador também faz uma enorme diferença. Minha experiência com a abordagem de fatoração é que ela funciona melhor em Adadelta (o Adagrad não funciona para mim, ainda não experimentou o RMSprop, o desempenho do SGD está sujeito a parâmetros).

Comentário lateral sobre sigmóide : Eu certamente tentei sigmóide + crossentropia e não deu certo. O modelo inclinou-se a prever apenas o e não conseguiu capturar a variação na função de distribuição. (ou seja, é de alguma forma bastante útil para modelar a partição e pode haver motivos matemáticos por trás dela)Z

ATUALIZAÇÃO : (Pensamento aleatório) Parece que o uso do processo Dirichlet permitiria a incorporação de alguns itens anteriores no número de etiquetas?

ATUALIZAÇÃO : Por experimento, a divergência KL modificada ainda está inclinada a fornecer saída de classe múltipla em vez de saída de etiqueta múltipla.


(Resposta antiga)

Minha experiência com entropia sigmóide não foi muito agradável. No momento, estou usando uma divergência KL modificada. Toma a forma

Loss(P,Q)=x|P(x)Q(x)||logP(x)Q(x)|=x|(P(x)Q(x))logP(x)Q(x)|
Onde é a pseudo-distribuição alvo e é a pseudo-distribuição prevista (mas a função é realmente simétrica, portanto, na verdade não importa)P(x)Q(x)

Eles são chamados de pseudo-distribuições por não serem normalizados. Portanto, você pode ter se tiver 2 rótulos para uma amostra específica.xP(x)=2

Keras impelmentation

def abs_KL_div(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), None)
    y_pred = K.clip(y_pred, K.epsilon(), None)
    return K.sum( K.abs( (y_true- y_pred) * (K.log(y_true / y_pred))), axis=-1)
deveria ver
fonte
no meu conjunto de dados particular, adamfoi muito melhor do quermsprop
shadi
Se você usa essa perda para o treinamento, como fazê-lo na fase de teste? Use também o softmax para a previsão, mas como selecionar o limite para determinar as classes com vários rótulos?
karl_TUM 17/09
1

Ainda não usei keras. Tomando caffe, por exemplo, você pode usar SigmoidCrossEntropyLossLayerpara problemas com vários rótulos.

mintaka
fonte
11
Gostaria de explicar por que essa é uma boa abordagem?
Firebug #
0

Na verdade, no tensor-fluxo, você ainda pode usar a sigmoid_cross_entropy_meanfunção de cálculo de perda no rótulo múltiplo.

um macaco único
fonte
Dê-nos um link para a documentação
Ivelin
0

Eu sou um novato aqui, mas vou tentar tentar com esta pergunta. Eu estava pesquisando a mesma coisa que você e, finalmente, encontrei um ótimo tutorial de classificação multi-classe keras em http://machinelearningmastery.com/multi-class-classification-tutorial-keras-deep-learning-library/ .

O autor desse tutorial usa a função de perda de entropia cruzada categórica e há outro encadeamento que pode ajudá-lo a encontrar a solução @ aqui .

Willy satrio nugroho
fonte
3
Não é apenas multi-classe, é também multi-etiquetas.
Monge