Je voudrais calculer la certitude/confiance du modèle NN (voir Ce que mon modèle profond ne sait pas ) - lorsque NN me dit qu'une image représente "8", je voudrais savoir à quel point il est certain. Mon modèle est-il certain à 99% qu'il est "8" ou à 51% est-il "8", mais il pourrait également être "6"? Certains chiffres sont assez ambigus et je voudrais savoir pour quelles images le modèle est juste en train de "lancer une pièce".
J'ai trouvé quelques écrits théoriques à ce sujet mais j'ai du mal à mettre cela en code. Si je comprends bien, je devrais évaluer une image de test plusieurs fois tout en "tuant" différents neurones (en utilisant le décrochage) et ensuite ...?
En travaillant sur le jeu de données MNIST, j'utilise un modèle suivant:
from keras.models import Sequential
from keras.layers import Dense, Activation, Conv2D, Flatten, Dropout
model = Sequential()
model.add(Conv2D(128, kernel_size=(7, 7),
activation='relu',
input_shape=(28, 28, 1,)))
model.add(Dropout(0.20))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Dropout(0.20))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(units=10, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer='sgd',
metrics=['accuracy'])
model.fit(train_data, train_labels, batch_size=100, epochs=30, validation_data=(test_data, test_labels,))
Question: comment devrais-je prédire avec ce modèle afin d'avoir aussi sa certitude sur les prédictions? J'apprécierais un exemple pratique (de préférence à Keras, mais n'importe qui fera l'affaire).
[~ # ~] edit [~ # ~] : pour clarifier, je cherche par exemple comment obtenir la certitude en utilisant la méthode décrite par Yurin Gal ( ou une explication pourquoi une autre méthode donne de meilleurs résultats).
Si vous souhaitez implémenter l'approche dropout pour mesurer l'incertitude, vous devez procéder comme suit:
Implémentez la fonction qui s'applique abandon également pendant le temps de test:
import keras.backend as K
f = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[-1].output])
Utilisez cette fonction comme prédicteur d'incertitude, par ex. de la manière suivante:
def predict_with_uncertainty(f, x, n_iter=10):
result = numpy.zeros((n_iter,) + x.shape)
for iter in range(n_iter):
result[iter] = f(x, 1)
prediction = result.mean(axis=0)
uncertainty = result.var(axis=0)
return prediction, uncertainty
Bien sûr, vous pouvez utiliser n'importe quelle fonction différente pour calculer l'incertitude.
Votre modèle utilise une activation softmax, donc la façon la plus simple d'obtenir une sorte de mesure d'incertitude est de regarder les probabilités softmax en sortie:
probs = model.predict(some input data)[0]
Le tableau probs
sera alors un vecteur de 10 éléments de nombres dans la plage [0, 1] qui totalisent 1,0, de sorte qu'ils peuvent être interprétés comme des probabilités. Par exemple, la probabilité pour le chiffre 7 est juste probs[7]
.
Ensuite, avec ces informations, vous pouvez effectuer un post-traitement, généralement la classe prédite est celle avec la probabilité la plus élevée, mais vous pouvez également regarder la classe avec la deuxième probabilité la plus élevée, etc.
Apporté quelques modifications à la réponse la plus votée. Maintenant ça marche pour moi.
C'est une façon d'estimer l'incertitude du modèle. Pour une autre source d'incertitude, j'ai trouvé https://eng.uber.com/neural-networks-uncertainty-estimation/ utile.
f = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[-1].output])
def predict_with_uncertainty(f, x, n_iter=10):
result = []
for i in range(n_iter):
result.append(f([x, 1]))
result = np.array(result)
prediction = result.mean(axis=0)
uncertainty = result.var(axis=0)
return prediction, uncertainty
Une manière plus simple consiste à définir training=True
sur toutes les couches de décrochage que vous souhaitez également exécuter pendant l'inférence (indique essentiellement à la couche de fonctionner comme si elle était toujours en mode d'apprentissage - elle est donc toujours présente à la fois pour l'entraînement et l'inférence).
import keras
inputs = keras.Input(shape=(10,))
x = keras.layers.Dense(3)(inputs)
outputs = keras.layers.Dropout(0.5)(x, training=True)
model = keras.Model(inputs, outputs)
Le code ci-dessus provient de ce problème .