Intenta interpretar el código de forma correcta antes de utilizarlo a tu trabajo y si tdeseas aportar algo puedes dejarlo en los comentarios.
Solución:
Respuesta corta: es no.
Para ver eso, simplemente intente calcular la precisión "a mano", y verá que es diferente a la reportada por Keras con el model.evaluate
método:
# Keras reported accuracy:
score = model.evaluate(x_test, y_test, verbose=0)
score[1]
# 0.99794011611938471
# Actual accuracy calculated manually:
import numpy as np
y_pred = model.predict(x_test)
acc = sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000
acc
# 0.98999999999999999
la razón por la que parece ser así es un problema bastante sutil sobre cómo Keras realmente suposiciones qué precisión usar, dependiendo de la función de pérdida que haya seleccionado, cuando incluye simplemente metrics=['accuracy']
en la compilación de su modelo.
Si revisas el código fuente, Keras no define una única métrica de precisión, sino varias diferentes, entre ellas binary_accuracy
y categorical_accuracy
. Lo que sucede bajo el capó es que, dado que ha seleccionado la entropía cruzada binaria como su función de pérdida y no ha especificado una métrica de precisión particular, Keras (erróneamente...) infiere que está interesado en la binary_accuracy
y esto es lo que devuelve.
Para evitar eso, es decir, usar la entropía cruzada binaria como su función de pérdida (no hay nada de malo en esto, en principio) sin dejar de obtener el categórico precisión requerida por el problema en cuestión (es decir, clasificación MNIST), debe solicitar explícitamente categorical_accuracy
en la compilación del modelo de la siguiente manera:
from keras.metrics import categorical_accuracy
model.compile(loss='binary_crossentropy', optimizer='adamax', metrics=[categorical_accuracy])
Y después de entrenar, puntuar y predecir el conjunto de pruebas como muestro arriba, las dos métricas ahora son las mismas, como deberían ser:
sum([np.argmax(y_test[i])==np.argmax(y_pred[i]) for i in range(10000)])/10000 == score[1]
# True
(HT a esta gran respuesta a un problema similar, que me ayudó a entender el problema...)
ACTUALIZAR: Después de mi publicación, descubrí que este problema ya se había identificado en esta respuesta.
En primer lugar, binary_crossentropy no es cuando hay dos clases.
El nombre "binario" se debe a que está adaptado para la salida binaria, y cada número de softmax tiene como objetivo ser 0 o 1. Aquí, verifica cada número de la salida.
No explica su resultado, ya que categorical_entropy explota el hecho de que es un problema de clasificación.
¿Está seguro de que cuando lee sus datos hay una y solo una clase por muestra? Es la única explicación que puedo dar.
Aquí tienes las comentarios y calificaciones
Recuerda que tienes permiso de añadir una puntuación justa si te fue de ayuda.