Позвольте мне привести пример того, чего я пытаюсь достичь с помощью набора данных Iris. Я не только хочу предсказать класс цветов, я также хочу знать, какой цветок наиболее похож.
К набору данных я добавил индекс для каждого цветка, начиная с 0 до 149. Из выходных данных мне нужен прогнозируемый класс и индекс ближайшего члена этого класса.
Вот модель, которую я пытался использовать см. Рисунок
Вот код, который я использовал:
Загрузка данных
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from keras.utils import to_categorical
from keras.layers import Input
from keras.models import Model
from keras.optimizers import Adam
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
iris = load_iris()
data = iris.data
target = iris.target.reshape(150,1)
indexes = np.arange(target.shape[0]).reshape(150,1)
table = np.concatenate([indexes,iris.target.reshape(150,1)], axis = 1)
table = pd.DataFrame(table, columns=['index', 'real_class'])
y_index = to_categorical( indexes )
target = to_categorical( target )
Разделение на данные тренировок и испытаний
X_train, X_test, Y_train, Y_test, Y_train_index, Y_test_index = train_test_split( data, target, y_index, test_size=0.5, shuffle = True)
Создание модели Keras
main_input = Input(shape=(data.shape[1],), name='main_input')
x = Dense(12, activation='relu')(main_input)
x = Dense(6, activation='relu')(x)
main_output = Dense(target.shape[1], activation='softmax', name='main_output')(x)
auxiliary_output = Dense(Y_train_index.shape[1], activation='softmax', name='index_of_claim')(x)
model = Model(inputs=main_input, outputs=[main_output,auxiliary_output])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy'])
model.fit(X_train, [Y_train,Y_train_index], validation_data=(X_test, [Y_test,Y_test_index]), epochs=100, batch_size=50)
Прогнозирование как класса, так и индекса
proba,proba_index = model.predict([X_test])
predictions = np.concatenate([np.argmax(proba_index, axis = 1).reshape(75,1), np.argmax(proba, axis = 1).reshape(75,1)], axis = 1)
predictions = pd.DataFrame(predictions, columns=['index', 'predicted_class'])
fact_table = pd.merge(predictions, table, on='index', how='left')
Проверка соответствия классов индексов реальным классам
fact_table['predicted_class'].equals(fact_table['real_class'])
Это всегда дает Ложь
Как я могу изменить модель, чтобы всегда получать прогнозируемые классы в соответствии с классами прогнозируемых индексов?