Как Keras управляет многоколоночной классификацией?
Я не уверен, как интерпретировать поведение Keras по умолчанию в следующей ситуации:
My Y (основная правда) была создана с помощью scikit-learn MultilabelBinarizer
().
Поэтому, чтобы дать случайный пример, одна строка моего столбца y
является одним горячим кодированием как таковым:
[0,0,0,1,0,1,0,0,0,0,1]
.
Итак, у меня есть 11 классов, которые можно было бы предсказать, и более чем одно может быть истинным; следовательно, многозонный характер проблемы. Для этого конкретного образца есть три метки.
Я тренирую модель так, как я бы хотел, для многоквартирной проблемы (как обычно), и я не получаю ошибок.
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
model = Sequential()
model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))
model.add(Dropout(0.1))
model.add(Dense(600, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(y_train.shape[1], activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy',])
model.fit(X_train, y_train,epochs=5,batch_size=2000)
score = model.evaluate(X_test, y_test, batch_size=2000)
score
Что делает Keras, когда он встречает мой y_train
, и видит, что это "multi" одноразовое кодирование, что означает, что в каждой строке y_train
присутствует более одного "одного"? В принципе, Keras автоматически выполняет многосегментную классификацию? Любые различия в интерпретации показателей оценки?
Ответы
Ответ 1
Короче
Не используйте softmax
.
Используйте sigmoid
для активации вашего выходного слоя.
Используйте binary_crossentropy
для функции потерь.
Используйте predict
для оценки.
Почему
В softmax
при увеличении оценки для одной метки все остальные опускаются (это распределение вероятности). Вы не хотите этого, когда у вас есть несколько ярлыков.
Полный код
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD
model = Sequential()
model.add(Dense(5000, activation='relu', input_dim=X_train.shape[1]))
model.add(Dropout(0.1))
model.add(Dense(600, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(y_train.shape[1], activation='sigmoid'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy',
optimizer=sgd)
model.fit(X_train, y_train, epochs=5, batch_size=2000)
preds = model.predict(X_test)
preds[preds>=0.5] = 1
preds[preds<0.5] = 0
# score = compare preds and y_test