Как выполнить многоклассовую классификацию с несколькими выходами с помощью lstm - PullRequest
3 голосов
/ 29 мая 2020

У меня multiclass multioutput classification (подробнее см. https://scikit-learn.org/stable/modules/multiclass.html). Другими словами, мой набор данных выглядит следующим образом.

node_name, timeseries_1, timeseries_2, label_1, label_2
node1, [1.2, ...], [1.8, ...], 0, 2
node2, [1.0, ...], [1.1, ...], 1, 1
node3, [1.9, ...], [1.2, ...], 0, 3 
...
...
...

Итак, мой label_1 может быть 0 или 1, тогда как мой label_2 может быть 0, 1 или 2.

Мой текущий код выглядит следующим образом.

def create_network():
    model = Sequential()
    model.add(LSTM(200, input_shape=(16,2)))
    model.add(Dense(100))
    model.add(Dropout(0.2))
    model.add(Dense(3, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

    return model

neural_network = KerasClassifier(build_fn=create_network, epochs=100, batch_size=100, verbose=0)

k_fold = StratifiedKFold(n_splits=10, shuffle=True, random_state=0)

scores = cross_validate(neural_network, my_features, label_data_encoded, cv=k_fold, scoring = ('accuracy', 'precision_weighted', 'recall_weighted', 'f1_weighted', 'roc_auc'))

Мои вопросы следующие.

  • Поскольку у меня две метки ( т.е. label_1 и label_2), как подогнать эти метки к модели lstm? Надо ли делать что-то вроде keras.utils.to_categorical(label_1, 2) и keras.utils.to_categorical(label_2, 3)?
  • Как поменять модель, чтобы она подходила к multiclass multioutput classification?

Рад при необходимости предоставьте более подробную информацию.

Ответы [ 2 ]

2 голосов
/ 29 мая 2020

Если я правильно понимаю, label_1 является двоичным, тогда как label_2 - это мультиклассовая проблема, поэтому нам нужно, чтобы модель имела два выхода с отдельными функциями потерь; двоичная и категориальная кроссэнтропия соответственно.

Однако последовательный API не допускает множественный ввод / вывод.

Последовательный API позволяет создавать модели послойно для большинства проблем. Он ограничен тем, что не позволяет создавать модели с общими слоями или с несколькими входами или выходами.

Вы можете использовать функциональный API для создания двух выходных слоев и скомпилировать модель с требуемым функции потерь.

X=Input(input_shape)
X=Layer(X)
'
'
'
'
out1=Dense(1, activation='sigmoid')(X)
out2=Dense(3, activation='softmax')(X)
model = Model(inputs = input, outputs = [out1,out2])
model.compile(loss = ['binary_crossentropy','categorical_crossentropy'], loss_weights = [l1,l2], ...)

model.fit(input,[label_1, label_2_toCategotical]

Потери, которые сеть будет минимизировать, будут взвешенной суммой двух потерь, взвешенных по l1 и l2.

Надеюсь, это поможет :)

1 голос
/ 09 июня 2020

Это несколько сложная проблема, поскольку API-интерфейс Scikit-Learn и API-интерфейс Keras для мультиклассового множественного вывода не совместимы напрямую. Кроме того, есть даже различия в том, как TensorFlow v1 и v2 обрабатывает вещи. Существующие оболочки Keras на самом деле не работают для более сложных случаев.

Я создал расширение KerasClassifier, которое может справляться с этими ситуациями, пакет и документация здесь (GitHub) . Полное раскрытие информации: я являюсь создателем пакета, но у меня нет финансовых интересов, это открытый исходный код.

С этими расширенными версиями вы можете легко решить проблемы с несколькими классами с несколькими выходами. Я думаю, что для вашей ситуации это должно работать из коробки, но если нет, вы можете просто унаследовать от KerasClassifier и перезаписать _pre_process_y и _post_process_y для преобразования из формата данных Scikit-Learn в то, что использует ваша модель Keras. Подробнее здесь (документы) .

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...