web-dev-qa-db-fra.com

Comment calculer l'incertitude de prédiction à l'aide de Keras?

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).

33
johndodo

Si vous souhaitez implémenter l'approche dropout pour mesurer l'incertitude, vous devez procéder comme suit:

  1. 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])
    
  2. 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.

23
Marcin Możejko

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.

4
Matias Valdenegro

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
2
Chexn

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 .

2
abagshaw