从Keras函数模型中获取类标签



我有一个功能模型在Keras (Resnet50从回购的例子)。用ImageDataGeneratorflow_from_directory数据对模型进行训练,并将模型保存到.h5文件中。当我调用model.predict时,我得到一个类概率数组。但是我想将它们与类标签(在我的例子中是文件夹名称)联系起来。我怎样才能得到它们呢?我发现我可以使用model.predict_classesmodel.predict_proba,但我在功能模型中没有这些功能,只有在顺序中。

y_prob = model.predict(x) 
y_classes = y_prob.argmax(axis=-1)

当使用flow_from_directory时,问题是如何解释概率输出。例如,如何将概率输出和类标签映射为flow_from_directory如何创建单热向量,这在之前是未知的。

可以得到一个字典,它将类标签映射到使用

得到的输出预测向量的索引。
generator= train_datagen.flow_from_directory("train", batch_size=batch_size)
label_map = (generator.class_indices)

label_map变量是一个像这样的字典

{'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}

由此可以导出概率分数与类名之间的关系。

基本上,你可以通过下面的代码创建这个字典。

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

上述代码中的变量name_id_map也包含与flow_from_directory的class_indices函数获得的字典相同的字典。

希望这对你有帮助!

UPDATE:这对于较新的Keras版本不再有效。请使用argmax()作为Emilia Apostolova的答案。

功能API模型只有predict()函数,用于分类将返回类概率。然后可以使用probas_to_classes()实用程序函数选择最可能的类。例子:

y_proba = model.predict(x)
y_classes = keras.np_utils.probas_to_classes(y_proba)

这相当于顺序模型上的model.predict_classes(x)

这样做的原因是功能API支持更通用的任务类,而predict_classes()没有意义。

更多信息:https://github.com/fchollet/keras/issues/2524

除了@Emilia Apostolova的回答获得地面真理标签,从

generator = train_datagen.flow_from_directory("train", batch_size=batch_size)

就叫

y_true_labels = generator.classes

您必须使用您拥有的标签索引,下面是我为文本分类所做的:

# data labels = [1, 2, 1...]
labels_index = { "website" : 0, "money" : 1 ....} 
# to feed model
label_categories = to_categorical(np.asarray(labels)) 

然后,对于预测:

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

这给:

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

可以直接在keras模型中保存标签的"列表"。这样,使用模型进行预测且没有任何其他信息源的用户可以自己执行查找。下面是如何执行标签

"注入"的虚拟示例。
# 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])

当用于预测时,该模型返回分数张量和字符串标签张量。这样的模型可以保存到h5。在本例中,文件包含标签。该模型还可以导出到saved_model,并用于在云中提供服务。

要使用ImageDataGenerator映射预测的类和文件名,我使用:

# Data generator and prediction
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
        inputpath,
        target_size=(150, 150),
        batch_size=20,
        class_mode='categorical',
        shuffle=False)
pred = model.predict_generator(test_generator, steps=len(test_generator), verbose=0)
# Get classes by max element in np (as a list)
classes = list(np.argmax(pred, axis=1))
# Get filenames (set shuffle=false in generator is important)
filenames = test_generator.filenames

我可以循环遍历预测的类和相关的文件名:

for f in zip(classes, filenames):
    ...

附录:

图像所在的路径inputpath需要有一个实际存储图像的子目录。原因是生成器查找子目录。生成器将在预测期间给出反馈:

Found 283 images belonging to 1 classes.

1 classes部分指向 1 子目录(这来自生成器,与实际预测无关)。

所以当你的inputpath是(例如)C:/images/,实际的图像位于C:/images/temp/

在您的数据生成器上执行此魔术

y_true_labels = train_generator. class_indices
y_true_labels

它将打印(cat, dogs on my case)

{'cat': 0, 'dog': 1}

您可以使用:

model.predict(x_test).argmax(axis=-1)

相关内容

  • 没有找到相关文章

最新更新