J'ai un problème de classification avec des données très déséquilibrées. J'ai lu que le suréchantillonnage et le sous-échantillonnage ainsi que la modification du coût des extrants catégoriels sous-représentés conduiront à un meilleur ajustement. Avant cela, tensorflow catégoriserait chaque entrée comme le groupe majoritaire (et gagnerait plus de 90% de précision, aussi insignifiant que cela soit).
J'ai remarqué que le logarithme du pourcentage inverse de chaque groupe a fait le meilleur multiplicateur que j'ai essayé. Existe-t-il une manipulation plus standard pour la fonction de coût? Est-ce mis en œuvre correctement?
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)
Réponses:
Cela semble être une bonne solution pour la fonction de perte. J'ai eu du succès avec une approche similaire récemment, mais je pense que vous voudriez réorganiser où vous vous multipliez dans le
class_weight
.En y réfléchissant logiquement, le
class_weight
sera une constante par rapport à la sortie, donc il sera transporté et appliqué au gradient de la même manière qu'il est appliqué à la fonction de coût. Mais il y a un problème.La façon dont vous l'avez,
class_weight
affecterait la valeur de prédiction. Mais vous voulez qu'il affecte l'échelle du dégradé. Si je ne me trompe pas, je pense que vous voudriez inverser l'ordre des opérations:Je serais très intéressé de savoir comment cela fonctionne par rapport au simple suréchantillonnage de la classe sous-représentée, ce qui est plus typique. Donc, si vous obtenez un aperçu, postez-en à ce sujet! :)
Fait intéressant, j'ai récemment utilisé avec succès une technique très similaire dans un autre domaine problématique (ce qui m'a amené à ce poste):
Apprentissage multitâche, recherche d'une fonction de perte qui "ignore" certains échantillons
la source
Commander
tf.nn.weighted_cross_entropy_with_logits()
:Cela devrait vous permettre de faire ce que vous voulez.
la source
J'ai 2 implémentations différentes:
Lorsque le poids_classe est un espace réservé, je remplis chaque itération par lots.
Où j'utilise la fonction tensorflow implémentée mais je dois calculer les poids pour le lot. Les documents sont un peu déroutants. Il y a 2 façons de le faire avec tf.gather ou comme ceci:
ici, il y a une belle discussion à ce sujet
Et finalement, comme je ne voulais pas me marier à aucune des implémentations de façon permanente, j'ai ajouté un petit tf.case et je transmets au temps de formation la stratégie que je veux utiliser.
la source