Ответ 1
y_prob = model.predict(x)
y_classes = y_prob.argmax(axis=-1)
Как предложено здесь.
У меня есть функциональная модель в Keras (Resnet50 из примеров репо). Я обучил его с ImageDataGenerator
данных ImageDataGenerator
и flow_from_directory
и сохранил модель в файле .h5
. Когда я вызываю model.predict
я получаю массив вероятностей класса. Но я хочу связать их с метками классов (в моем случае - именами папок). Как я могу их получить? Я обнаружил, что могу использовать model.predict_classes
и model.predict_proba
, но у меня нет этих функций в функциональной модели, только в Sequential.
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 в приведенном выше коде также содержит тот же словарь, что и тот, который получен из функции class_indices потока_from_directory.
Надеюсь это поможет!
UPDATE: это больше не действует для новых версий Keras. Используйте argmax()
как в ответе Эмилии Апостоловой.
Функциональные API-модели имеют только функцию predict()
которая для классификации вернет вероятности класса. Затем вы можете выбрать наиболее вероятные классы, используя probas_to_classes()
утилиты 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
Можно напрямую сохранить "список" меток в модели керас. Таким образом, пользователь, который использует модель для предсказаний и не имеет никаких других источников информации, может выполнить поиск самостоятельно. Вот фиктивный пример того, как можно выполнить "инъекцию" меток
# 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. В этом случае файл содержит метки. Эту модель также можно экспортировать в save_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):
...