从Keras功能模型获取类标签


76

我在Keras中有一个功能模型(来自repo示例的Resnet50)。我使用ImageDataGeneratorflow_from_directory数据对其进行了训练,并将模型保存到.h5文件中。当我打电话时,model.predict我得到了一系列的类概率。但是我想将它们与类标签相关联(在我的情况下-文件夹名称)。我怎样才能得到它们?我发现可以使用model.predict_classesand model.predict_proba,但是我在Functional模型中没有这些功能,仅在Sequential中。

Answers:


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

这里的建议。


20
这给了我偏移量,但是我已经有办法弄清楚了……我如何获得标签名称?
Trejkaz

10
Keras按字母顺序对标签(火车目录中文件夹的名称)进行排序。如果您有一个名为的标签列表labels,则预计的标签名称将为:predicted_label = sorted(labels)[y_classes]
Guillaume18

1
您还可以调用model.predict_classes以检索多类输出向量中的最高概率类
bibzzzz

1
嘿,@纪尧姆(Jaillaume),能否请我指向alphabetical ordering提及此问题的文档?这是非常关键的信息,我似乎在任何地方都找不到。谢谢
ameet chaubal

1
nm,directory_iterator.pykeras_preprocessing代码中找到它,`classes = [] for sorted(os.listdir(directory))中的子目录:if os.path.isdir(os.path.join(directory,subdir)):classes.append (subdir)`
ameet chaubal

46

当使用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函数获得的字典相同的字典。

希望这可以帮助!


8
在我的解释中,这回答了实际的问题-获得课程标签
CSquare,

4
我同意,我认为这应该是公认的答案。
令人毛骨悚然的

2
保存了我的一天,<3
罗希特·斯瓦米

14

更新:这对于较新的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


3
当前,np.utils.py的代码(请参见github.com/fchollet/keras/blob/master/keras/utils/np_utils.py)没有probas_to_classes方法。他们是否将其更改为其他功能?请帮我。
noobalert

1
我有与@noobalert提到的相同的问题,它没有该功能。
斯蒂芬·约翰逊

8
使用y_classes = y_proba.argmax(axis=-1)代替
扎克-

3
AttributeError:模块“ keras”没有属性“ np_utils” –JürgenK
.

@Zach为什么轴= -1而不是1?
WaterRocket8236 '18

6

除了@Emilia Apostolova答案以外,还可以获取地面真相标签,

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

只是打电话

y_true_labels = generator.classes

1
这似乎没有提供OP所要求的标签名称。
Moondra '18年

就像我说的那样,它是对@Emilia Apostolova答案的补充,除了她说的以外,还可以使用来获得标签名称map。特别是我用它来制作混淆矩阵。当我发布此帖子时,我没有声誉在她的答案中发表评论,因为我在这里发布了。
Hemerson Tacon '18

2

您必须使用您拥有的标签索引,这是我进行文本分类的方法:

# 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

2

可以直接在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并用于在云中提供服务。


1

要使用映射预测的类和文件名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):
    ...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.