Eu tenho um problema de classificação com dados altamente desequilibrados. Li que a sobredimensionagem e a subamostragem, bem como a alteração do custo de resultados categóricos sub-representados, levarão a um melhor ajuste. Antes disso, o tensorflow categorizava cada entrada como o grupo majoritário (e ganha mais de 90% de precisão, por menos que seja isso).
Percebi que o log da porcentagem inversa de cada grupo foi o melhor multiplicador que tentei. Existe uma manipulação mais padrão para a função de custo? Isso foi implementado corretamente?
from collections import Counter
counts = Counter(category_train)
weightsArray =[]
for i in range(n_classes):
weightsArray.append(math.log(category_train.shape[0]/max(counts[i],1))+1)
class_weight = tf.constant(weightsArray)
weighted_logits = tf.mul(pred, class_weight)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(weighted_logits, y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
tensorflow
loss-function
Cole
fonte
fonte
Respostas:
Esta parece ser uma boa solução para a função de perda. Eu tive sucesso com uma abordagem semelhante recentemente, mas acho que você gostaria de reordenar onde você se multiplica no
class_weight
.Pensando nisso logicamente, o resultado
class_weight
será uma constante, por isso será transportado e aplicado ao gradiente da mesma maneira que está sendo aplicado à função de custo. Há um problema, entretanto.Do jeito que você tem,
class_weight
isso afetaria o valor da previsão. Mas você quer que isso afete a escala do gradiente. Se não estou errado, acho que você deseja reverter a ordem das operações:Eu ficaria muito interessado em saber como isso funciona em comparação com simplesmente exagerar a classe sub-representada, o que é mais típico. Então, se você tiver alguma ideia, poste sobre isso! :)
Curiosamente, usei com sucesso uma técnica muito semelhante em um domínio de problema diferente recentemente (o que me levou a este post):
Aprendizado multitarefa, encontrando uma função de perda que "ignora" certas amostras
fonte
Saída
tf.nn.weighted_cross_entropy_with_logits()
:Isso deve permitir que você faça o que quiser.
fonte
Eu tenho 2 implementações diferentes:
Onde class_weight é um espaço reservado, preencho a iteração em lote de everey.
Onde eu uso a função tensorflow implementada, mas preciso calcular os pesos para o lote. Os documentos são um pouco confusos. Existem 2 maneiras de fazer isso com o tf.gather ou assim:
aqui tem uma boa discussão sobre isso
E, finalmente, como não queria me casar com nenhuma das implementações, acrescentei um pouco de mala e passo o tempo de treinamento para a estratégia que quero usar.
fonte