softmax_cross_entropy losses python machine-learning tensorflow

python - losses - ¿Qué es logits, softmax y softmax_cross_entropy_with_logits?



tf losses softmax_cross_entropy (5)

Estaba revisando los documentos de la API de tensorflow here . En la documentación de tensorflow, utilizaron una palabra clave llamada logits . ¿Qué es? En muchos métodos en los documentos de API se escribe como

tf.nn.softmax(logits, name=None)

Si lo que se escribe es que esos logits son solo Tensors , ¿por qué mantener un nombre diferente como logits ?

Otra cosa es que hay dos métodos que no pude diferenciar. Ellos eran

tf.nn.softmax(logits, name=None) tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

Cuáles son las diferencias entre ellos? Los documentos no son claros para mí. Sé lo que hace tf.nn.softmax . Pero no el otro. Un ejemplo será realmente útil.


Las respuestas anteriores tienen suficiente descripción para la pregunta formulada.

Además de eso, Tensorflow ha optimizado la operación de aplicar la función de activación y luego calcular el costo utilizando su propia activación seguida de las funciones de costo. Por lo tanto, es una buena práctica usar: tf.nn.softmax_cross_entropy() sobre tf.nn.softmax(); tf.nn.cross_entropy() tf.nn.softmax(); tf.nn.cross_entropy()

Puede encontrar una diferencia notable entre ellos en un modelo de uso intensivo de recursos.


Lo que va a softmax es logit, esto es lo que J. Hinton repite en videos de curso todo el tiempo.


Logits simplemente significa que la función opera en la salida sin escala de capas anteriores y que la escala relativa para comprender las unidades es lineal. Significa, en particular, que la suma de las entradas puede no ser igual a 1, que los valores no son probabilidades (puede tener una entrada de 5).

tf.nn.softmax produce solo el resultado de aplicar la función softmax a un tensor de entrada. El softmax "aplasta" las entradas de modo que sum(input) = 1 : es una forma de normalización. La forma de salida de un softmax es la misma que la entrada: simplemente normaliza los valores. Las salidas de softmax pueden interpretarse como probabilidades.

a = tf.constant(np.array([[.1, .3, .5, .9]])) print s.run(tf.nn.softmax(a)) [[ 0.16838508 0.205666 0.25120102 0.37474789]]

En contraste, tf.nn.softmax_cross_entropy_with_logits calcula la entropía cruzada del resultado después de aplicar la función softmax (pero lo hace todo de una manera matemáticamente más cuidadosa). Es similar al resultado de:

sm = tf.nn.softmax(x) ce = cross_entropy(sm)

La entropía cruzada es una métrica de resumen: suma a través de los elementos. La salida de tf.nn.softmax_cross_entropy_with_logits en un tensor de forma [2,5] es de forma [2,1] (la primera dimensión se trata como el lote).

Si desea hacer una optimización para minimizar la entropía cruzada Y está haciendo softmaxing después de su última capa, debe usar tf.nn.softmax_cross_entropy_with_logits lugar de hacerlo usted mismo, porque cubre casos de esquina numéricamente inestables de la manera matemáticamente correcta. De lo contrario, terminarás hackeando agregando pequeños épsilons aquí y allá.

Editado el 07/02/2016: si tiene etiquetas de una sola clase, donde un objeto solo puede pertenecer a una clase, ahora puede considerar usar tf.nn.sparse_softmax_cross_entropy_with_logits para que no tenga que convertir sus etiquetas a una densa -tipo de disparo. Esta función se agregó después de la versión 0.6.0.


tf.nn.softmax calcula la propagación directa a través de una capa softmax. Lo usa durante la evaluación del modelo cuando calcula las probabilidades que genera el modelo.

tf.nn.softmax_cross_entropy_with_logits calcula el costo de una capa softmax. Solo se usa durante el entrenamiento .

Los logits son las probabilidades de registro no normalizadas que salen del modelo (los valores que salen antes de que se les aplique la normalización softmax).


Version corta:

Supongamos que tiene dos tensores, donde y_hat contiene puntuaciones calculadas para cada clase (por ejemplo, de y = W * x + b) y y_true contiene etiquetas verdaderas codificadas en caliente.

y_hat = ... # Predicted label, e.g. y = tf.matmul(X, W) + b y_true = ... # True label, one-hot encoded

Si interpreta las puntuaciones en y_hat como probabilidades de registro no normalizadas, entonces son logits .

Además, la pérdida total de entropía cruzada se calculó de esta manera:

y_hat_softmax = tf.nn.softmax(y_hat) total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

