with raspberry machine learning instalar for como classifier python machine-learning tensorflow deep-learning

python - raspberry - Datos no balanceados y entropía cruzada ponderada



tensorflow mnist (2)

Estoy tratando de entrenar una red con datos no balanceados. Tengo A (198 muestras), B (436 muestras), C (710 muestras), D (272 muestras) y he leído sobre "weighted_cross_entropy_with_logits", pero todos los ejemplos que encontré son para clasificación binaria, así que no soy muy confía en cómo establecer esos pesos.

Muestras totales: 1616

A_weight: 198/1616 = 0.12?

La idea detrás, si entendí, es penalizar los errores de la clase mayoritaria y valorar más positivamente los golpes en la minoría, ¿verdad?

Mi pieza de código:

weights = tf.constant([0.12, 0.26, 0.43, 0.17]) cost = tf.reduce_mean(tf.nn.weighted_cross_entropy_with_logits(logits=pred, targets=y, pos_weight=weights))

He leído este y otros ejemplos con clasificación binaria, pero aún no está muy claro.

Gracias por adelantado.


Tenga en cuenta que weighted_cross_entropy_with_logits es la variante ponderada de sigmoid_cross_entropy_with_logits . La entropía cruzada sigmoidea se usa típicamente para la clasificación binaria . Sí, puede manejar múltiples etiquetas, pero la entropía cruzada sigmoidea básicamente toma una decisión (binaria) sobre cada una de ellas; por ejemplo, para una red de reconocimiento facial, esas etiquetas (no mutuamente excluyentes) podrían ser " ¿El sujeto usa anteojos? "," ¿El sujeto es femenino? ", Etc.

En las clasificaciones binarias, cada canal de salida corresponde a una decisión binaria (suave). Por lo tanto, la ponderación debe ocurrir dentro del cálculo de la pérdida. Esto es lo que hace weighted_cross_entropy_with_logits , al ponderar un término de la entropía cruzada sobre el otro.

En la clasificación multicabel mutuamente excluyente, utilizamos softmax_cross_entropy_with_logits , que se comporta de manera diferente: cada canal de salida corresponde a la puntuación de un candidato de clase. La decisión viene después , comparando las salidas respectivas de cada canal.

Por lo tanto, ponderar antes de la decisión final es una simple cuestión de modificar los puntajes antes de compararlos, generalmente por multiplicación con pesas. Por ejemplo, para una tarea de clasificación ternaria,

# your class weights class_weights = tf.constant([[1.0, 2.0, 3.0]]) # deduce weights for batch samples based on their true label weights = tf.reduce_sum(class_weights * onehot_labels, axis=1) # compute your (unweighted) softmax cross entropy loss unweighted_losses = tf.nn.softmax_cross_entropy_with_logits(onehot_labels, logits) # apply the weights, relying on broadcasting of the multiplication weighted_losses = unweighted_losses * weights # reduce the result to get your final loss loss = tf.reduce_mean(weighted_losses)

También puede confiar en tf.losses.softmax_cross_entropy para manejar los últimos tres pasos.

En su caso, donde necesita abordar el desequilibrio de datos, los pesos de clase podrían ser inversamente proporcionales a su frecuencia en los datos de su tren. También tiene sentido normalizarlos para que sumen uno o el número de clases.

Tenga en cuenta que en lo anterior, penalizamos la pérdida en función de la etiqueta real de las muestras. También podríamos haber penalizado la pérdida en función de las etiquetas estimadas simplemente definiendo

weights = class_weights

y el resto del código no necesita cambiar gracias a la transmisión de magia.

En el caso general, querrá pesos que dependan del tipo de error que cometa. En otras palabras, para cada par de etiquetas X e Y , puede elegir cómo penalizar la elección de la etiqueta X cuando la etiqueta verdadera es Y (num_samples, num_classes) con una matriz de peso anterior completa, lo que da como resultado que los weights anteriores sean un tensor completo (num_samples, num_classes) . Esto va un poco más allá de lo que desea, pero podría ser útil saber que solo su definición del tensor de peso debe cambiar en el código anterior.


Vea esta respuesta para una solución alternativa que funciona con sparse_softmax_cross_entropy:

import tensorflow as tf import numpy as np np.random.seed(123) sess = tf.InteractiveSession() # let''s say we have the logits and labels of a batch of size 6 with 5 classes logits = tf.constant(np.random.randint(0, 10, 30).reshape(6, 5), dtype=tf.float32) labels = tf.constant(np.random.randint(0, 5, 6), dtype=tf.int32) # specify some class weightings class_weights = tf.constant([0.3, 0.1, 0.2, 0.3, 0.1]) # specify the weights for each sample in the batch (without having to compute the onehot label matrix) weights = tf.gather(class_weights, labels) # compute the loss tf.losses.sparse_softmax_cross_entropy(labels, logits, weights).eval()