J'ai un modèle fonctionnel dans Keras (Resnet50 à partir d'exemples de pension). Je l'ai entraîné avec les données ImageDataGenerator
et flow_from_directory
et ai enregistré le modèle dans le fichier .h5
. Lorsque j'appelle model.predict
, je reçois un tableau de probabilités de classe. Mais je veux les associer à des étiquettes de classe (dans mon cas - les noms de dossiers). Comment puis-je les obtenir? J'ai découvert que je pouvais utiliser model.predict_classes
et model.predict_proba
, mais je n'ai pas ces fonctions dans le modèle fonctionnel, uniquement dans le séquentiel.
y_prob = model.predict(x)
y_classes = y_prob.argmax(axis=-1)
Comme suggéré ici .
Quand on utilise flow_from_directory, le problème est de savoir comment interpréter les résultats de probabilité. Comme dans, la manière de mapper les sorties de probabilité et les étiquettes de classe, comme comment flow_from_directory crée des vecteurs one-hot, n'est pas connue auparavant.
Nous pouvons obtenir un dictionnaire qui mappe les étiquettes de classe sur l'index du vecteur de prédiction que nous obtenons en sortie lorsque nous utilisons
generator= train_datagen.flow_from_directory("train", batch_size=batch_size)
label_map = (generator.class_indices)
La variable label_map est un dictionnaire comme celui-ci
{'class_14': 5, 'class_10': 1, 'class_11': 2, 'class_12': 3, 'class_13': 4, 'class_2': 6, 'class_3': 7, 'class_1': 0, 'class_6': 10, 'class_7': 11, 'class_4': 8, 'class_5': 9, 'class_8': 12, 'class_9': 13}
On peut alors déduire la relation entre les scores de probabilité et les noms de classe.
Fondamentalement, vous pouvez créer ce dictionnaire avec ce code.
from glob import glob
class_names = glob("*") # Reads all the folders in which images are present
class_names = sorted(class_names) # Sorting them
name_id_map = dict(Zip(class_names, range(len(class_names))))
La variable name_id_map dans le code ci-dessus contient également le même dictionnaire que celui obtenu à partir de la fonction class_indices de flow_from_directory.
J'espère que cela t'aides!
UPDATE: Ceci n'est plus valable pour les nouvelles versions de Keras. Veuillez utiliser argmax()
comme dans la réponse d'Emilia Apostolova.
Les modèles d'API fonctionnels ont uniquement la fonction predict()
qui, pour la classification, renverrait les probabilités de classe. Vous pouvez ensuite sélectionner les classes les plus probables à l'aide de la fonction utilitaire probas_to_classes()
. Exemple:
y_proba = model.predict(x)
y_classes = keras.np_utils.probas_to_classes(y_proba)
Ceci équivaut à model.predict_classes(x)
sur le modèle séquentiel.
La raison en est que l'API fonctionnelle prend en charge une classe de tâches plus générale dans laquelle predict_classes()
n'aurait aucun sens.
Plus d'infos: https://github.com/fchollet/keras/issues/2524
En plus de @Emilia Apostolova répondre pour obtenir les étiquettes de vérité au sol de
generator = train_datagen.flow_from_directory("train", batch_size=batch_size)
il suffit d'appeler
y_true_labels = generator.classes
Vous devez utiliser l'index des étiquettes que vous avez, voici ce que je fais pour la classification du texte:
# data labels = [1, 2, 1...]
labels_index = { "website" : 0, "money" : 1 ....}
# to feed model
label_categories = to_categorical(np.asarray(labels))
Ensuite, pour les prédictions:
texts = ["hello, rejoins moi sur skype", "bonjour comment ça va ?", "tu me donnes de l'argent"]
sequences = tokenizer.texts_to_sequences(texts)
data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)
predictions = model.predict(data)
t = 0
for text in texts:
i = 0
print("Prediction for \"%s\": " % (text))
for label in labels_index:
print("\t%s ==> %f" % (label, predictions[t][i]))
i = i + 1
t = t + 1
Cela donne:
Prediction for "hello, rejoins moi sur skype":
website ==> 0.759483
money ==> 0.037091
under ==> 0.010587
camsite ==> 0.114436
email ==> 0.075975
abuse ==> 0.002428
Prediction for "bonjour comment ça va ?":
website ==> 0.433079
money ==> 0.084878
under ==> 0.048375
camsite ==> 0.036674
email ==> 0.369197
abuse ==> 0.027798
Prediction for "tu me donnes de l'argent":
website ==> 0.006223
money ==> 0.095308
under ==> 0.003586
camsite ==> 0.003115
email ==> 0.884112
abuse ==> 0.007655
Il est possible de sauvegarder directement une "liste" d'étiquettes dans le modèle keras. Ainsi, l'utilisateur qui utilise le modèle pour les prédictions et ne dispose d'aucune autre source d'informations peut effectuer la recherche lui-même. Voici un exemple factice de la façon dont on peut effectuer une "injection" d'étiquettes
# assume we get labels as list
labels = ["cat","dog","horse","tomato"]
# here we start building our model with input image 299x299 and one output layer
xx = Input(shape=(299,299,3))
flat = Flatten()(xx)
output = Dense(shape=(4))(flat)
# here we perform injection of labels
tf_labels = tf.constant([labels],dtype="string")
tf_labels = tf.tile(labels,[tf.shape(xx)[0],1])
output_labels = Lambda(lambda x: tf_labels,name="label_injection")(xx)
#and finaly creating a model
model=tf.keras.Model(xx,[output,output_labels])
Lorsqu'il est utilisé pour la prédiction, ce modèle renvoie le tenseur des scores et le tensot des étiquettes de chaîne. Un modèle comme celui-ci peut être enregistré en h5. Dans ce cas, le fichier contient les étiquettes. Ce modèle peut également être exporté vers saved_model et utilisé pour servir dans le nuage.