es esencialmente equivalente a la pérdida total de entropía cruzada calculada con la función softmax_cross_entropy_with_logits() :

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

Versión larga:

En la capa de salida de su red neuronal, probablemente calculará una matriz que contiene los puntajes de clase para cada una de sus instancias de entrenamiento, como a partir de un cálculo y_hat = W*x + b . Para servir de ejemplo, a continuación he creado un y_hat como una matriz de 2 x 3, donde las filas corresponden a las instancias de entrenamiento y las columnas corresponden a las clases. Así que aquí hay 2 instancias de entrenamiento y 3 clases.

import tensorflow as tf import numpy as np sess = tf.Session() # Create example y_hat. y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]])) sess.run(y_hat) # array([[ 0.5, 1.5, 0.1], # [ 2.2, 1.3, 1.7]])

Tenga en cuenta que los valores no están normalizados (es decir, las filas no suman 1). Para normalizarlos, podemos aplicar la función softmax, que interpreta la entrada como probabilidades de registro no normalizadas (también conocidas como logits ) y genera probabilidades lineales normalizadas.

y_hat_softmax = tf.nn.softmax(y_hat) sess.run(y_hat_softmax) # array([[ 0.227863 , 0.61939586, 0.15274114], # [ 0.49674623, 0.20196195, 0.30129182]])

Es importante comprender completamente lo que dice la salida softmax. A continuación, he mostrado una tabla que representa más claramente el resultado anterior. Se puede ver que, por ejemplo, la probabilidad de que la instancia de entrenamiento 1 sea "Clase 2" es 0.619. Las probabilidades de clase para cada instancia de entrenamiento están normalizadas, por lo que la suma de cada fila es 1.0.

Pr(Class 1) Pr(Class 2) Pr(Class 3) ,-------------------------------------- Training instance 1 | 0.227863 | 0.61939586 | 0.15274114 Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

Entonces, ahora tenemos probabilidades de clase para cada instancia de entrenamiento, donde podemos tomar el argumento argmax () de cada fila para generar una clasificación final. Desde arriba, podemos generar que la instancia de entrenamiento 1 pertenece a "Clase 2" y la instancia de entrenamiento 2 pertenece a "Clase 1".

¿Son correctas estas clasificaciones? Necesitamos medir contra las verdaderas etiquetas del conjunto de entrenamiento. Necesitará una matriz y_true codificada en caliente, donde nuevamente las filas son instancias de entrenamiento y las columnas son clases. A continuación, he creado un ejemplo y_true one-hot array donde la verdadera etiqueta para la instancia de entrenamiento 1 es "Clase 2" y la verdadera etiqueta para la instancia de entrenamiento 2 es "Clase 3".

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]])) sess.run(y_true) # array([[ 0., 1., 0.], # [ 0., 0., 1.]])

¿La distribución de probabilidad en y_hat_softmax cerca de la distribución de probabilidad en y_true ? Podemos usar la pérdida de entropía cruzada para medir el error.

Podemos calcular la pérdida de entropía cruzada en base a filas y ver los resultados. A continuación podemos ver que la instancia de entrenamiento 1 tiene una pérdida de 0.479, mientras que la instancia de entrenamiento 2 tiene una pérdida mayor de 1.200. Este resultado tiene sentido porque en nuestro ejemplo anterior, y_hat_softmax mostró que la mayor probabilidad de la instancia de entrenamiento 1 era para "Clase 2", que coincide con la instancia de entrenamiento 1 en y_true ; sin embargo, la predicción para la instancia de entrenamiento 2 mostró una mayor probabilidad de "Clase 1", que no coincide con la verdadera clase "Clase 3".

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]) sess.run(loss_per_instance_1) # array([ 0.4790107 , 1.19967598])

Lo que realmente queremos es la pérdida total en todas las instancias de entrenamiento. Entonces podemos calcular:

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])) sess.run(total_loss_1) # 0.83934333897877944

Usando softmax_cross_entropy_with_logits ()

En cambio, podemos calcular la pérdida total de entropía cruzada utilizando la función tf.nn.softmax_cross_entropy_with_logits() , como se muestra a continuación.

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true) sess.run(loss_per_instance_2) # array([ 0.4790107 , 1.19967598]) total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)) sess.run(total_loss_2) # 0.83934333897877922

Tenga en cuenta que total_loss_1 y total_loss_2 producen resultados esencialmente equivalentes con algunas pequeñas diferencias en los dígitos finales. Sin embargo, también podría usar el segundo enfoque: toma una línea de código menos y acumula menos error numérico porque el softmax se realiza dentro de softmax_cross_entropy_with_logits() .